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