1: 2: /* 3: * This software is Copyright (c) 1985 by Rick Adams. 4: * 5: * Permission is hereby granted to copy, reproduce, redistribute or 6: * otherwise use this software as long as: there is no monetary 7: * profit gained specifically from the use or reproduction or this 8: * software, it is not sold, rented, traded or otherwise marketed, and 9: * this copyright notice is included prominently in any copy 10: * made. 11: * 12: * The author make no claims as to the fitness or correctness of 13: * this software for any use whatsoever, and it is provided as is. 14: * Any use of this software is at the user's own risk. 15: * 16: * Batch: program to batch a list of news articles into an unbatch script. 17: * Usage: /usr/lib/news/batch listfile [bytecount] 18: * where listfile is a file containing a list, one per line, of full 19: * path names of files containing articles, e.g. as produced by the F 20: * transmission option in the sys file. 21: * bytecount is the maximum number of bytes to output before exiting 22: * Output is placed on standard output. 23: * 24: * Intended usage: 25: * 26: * With the shellfile "sendbatch", with machine names as arguments: 27: * e.g 28: * sendbatch rlgvax seismo 29: * 30: * This would be invoked every hour or two from crontab. 31: * 32: */ 33: 34: #ifdef SCCSID 35: static char *SccsId = "@(#)batch.c 1.15 1/17/86"; 36: #endif /* SCCSID */ 37: 38: #include <stdio.h> 39: #include <sys/types.h> 40: #include <sys/stat.h> 41: #include <errno.h> 42: #include "defs.h" 43: 44: #if defined(USG) || defined(BSD4_2) || defined(BSD4_1C) 45: #include <fcntl.h> 46: #endif 47: 48: struct stat sbuf; 49: 50: extern int errno; 51: extern char *sys_errlist[]; 52: 53: main(argc,argv) 54: char **argv; 55: { 56: register FILE *fd, *nfd; 57: register int c; 58: register long n; 59: register char *cp; 60: char *fdstatus; 61: long maxbytes, nbytes; 62: long atol(); 63: char fname[512]; 64: char workfile[512]; 65: char *index(), *fgets(); 66: 67: if (argc < 2) { 68: fprintf(stderr, "Usage: batch listfile [bytecount]\n"); 69: exit(1); 70: } 71: 72: /* 73: * Rename real file to a work name to avoid race conditions. 74: * If workfile exists skip the rename in order 75: * to recover from a crash w/o losing anything. 76: */ 77: (void) strcpy(workfile, argv[1]); 78: (void) strcat(workfile, ".work"); 79: if (access(workfile, 0) < 0) { 80: if (access(argv[1], 0) < 0 && errno == ENOENT) 81: exit(0); /* no news */ 82: if (rename(argv[1], workfile) < 0) { 83: logerror("rename(%s,%s) %s", argv[1], workfile, 84: sys_errlist[errno]); 85: exit(1); 86: } 87: } 88: fd = fopen(workfile, "r"); 89: if (fd == NULL) { 90: logerror("fopen(%s,r) %s", workfile, sys_errlist[errno]); 91: exit(1); 92: } 93: 94: if (argc > 2) 95: maxbytes = atol(argv[2]); 96: else 97: maxbytes = 100000000L; /* backwards compatible */ 98: nbytes = 0; 99: while ((fdstatus = fgets(fname, sizeof fname, fd)) != NULL) { 100: cp = index(fname, '\n'); 101: if (cp) 102: *cp = '\0'; 103: nfd = fopen(fname, "r"); 104: if (nfd == NULL) { 105: perror(fname); 106: continue; 107: } 108: (void) fstat(fileno(nfd), &sbuf); 109: if (cp) 110: *cp = '\n'; 111: nbytes += sbuf.st_size; 112: if (nbytes > maxbytes && nbytes != sbuf.st_size) 113: break; 114: printf("#! rnews %ld\n", (long)sbuf.st_size); 115: /* guess length of #! rnews string */ 116: nbytes += 13; 117: n = 0; 118: while ((c = getc(nfd)) != EOF) { 119: putchar(c); 120: n++; 121: } 122: (void) fclose(nfd); 123: if (ferror(stdout)){ 124: logerror("stdout write %s", sys_errlist[errno]); 125: exit(1); 126: } 127: if (n != sbuf.st_size) { /* paranoia */ 128: logerror("%s, expected %ld bytes, got %ld", fname, 129: n, sbuf.st_size); 130: /* breaking out of this early will end up resyncing 131: the batch files (isn't serendipity wonderful?) */ 132: break; 133: } 134: } 135: if (fdstatus != NULL) { /* exceeded maxbytes */ 136: char tmpfile[512]; 137: 138: (void) umask(2); 139: (void) strcpy(tmpfile, argv[1]); 140: (void) strcat(tmpfile, ".tmp"); 141: nfd = fopen(tmpfile, "w"); 142: if (nfd == NULL) { 143: logerror("fopen(%s,w) %s", tmpfile, sys_errlist[errno]); 144: exit(1); 145: } 146: do { 147: fputs(fname, nfd); 148: } while (fgets(fname, sizeof fname, fd) != NULL); 149: if (ferror(nfd)) { 150: logerror("write(%s) %s", tmpfile, sys_errlist[errno]); 151: exit(1); 152: } 153: (void) fclose(nfd); 154: (void) fclose(fd); 155: /* will pick it up next time thru */ 156: if (rename(tmpfile, workfile) < 0) { 157: logerror("rename(%s,%s) %s", tmpfile, workfile, 158: sys_errlist[errno]); 159: exit(1); 160: } 161: } 162: else 163: (void) unlink(workfile); 164: exit(0); 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: logerror(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) 173: char *fmt; 174: { 175: FILE *logfile; 176: char lfname[BUFLEN]; /* the log file */ 177: char bfr[BUFLEN]; 178: char *logtime, *ctime(); 179: time_t 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: } 206: 207: #if !defined(BSD4_2) && !defined(BSD4_1C) 208: rename(from, to) 209: register char *from, *to; 210: { 211: (void) unlink(to); 212: if (link(from, to) < 0) 213: return -1; 214: 215: (void) unlink(from); 216: return 0; 217: } 218: #endif /* !BSD4_2 && !BSD4_1C */