|
|
1.1 root 1: /*
2: * unbatchnews: extract news in batched format and process it one article
3: * at a time. The format looks like
4: * #! rnews 1234
5: * article containing 1234 characters
6: * #! rnews 4321
7: * article containing 4321 characters
8: *
9: * or
10: *
11: * #! command [args]
12: * calls LIBDIR/command [args] to process the news
13: */
14:
15: #ifdef SCCSID
16: static char *SccsId = "@(#)unbatch.c 6.3 5/17/86";
17: #endif /* SCCSID */
18:
19: #define MAXARGS 20
20:
21: #ifdef BSD4_2
22: #define fork vfork
23: #endif /* BSD4_2 */
24:
25: #include <stdio.h>
26: #include <ctype.h>
27: #ifdef USG
28: #include <fcntl.h>
29: #endif /* USG */
30:
31: char buf[BUFSIZ];
32: char sibuf[BUFSIZ];
33:
34: main()
35: {
36: register int c;
37: register FILE *pfn;
38: register long size;
39: char *filename;
40: int pid, wpid, exstat;
41: char *mktemp(), *gets();
42: long atol();
43:
44: filename = mktemp("/tmp/unbnewsXXXXXX");
45: setbuf(stdin, (char *)NULL); /* only for the first line */
46: if (gets(buf) == NULL) {
47: (void) unlink(filename);
48: exit(0);
49: }
50: if (strncmp(buf, "#! rnews ", 9) != 0) {
51: docmd(buf);
52: /* should not return */
53: logerr("unbatch: docmd returned!");
54: exit(1);
55: }
56:
57: setbuf(stdin, sibuf); /* buffer the rest of the file */
58:
59: do {
60: while (strncmp(buf, "#! rnews ", 9)
61: && strncmp(buf, "! rnews ", 8)) { /* kludge for bug */
62: register char *cp;
63: for (cp = buf; *cp != '\0'; ++cp)
64: if (!isascii(*cp) ||
65: (!isprint(*cp) && !isspace(*cp)))
66: *cp = '?';
67: logerr("out of sync, skipping %s", buf);
68: if (gets(buf) == NULL)
69: exit(0);
70: }
71: size = atol(buf + (buf[0] == '#' ? 9 : 8));
72: if(size <= 0) {
73: logerr("nonsense size %ld", size);
74: continue;
75: }
76: #ifdef VMS
77: vmsdelete(filename);
78: #endif /* VMS */
79: pfn = fopen(filename, "w");
80: while(--size >= 0 && (c = getc(stdin)) != EOF)
81: putc(c, pfn);
82: (void) fclose(pfn);
83:
84: /*
85: * If we got a truncated batch, don't process the
86: * last article; it will probably be received again.
87: */
88: if (size > 0)
89: break;
90:
91: /*
92: * rnews < filename
93: */
94: while ((pid = fork()) == -1) {
95: logerr("fork failed, waiting...\n");
96: sleep(53);
97: }
98: if (pid == 0) {
99: (void) close(0);
100: (void) open(filename, 0);
101: #ifdef IHCC
102: (void) sprintf(buf, "%s/%s/rnews", logdir(HOME), LIBDIR);
103: #else
104: (void) sprintf(buf, "%s/rnews", BINDIR);
105: #endif
106: execlp(buf, "rnews", (char *)0);
107: perror("rnews");
108: exit(1);
109: }
110: while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
111: ;
112: } while (gets(buf) != NULL);
113: (void) unlink(filename);
114: exit(0);
115: }
116:
117: docmd(p)
118: register char *p;
119: {
120: char *args[MAXARGS];
121: register char **ap = args;
122: char path[BUFSIZ];
123: char *rindex(), *cp;
124:
125: while (*p && !isspace(*p)) /* skip leading #! crud */
126: p++;
127:
128: while (isspace(*p))
129: p++;
130:
131: while (*p != '\0') {
132: *ap++ = p;
133: if (ap >= &args[MAXARGS]) {
134: logerr("unbatch: Too many args to %s", args[0]);
135: exit(2);
136: }
137: while (*p && !isspace(*p))
138: p++;
139: if (*p)
140: *p++ = '\0';
141: while (isspace(*p))
142: p++;
143: }
144: *ap = (char *)0;
145:
146: if (ap == args) {
147: logerr("unbatch: no command to execute");
148: exit(2);
149: }
150:
151: /* strip off any leading pathname in case someone gets tricky */
152: cp = rindex(args[0], '/');
153: if (cp++ == NULL)
154: cp = args[0];
155:
156: sprintf(path, "%s/%s", LIBDIR, cp);
157:
158: /*
159: * "path" is absolute, no searching is needed, we use
160: * 'execvp' solely so that sh scripts will be handled
161: */
162: (void) execvp(path, args);
163: perror(path);
164: exit(2);
165: }
166:
167: /*
168: * Log the given message, with printf strings and parameters allowed,
169: * on the log file, if it can be written.
170: */
171: /* VARARGS1 */
172: logerr(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
173: char *fmt;
174: {
175: FILE *logfile;
176: char lfname[BUFSIZ]; /* the log file */
177: char bfr[BUFSIZ];
178: char *logtime, *ctime();
179: long t;
180:
181: (void) time(&t);
182: logtime = ctime(&t);
183: logtime[16] = 0;
184: logtime += 4;
185:
186: #ifdef IHCC
187: (void) sprintf(lfname, "%s/%s/errlog", logdir(HOME), LIBDIR);
188: #else
189: (void) sprintf(lfname, "%s/errlog", LIBDIR);
190: #endif
191:
192: (void) sprintf(bfr, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
193: fprintf(stderr, bfr);
194: if (access(lfname, 0) == 0 && (logfile = fopen(lfname, "a")) != NULL) {
195: #if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
196: int flags;
197: flags = fcntl(fileno(logfile), F_GETFL, 0);
198: (void) fcntl(fileno(logfile), F_SETFL, flags|O_APPEND);
199: #else /* v7 */
200: (void) lseek(fileno(logfile), 0L, 2);
201: #endif /* v7 */
202: fprintf(logfile, "%s\tbatch\t%s\n", logtime, bfr);
203: (void) fclose(logfile);
204: }
205: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.