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