xref: /plan9/sys/src/cmd/fossil/fossil.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1 #include "stdinc.h"
2 #include <ctype.h>
3 
4 #include "9.h"
5 
6 int Dflag;
7 char* none = "none";
8 
9 static void
10 usage(void)
11 {
12 	fprint(2, "usage: %s"
13 		" [-Dt]"
14 		" [-c cmd]"
15 		" [-f partition]\n"
16 		, argv0);
17 	exits("usage");
18 }
19 
20 static void
21 readCmdPart(char *file, char ***pcmd, int *pncmd)
22 {
23 	char buf[1024+1], *f[1024];
24 	char tbuf[1024];
25 	int nf;
26 	int i, fd, n;
27 	char **cmd, *p;
28 	int ncmd;
29 
30 	cmd = *pcmd;
31 	ncmd = *pncmd;
32 
33 	if((fd = open(file, OREAD)) < 0)
34 		sysfatal("open %s: %r", file);
35 	if(seek(fd, 127*1024, 0) != 127*1024)
36 		sysfatal("seek %s 127kB: %r", file);
37 	n = readn(fd, buf, sizeof buf-1);
38 	if(n == 0)
39 		sysfatal("short read of %s at 127kB", file);
40 	if(n < 0)
41 		sysfatal("read %s: %r", file);
42 	buf[n] = 0;
43 	if(memcmp(buf, "fossil config\n", 6+1+6+1) != 0)
44 		sysfatal("bad config magic in %s", file);
45 	nf = getfields(buf+6+1+6+1, f, nelem(f), 1, "\n");
46 	for(i=0; i<nf; i++){
47 		if(f[i][0] == '#')
48 			continue;
49 		cmd = vtMemRealloc(cmd, (ncmd+1)*sizeof(char*));
50 		/* expand argument '*' to mean current file */
51 		if((p = strchr(f[i], '*')) && (p==f[i]||isspace(p[-1])) && (p[1]==0||isspace(p[1]))){
52 			memmove(tbuf, f[i], p-f[i]);
53 			strecpy(tbuf+(p-f[i]), tbuf+sizeof tbuf, file);
54 			strecpy(tbuf+strlen(tbuf), tbuf+sizeof tbuf, p+1);
55 			f[i] = tbuf;
56 		}
57 		cmd[ncmd++] = vtStrDup(f[i]);
58 	}
59 	close(fd);
60 	*pcmd = cmd;
61 	*pncmd = ncmd;
62 }
63 
64 void
65 main(int argc, char* argv[])
66 {
67 	char **cmd, *p;
68 	int i, ncmd, tflag;
69 
70 	fmtinstall('D', dirfmt);
71 	fmtinstall('F', fcallfmt);
72 	fmtinstall('M', dirmodefmt);
73 	quotefmtinstall();
74 
75 	/*
76 	 * Insulate from the invoker's environment.
77 	 */
78 	if(rfork(RFREND|RFNOTEG|RFNAMEG) < 0)
79 		sysfatal("rfork: %r");
80 
81 	close(0);
82 	open("/dev/null", OREAD);
83 	close(1);
84 	open("/dev/null", OWRITE);
85 
86 	cmd = nil;
87 	ncmd = tflag = 0;
88 
89 	vtAttach();
90 
91 	ARGBEGIN{
92 	case '?':
93 	default:
94 		usage();
95 		break;
96 	case 'D':
97 		Dflag ^= 1;
98 		break;
99 	case 'f':
100 		p = EARGF(usage());
101 		readCmdPart(p, &cmd, &ncmd);
102 		break;
103 	case 'c':
104 		p = EARGF(usage());
105 		cmd = vtMemRealloc(cmd, (ncmd+1)*sizeof(char*));
106 		cmd[ncmd++] = p;
107 		break;
108 	case 't':
109 		tflag = 1;
110 		break;
111 	}ARGEND
112 	if(argc != 0)
113 		usage();
114 
115 	consInit();
116 	cliInit();
117 	msgInit();
118 	conInit();
119 	cmdInit();
120 	fsysInit();
121 	exclInit();
122 	fidInit();
123 
124 	srvInit();
125 	lstnInit();
126 	usersInit();
127 
128 	for(i = 0; i < ncmd; i++)
129 		if(cliExec(cmd[i]) == 0)
130 			fprint(2, "%s: %R\n", cmd[i]);
131 	vtMemFree(cmd);
132 
133 	if(tflag && consTTY() == 0)
134 		consPrint("%s\n", vtGetError());
135 
136 	vtDetach();
137 	exits(0);
138 }
139