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 int mainstacksize = 16 * 1024;
12
13 static void
usage(void)14 usage(void)
15 {
16 fprint(2, "usage: %s [-Dt] [-c cmd] [-f partition] [-m %%]\n", argv0);
17 threadexitsall("usage");
18 }
19
20 static void
readCmdPart(char * file,char *** pcmd,int * pncmd)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 = vtrealloc(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
threadmain(int argc,char * argv[])65 threadmain(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 ARGBEGIN{
90 case '?':
91 default:
92 usage();
93 break;
94 case 'c':
95 p = EARGF(usage());
96 currfsysname = p;
97 cmd = vtrealloc(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 vtfree(cmd);
137
138 if(tflag && consTTY() == 0)
139 consPrint("%r\n");
140
141 threadexits(0);
142 }
143