|
|
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.