1: #include "parms.h" 2: #include "structs.h" 3: #include "newsgate.h" 4: 5: #ifdef FASTSEQ 6: #include <sys/types.h> 7: #include <sys/stat.h> 8: #endif FASTSEQ 9: 10: #ifdef pdp11 11: #define gatesysnames _gtsysn 12: #define gatesyscount _gtsysc 13: #endif 14: 15: #ifdef RCSIDENT 16: static char rcsid[] = "$Header: newsout.c,v 1.7.0.2 85/03/22 10:53:59 notes Rel $"; 17: #endif RCSIDENT 18: 19: /* 20: * newsoutput - process a particular notesfile for updates 21: * out to the news system. 22: * 23: * 24: * Original Coding: Ray Essick April 1982 25: * Modified to handle gateing for multiple systems better 26: * Ray Essick September 1982 27: */ 28: 29: newsout (nfname, backwards, usetime, verbosity) 30: char *nfname; 31: { 32: struct io_f io; 33: struct note_f note; 34: struct resp_f rsprec; 35: struct when_f whendump; /* when we did this */ 36: int notenum, 37: respnum, 38: rdumped, 39: ndumped, /* number dumped */ 40: roffset, 41: rblock; 42: char basengroup[NNLEN]; /* hold newsgroup */ 43: char respngroup[NNLEN]; /* hold newsgroup */ 44: FILE * log; 45: char buf[CMDLEN]; 46: char ztime[DATELEN]; 47: 48: #ifdef FASTSEQ 49: { 50: struct when_f whenvec; 51: char NoteFile[WDLEN]; 52: struct stat StatBuf; 53: 54: if (nfname[0] == '/') /* absolute pathname */ 55: { 56: getlast (&io.stime, rindex (nfname, '/') + 1, usetime, Seqname); 57: sprintf (NoteFile, "%s/%s", nfname, TEXT); 58: } 59: else /* from Mstdir */ 60: { 61: getlast (&io.stime, nfname, usetime, Seqname); 62: sprintf (NoteFile, "%s/%s/%s", Mstdir, nfname, TEXT); 63: } 64: if (stat (NoteFile, &StatBuf) >= 0) 65: { 66: maketime (&whenvec, (long) StatBuf.st_mtime); 67: if (inorder (&whenvec, &io.stime)) 68: { 69: return (0); 70: } 71: } 72: } 73: #endif FASTSEQ 74: 75: if (init (&io, nfname) < 0) /* open the bugger */ 76: return (-1); 77: 78: if ((io.descr.d_stat & NETWRKD) == 0) /* can we gate? */ 79: { 80: closenf (&io); 81: printf ("%s must be networked to go to news!\n", nfname); 82: fflush (stdout); 83: return (-1); 84: } 85: 86: gettime (&whendump); /* for seq. update */ 87: getlast (&io.stime, io.nf, usetime, Seqname); /* grab last time */ 88: newsgroup (io.nf, basengroup, NFBASENEWS); /* alias base notes */ 89: newsgroup (io.nf, respngroup, NFRESPNEWS); /* and responses */ 90: 91: if (inorder (&io.descr.d_lastm, &io.stime)) /* no traffic */ 92: { 93: #ifdef FASTSEQ 94: /* 95: * Update the timestamp so the next scan will catch the idle 96: * notesfile in the FASTSEQ code. 97: */ 98: fixlast (&whendump, io.nf, NORMSEQ, Seqname); /* update sequencer */ 99: #endif FASTSEQ 100: closenf (&io); /* cheap no-stats exit */ 101: return (0); /* and out of here */ 102: } 103: 104: ndumped = rdumped = 0; 105: notenum = 0; /* start at the top */ 106: while ((notenum = nxtnote (&io, notenum, &io.stime)) != -1) 107: { 108: getnrec (&io, notenum, ¬e); /* get descriptor */ 109: respnum = 0; /* response chain */ 110: if (inorder (&io.stime, ¬e.n_rcvd) == 0) /* been dumped */ 111: goto doresps; 112: if ((note.n_stat & FRMNEWS) != 0) /* it's been in news */ 113: goto doresps; /* dont send back! */ 114: if ((note.n_stat & ORPHND) != 0) /* no foster parents */ 115: goto doresps; /* go out */ 116: if (!cansend (note.n_id.sys, sendclass)) /* can't send it */ 117: goto doresps; /* don't dump it */ 118: 119: if (newsnote (&io, ¬e, notenum, basengroup, backwards) == -1) 120: { 121: sprintf (buf, "%s/%s/%s", Mstdir, UTILITY, NETLOG); 122: sprdate (&whendump, ztime); 123: x ((log = fopen (buf, "a")) == NULL, "newsout: no log file"); 124: fprintf (log, "%s: Failed dumping note to NEWS for %s at %s\n", 125: nfname, note.n_id.sys, ztime); 126: fclose (log); 127: printf ("%s: Failed dumping note to NEWS for %s at %s\n", 128: nfname, note.n_id.sys, ztime); 129: fflush (stdout); 130: } 131: /* dump it */ 132: ndumped++; /* count */ 133: 134: doresps: /* process responses */ 135: 136: 137: while ((respnum = nxtresp (&io, notenum, respnum, &io.stime)) != -1) 138: { 139: if (lrsp (&io, notenum, respnum, &rsprec, &roffset, &rblock) == -1) 140: break; /* bad chain */ 141: if (rsprec.r_stat[roffset] & FRMNEWS) /* its from there */ 142: continue; /* dont go back */ 143: if (!cansend (rsprec.r_id[roffset].sys, sendclass))/* if can't then */ 144: continue; /* don't send it */ 145: 146: if (newsresp (&io, ¬e, notenum, &rsprec, roffset, 147: respnum, respngroup, backwards) == -1) 148: { 149: sprintf (buf, "%s/%s/%s", Mstdir, UTILITY, NETLOG); 150: sprdate (&whendump, ztime); 151: x ((log = fopen (buf, "a")) == NULL, "newsout: no log file"); 152: fprintf (log, "%s: Failed dumping note to NEWS for %s at %s\n", 153: nfname, rsprec.r_id[roffset].sys, ztime); 154: fclose (log); 155: printf ("%s: Failed dumping note to NEWS for %s at %s\n", 156: nfname, rsprec.r_id[roffset].sys, ztime); 157: fflush (stdout); 158: } 159: rdumped++; 160: 161: 162: } 163: } 164: 165: /* 166: * update the sequencer always. This is fine if we did send 167: * something for the system (and what we want to happen). 168: * By updating even when we don't send news, we avoid having 169: * to rescan those candidates we just looked at the next time. 170: * Eg: Running newsoutput for a usually quiet site could get 171: * very expensive if we didn't update this timestamp. 172: * 173: * We catch the "idle notesfile" case earlier and leave 174: * without scanning or updating if nothing of potential 175: * interest has happened since the last run. 176: */ 177: fixlast (&whendump, io.nf, NORMSEQ, Seqname); /* update sequencer */ 178: 179: if (ndumped + rdumped) /* log dump */ 180: { 181: sprintf (buf, "%s/%s/%s", Mstdir, UTILITY, NETLOG); 182: sprdate (&whendump, ztime); 183: x ((log = fopen (buf, "a")) == NULL, "newsout: missing log file"); 184: fprintf (log, "%s: Send (%d,%d) to NEWS at %s\n", 185: nfname, ndumped, rdumped, ztime); 186: fclose (log); 187: printf ("%s: Send (%d,%d) to NEWS (%s and %s) at %s\n", 188: nfname, ndumped, rdumped, 189: basengroup, respngroup, ztime); 190: fflush (stdout); 191: } 192: 193: finish (&io); /* close shop here */ 194: return 0; 195: } 196: 197: /* 198: * cansend(system,sendclass) 199: * 200: * check if we are gatewaying articles for the system named 201: * in "whichsys". Use the "sendclass" variable to check 202: * against sending anyone (NEWS_ALLSEND bit) 203: * If that doesn't qualify us, look through a list of 204: * sitenames in the gatesysname[] array. 205: */ 206: 207: cansend (sysname, class) 208: char *sysname; 209: int class; 210: { 211: int i, 212: j, 213: k; 214: extern int gatesyscount; /* size of array */ 215: extern char *gatesysnames[GATEMAX]; /* actual data */ 216: 217: if (class & NEWS_ALLSEND) 218: return (1); /* sending any articles */ 219: 220: /* 221: * This list should be sorted and we should do a binary search 222: * on the bugger.... 223: */ 224: for (i = 0; i < gatesyscount; i++) /* look through table */ 225: if (!strcmp (sysname, gatesysnames[i])) 226: return (1); /* find and dandy */ 227: 228: return (0); /* anything else is nogo */ 229: }