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