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