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