|
|
1.1 root 1: /*% cc -c -O %
2: */
3: #include "vars.h"
4: char *nextip;
5: long count;
6: /*
7: * newfile: read a new file name (if given) from command line.
8: *
9: * nullerr: if true, error if file is null.
10: * savspec: decides if string[savedfile] is set.
11: * If savspec==SAVEIFFIRST, only save if deffile is null.
12: * deffile: default file name.
13: *
14: * return value: string[FILEBUF]!=deffile
15: * (unless SAVEIFFIRST && deffile null ==> return FALSE)
16: * side effects:
17: * can set string[savedfile]
18: * always sets string[FILEBUF]
19: * zeroes count
20: */
21: newfile(nullerr, savspec, deffile)
22: char *deffile;
23: {
24: register char c;
25:
26: count = 0L;
27: cpstr(deffile, genbuf); /* in case we strcompact() */
28: startstring();
29: c = getchar();
30: if(c == '\n')
31: copystring(genbuf);
32: else {
33: if(c != ' ')
34: error('f');
35: do c = getchar(); while(c == ' ');
36: while(posn(c, " \t\n") < 0){
37: if(c<' ' || c=='\177')
38: error('f');
39: addstring(c);
40: c = getchar();
41: }
42: }
43: setstring(FILEBUF);
44: if(nullerr && string[FILEBUF].str[0]=='\0')
45: error('f');
46: if(savspec==SAVEALWAYS || (savspec==SAVEIFFIRST && genbuf[0]=='\0')){
47: startstring();
48: dupstring(FILEBUF);
49: setstring(savedfile);
50: if(savspec==SAVEIFFIRST && genbuf[0]=='\0')
51: return(FALSE);
52: }
53: return(!eqstr(genbuf, string[FILEBUF].str));
54: }
55: exfile()
56: {
57: close(io);
58: io = -1;
59: if (vflag && initflag)
60: ncom('f');
61: else if (vflag) {
62: putlong(count);
63: putchar('\n');
64: }
65: setcount((int)count);
66: }
67: getfile()
68: {
69: register c;
70: register char *lp, *fp;
71: lp = linebuf;
72: fp = nextip;
73: do {
74: if (--ninbuf < 0) {
75: if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0) {
76: if(ninbuf < -1)
77: error('r');
78: if(lp != linebuf)
79: error('N');
80: return(EOF);
81: }
82: fp = genbuf;
83: }
84: if (lp >= &linebuf[LBSIZE])
85: error('l');
86: if ((*lp++ = c = *fp++ ) == 0) {
87: lp--;
88: continue;
89: }
90: count++;
91: } while (c != '\n');
92: *--lp = 0;
93: nextip = fp;
94: return(0);
95: }
96: putfile()
97: {
98: int *a1;
99: register char *fp, *lp;
100: register nib;
101: nib = 512;
102: fp = genbuf;
103: a1 = addr1;
104: if(a1 == zero)
105: *a1++;
106: while(a1 <= addr2){
107: lp = getline(*a1++, linebuf);
108: for(;;){
109: if (--nib < 0) {
110: if(write(io, genbuf, fp-genbuf) < 0)
111: error('w');
112: nib = 511;
113: fp = genbuf;
114: }
115: count++;
116: if ((*fp++ = *lp++) == 0) {
117: fp[-1] = '\n';
118: break;
119: }
120: }
121: }
122: write(io, genbuf, fp-genbuf);
123: }
124: int savint= -1; /* awful; this is known in error() */
125: Unix(type)
126: char type;
127: {
128: register pid, rpid;
129: register char *s;
130: int *a, c;
131: int getsvc();
132: int onbpipe;
133: int retcode;
134: char unixbuf[512];
135: int pipe1[2];
136: int pipe2[2];
137: int *a1, *a2, *ndot;
138: startstring(); /* for the \zU register */
139: if(type == '!')
140: setnoaddr();
141: else {
142: if(type == '>' || type == '|')
143: nonzero();
144: count = 0L;
145: if(pipe(pipe1) == -1){
146: lastc = '\n';
147: error('|');
148: }
149: }
150: /* Quick hack: if char is doubled, push \'zU */
151: if(nextchar()==type){
152: getchar(); /* throw it away */
153: pushinp(STRING, UNIX, TRUE);
154: }
155: /*
156: * Use c not *s as EOF and getchar() are int's
157: */
158: for(s=unixbuf;(c=getquote("\n", getsvc))!='\n' && c!=EOF;*s++=(c&0177)){
159: if(s>=unixbuf+512)
160: error('l');
161: }
162: dropstring(); /* drop the newline */
163: setstring(UNIX);
164: *s='\0';
165: a1 = addr1;
166: a2 = addr2;
167: if ((pid = fork()) == 0) {
168: signal(SIGHUP, onhup);
169: signal(SIGINT, onintr);
170: signal(SIGQUIT, onquit);
171: if(type=='<' || type=='|'){
172: close(1);
173: dup(pipe1[1]);
174: }else if(type == '>'){
175: close(0);
176: dup(pipe1[0]);
177: }
178: if (type != '!') {
179: close(pipe1[0]);
180: close(pipe1[1]);
181: }
182: if(type == '|'){
183: if(pipe(pipe2) == -1){
184: puts("?|");
185: exit(1);
186: }
187: if((pid=fork()) == 0){
188: close(1);
189: dup(pipe2[1]);
190: close(pipe2[0]);
191: close(pipe2[1]);
192: tfile = tfile2; /* ugh */
193: /*
194: * It's ok if we get SIGPIPE here
195: */
196: display('p');
197: exit(0);
198: }
199: if(pid == -1){
200: puts("Can't fork\n?!");
201: exit(1);
202: }
203: close(0);
204: dup(pipe2[0]);
205: close(pipe2[0]);
206: close(pipe2[1]);
207: }
208: if (*unixbuf)
209: execl("/bin/sh", "sh", "-c", unixbuf, 0);
210: else
211: execl("/bin/sh", "sh", 0);
212: exit(-1);
213: }
214: if(pid == -1){
215: puts("Can't fork");
216: error('!');
217: }
218: savint = signal(SIGINT, 1);
219: if(type=='<' || type=='|') {
220: close(pipe1[1]);
221: io = pipe1[0];
222: ninbuf = 0;
223: append(getfile,addr2);
224: close(io);
225: io = -1;
226: ndot = dot;
227: } else if(type == '>') {
228: onbpipe = signal(SIGPIPE, 1);
229: close(pipe1[0]);
230: a=addr1;
231: do{
232: s=getline(*a++, linebuf);
233: do; while(*s++);
234: *--s='\n';
235: if (write(pipe1[1],linebuf,s-(linebuf-1))<0){
236: puts("?o");
237: break;
238: }
239: }while (a<=addr2);
240: close(pipe1[1]);
241: signal(SIGPIPE, onbpipe);
242: }
243: while ((rpid = wait(&retcode)) != pid && rpid != -1);
244: retcode = (retcode>>8)&0377;
245: settruth(retcode);
246: signal(SIGINT, savint);
247: if(type == '|'){
248: if(retcode == 0){
249: addr1 = a1;
250: addr2 = a2;
251: delete();
252: dot = ndot - (a2-a1+1);
253: } else
254: error('0');
255: }
256: if(vflag)
257: puts("!");
258: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.