1: #include "parms.h" 2: #include "structs.h" 3: 4: #ifdef RCSIDENT 5: static char rcsid[] = "$Header: loadem.c,v 1.7.0.2 87/02/25 09:05:39 notes Rel $"; 6: #endif RCSIDENT 7: 8: /* 9: * load a file of generic notes. 10: * This routine will read the file supplied ( as an fid ) 11: * and place it into the notefile. 12: * locking is supressed if the lockit flag is false 13: * uids are mapped to zero if the system that the note came from 14: * does not match the local system. 15: * 16: * Original coding: Ray Essick December 1981 17: * Recoding: Ray Essick March 1984 18: * Streamlining, prepare for alternate protocols 19: */ 20: 21: /* 22: * routines for loading notes and responses 23: */ 24: extern int loadnote (); /* proto 0 note */ 25: extern int loadresp (); /* proto 0 resp */ 26: extern int ldnote1 (); /* proto 1 note */ 27: extern int ldresp1 (); /* proto 1 resp */ 28: 29: /* 30: * jump tables pointing to the proper routines to parse 31: * notes and responses in the assorted protocols 32: */ 33: static int (*noteproto[]) () = /* notes */ 34: { 35: loadnote 36: }; 37: static int (*respproto[]) () = /* responses */ 38: { 39: loadresp 40: }; 41: static int nproto = sizeof noteproto / sizeof noteproto[0]; 42: static int rproto = sizeof respproto / sizeof respproto[0]; 43: 44: 45: loadem (io, infile, lockit, whofrom, extensive, articles) 46: struct io_f *io; 47: FILE * infile; 48: char *whofrom; 49: { 50: char oneline[BUFSIZ]; /* hold a line */ 51: char articletype[32]; /* proto switching */ 52: int proto; /* dynamic protocol */ 53: int loaded; /* article count */ 54: 55: loaded = 0; 56: while (loaded != articles && /* if want more */ 57: fgets (oneline, sizeof (oneline) - 1, infile) != (char *) NULL) 58: { 59: switch (oneline[0]) /* what is it */ 60: { 61: case 'N': /* proto 1 note */ 62: loadnote (io, oneline, whofrom, extensive, lockit, infile); 63: loaded++; /* count it */ 64: break; 65: 66: case 'R': /* proto 1 response */ 67: loadresp (io, oneline, whofrom, extensive, lockit, infile); 68: loaded++; /* count */ 69: break; 70: 71: /* 72: * Code to catch later protocols. This is currently unimplemented 73: */ 74: case 'P': /* newer protocol */ 75: sscanf (oneline, "Protocol: %d %s", &proto, articletype); 76: if (proto == 0) /* old protocol */ 77: break; /* to while() loop */ 78: if (!strcmp (articletype, "Note")) 79: { 80: if (proto < nproto) /* exists */ 81: (*noteproto[proto]) (io, whofrom, extensive, lockit, infile); 82: else 83: printf ("Unsupported note protocol %d\n", proto); 84: } 85: else /* assume response */ 86: { 87: if (proto < rproto) /* exists */ 88: (*respproto[proto]) (io, whofrom, extensive, lockit, infile); 89: else 90: printf ("Unsupported response protocol %d\n", proto); 91: } 92: 93: default: /* bong it */ 94: x (1, "loadem: Bad generic format"); 95: break; 96: } 97: } 98: } 99: 100: /* 101: * loadnote(line,infile) 102: * 103: * Load a note in protocol 1. line points to the first line 104: * of the article's header. 105: */ 106: 107: loadnote (io, firstline, whofrom, extensive, lockit, infile) 108: struct io_f *io; 109: char *firstline; 110: char *whofrom; 111: FILE * infile; 112: { 113: char oneline[BUFSIZ]; /* hold lines */ 114: long count; 115: long count2; 116: int i; 117: char title[TITLEN]; 118: struct note_f note, 119: note2; 120: struct id_f noteid; 121: struct daddr_f where; 122: struct auth_f auth; 123: int posit; 124: int status; 125: int fields; /* scanf retcodes */ 126: char field1[101], /* scanf temps */ 127: field2[100]; 128: 129: /* 130: * grab unique id (sys,integer). Ignore "number of responses" 131: */ 132: sscanf (firstline, "N:%99[^:]:%ld", field1, ¬eid.uniqid); 133: strncpy (noteid.sys, field1, SYSSZ); 134: noteid.sys[SYSSZ - 1] = '\0'; /* terminate */ 135: 136: fgets (oneline, sizeof (oneline) - 1, infile); /* title */ 137: for (i = 0; (i < TITLEN) && oneline[i] && (oneline[i] != '\n'); i++) 138: title[i] = oneline[i]; 139: if (i < TITLEN) 140: title[i] = '\0'; 141: else 142: title[TITLEN - 1] = '\0'; /* make sure it stops */ 143: for (i = strlen (title) - 1; i >= 0 && title[i] == ' '; i--) 144: title[i] = '\0'; /* chop trailing spaces */ 145: 146: fgets (oneline, sizeof (oneline) - 1, infile); /* author */ 147: fields = sscanf (oneline, "%99[^:]:%d:%99[^:]:", 148: field1, &auth.aid, field2); 149: strncpy (auth.aname, field1, NAMESZ); 150: auth.aname[NAMESZ - 1] = '\0'; /* shift name */ 151: if (fields < 3) /* no home system -- */ 152: { 153: strcpy (auth.asystem, noteid.sys); /* use unique id */ 154: } 155: else 156: { 157: strncpy (auth.asystem, field2, HOMESYSSZ); 158: auth.asystem[HOMESYSSZ - 1] = '\0'; /* terminate */ 159: } 160: auth.aid &= UIDMASK; 161: if (strcmp (System, noteid.sys) != 0) /* map non-local to */ 162: auth.aid = Anonuid; /* local anonymous */ 163: 164: fgets (oneline, sizeof (oneline) - 1, infile); /* time written */ 165: timein (oneline, ¬e.n_date); /* fills in if bad */ 166: 167: if (extensive) /* if reloading */ 168: { 169: fgets (oneline, sizeof (oneline) - 1, infile); /* received */ 170: timein (oneline, ¬e.n_rcvd); 171: fgets (oneline, sizeof (oneline) - 1, infile); /* last modified */ 172: timein (oneline, ¬e.n_lmod); 173: fgets (oneline, sizeof (oneline) - 1, infile); /* from */ 174: sscanf (oneline, "%s", field1); 175: strncpy (note.n_from, field1, SYSSZ); 176: note.n_from[SYSSZ - 1] = '\0'; /* make sure */ 177: } 178: else 179: { 180: strcpy (note.n_from, whofrom); /* who gave it to us */ 181: } 182: 183: do 184: { 185: fgets (oneline, sizeof (oneline) - 1, infile); /* status */ 186: /* 187: * old code forgot that fgets keeps the newline and didn't 188: * remove it before a strcpy. result is that we have a bunch 189: * of notesfiles with "\n" in the n_from field. This 190: * lets a nfdump/nfload cycle clear them up for us. 191: */ 192: } while (oneline[0] == '\n'); /* fix old bug */ 193: sscanf (oneline, "%o:%ld", &status, &count); 194: 195: 196: if (extensive == 0) /* if not reloading */ 197: { 198: getperms (io, 1, noteid.sys); /* check permission */ 199: if (!allow (io, WRITOK)) /* not allowed */ 200: { 201: io -> nnotdrop++; /* drop it */ 202: for (count2 = 0; count2 < count; count2++) /* drop message */ 203: getc (infile); /* ignore the character */ 204: return; /* back for another */ 205: } 206: } 207: 208: if (lockit) 209: locknf (io, DSCRLOCK); /* lock us up now */ 210: posit = chknote (io, ¬eid, ¬e2); /* see if here */ 211: if (posit == 0) /* not in data base */ 212: { 213: for (i = 0; i < SYSSZ; i++) 214: note.n_id.sys[i] = noteid.sys[i]; 215: note.n_id.uniqid = noteid.uniqid; /* copy unique id in */ 216: puttrec (io, infile, &where, count); /* suck text */ 217: putnote (io, &where, title, status, ¬e, &auth, NOPOLICY, 218: NOLOCKIT, NOADDID, note.n_from, (extensive == NODETAIL)); 219: io -> nnotrcvd++; /* count as a received */ 220: } 221: else 222: { 223: /* 224: * A copy exists. See if the one here is an orphan and possibly 225: * replace it 226: */ 227: if ((note2.n_stat & ORPHND) && !(status & ORPHND)) 228: { /* extant is orphan */ 229: /* new one isn't */ 230: puttrec (io, infile, ¬e2.n_addr, count); /* suck text */ 231: gettime (¬e2.n_rcvd); 232: gettime (¬e2.n_lmod); /* time stamp it */ 233: copyauth (&auth, ¬e2.n_auth); /* load author */ 234: note2.n_stat = status; /* correct status */ 235: strncpy (note2.ntitle, title, TITLEN); 236: copydate (¬e.n_date, ¬e2.n_date); 237: strmove (note.n_from, note2.n_from); 238: putnrec (io, posit, ¬e2); /* and replace */ 239: io -> adopted++; /* orphan adopted */ 240: printf ("Foster Parent Replaced. Id=%ld@%s\n", 241: noteid.uniqid, noteid.sys); 242: } 243: else 244: { 245: for (count2 = 0; count2 < count; count2++) 246: getc (infile); /* skip text */ 247: printf ("Duplicate note received id=%ld@%s\n", 248: noteid.uniqid, noteid.sys); 249: io -> nnotdrop++; /* count a dropped */ 250: } 251: } 252: 253: if (lockit) 254: unlocknf (io, DSCRLOCK); /* release lock */ 255: } 256: 257: /* 258: * loadresp(firstline,infile) 259: * 260: * load a protocol 1 response 261: */ 262: 263: loadresp (io, firstline, whofrom, extensive, lockit, infile) 264: struct io_f *io; 265: char *firstline; 266: char *whofrom; 267: FILE * infile; 268: { 269: char oneline[BUFSIZ]; 270: long count; 271: long count2; 272: struct note_f note; 273: struct id_f noteid, 274: respid; 275: struct auth_f auth; 276: struct daddr_f where; 277: struct when_f ztime, 278: ztime2; 279: char zfrom[BUFSIZ]; /* usually <10 */ 280: int status; 281: int fosterstat; 282: int posit; 283: int fields; /* scanf return codes */ 284: char field1[100], /* scanf temps */ 285: field2[100]; 286: int i; 287: char *p; 288: 289: /* 290: * parse the parent id and the response id. 291: */ 292: sscanf (firstline, "R:%99[^:]:%ld:%99[^:]:%ld", 293: field1, ¬eid.uniqid, 294: field2, &respid.uniqid); 295: strncpy (noteid.sys, field1, SYSSZ); 296: strncpy (respid.sys, field2, SYSSZ); 297: noteid.sys[SYSSZ - 1] = respid.sys[SYSSZ - 1] = '\0'; 298: 299: fgets (oneline, sizeof (oneline) - 1, infile); /* author */ 300: fields = sscanf (oneline, "%99[^:]:%d:%99[^:]:", 301: field1, &auth.aid, field2); 302: strncpy (auth.aname, field1, NAMESZ); /* shift and */ 303: auth.aname[NAMESZ - 1] = '\0'; /* terminate */ 304: if (fields < 3) /* no home system */ 305: { 306: strcpy (auth.asystem, respid.sys); /* use unique id */ 307: } 308: else 309: { 310: strncpy (auth.asystem, field2, HOMESYSSZ); 311: auth.asystem[HOMESYSSZ - 1] = '\0'; 312: } 313: auth.aid &= UIDMASK; /* mask appropriately */ 314: if (strcmp (System, note.n_id.sys) != 0) /* map non-local to */ 315: auth.aid = Anonuid; /* local anonymous */ 316: 317: fgets (oneline, sizeof (oneline) - 1, infile); /* date written */ 318: timein (oneline, &ztime); 319: 320: if (extensive) /* if reloading */ 321: { 322: fgets (oneline, sizeof (oneline) - 1, infile); /* date received */ 323: timein (oneline, &ztime2); 324: fgets (oneline, sizeof (oneline) - 1, infile); /* received from */ 325: sscanf (oneline, "%s", field1); 326: strncpy (zfrom, field1, SYSSZ); 327: zfrom[SYSSZ - 1] = '\0'; /* make sure */ 328: } 329: else 330: { 331: strcpy (zfrom, whofrom); /* who gave it to us */ 332: } 333: 334: do 335: { 336: fgets (oneline, sizeof (oneline) - 1, infile); /* status */ 337: /* 338: * old code forgot that fgets keeps the newline and didn't 339: * remove it before a strcpy. result is that we have a bunch 340: * of notesfiles with "\n" in the n_from field. This 341: * lets a nfdump/nfload cycle clear them up for us. 342: */ 343: } while (oneline[0] == '\n'); /* fix old bug */ 344: sscanf (oneline, "%o:%ld", &status, &count); 345: 346: 347: if (lockit) 348: locknf (io, DSCRLOCK); /* CRITICAL SECTION */ 349: posit = chknote (io, ¬eid, ¬e); /* look for daddy */ 350: if (posit == 0) /* no daddy */ 351: { /* build foster parent */ 352: strcpy (note.n_id.sys, noteid.sys); 353: note.n_id.uniqid = noteid.uniqid; 354: note.n_nresp = 0; 355: note.n_auth.aid = Anonuid; 356: strcpy (note.n_auth.aname, "Unknown"); 357: strcpy (note.n_auth.asystem, note.n_id.sys); /* use unique id */ 358: copydate (&ztime, ¬e.n_date); 359: fosterstat = ORPHND; /* mark as foster */ 360: strcpy (note.ntitle, "Orphaned Response"); 361: where.addr = 0; /* no text */ 362: where.textlen = 0; 363: posit = putnote (io, &where, note.ntitle, fosterstat, ¬e, 364: ¬e.n_auth, NOPOLICY, NOLOCKIT, NOADDID, whofrom, ADDTIME); 365: io -> norphans++; /* count orphans */ 366: printf ("Response Id=%ld@%s is an orphan of note Id=%ld@%s\n", 367: respid.uniqid, respid.sys, 368: noteid.uniqid, noteid.sys); 369: } 370: /* 371: * we definitely have a parent here, since we either found one 372: * or created one 373: */ 374: if (chkresp (io, &respid, ¬e, posit) == 0) /* response here */ 375: { 376: if (extensive == 0) /* if not reloading */ 377: getperms (io, 1, respid.sys); /* can he? */ 378: if (allow (io, RESPOK) || extensive) 379: { 380: puttrec (io, infile, &where, count); /* read text */ 381: putresp (io, &where, status, posit, &ztime, &auth, 382: ¬e, 0, &respid, 0, zfrom, (extensive == NODETAIL), &ztime2); 383: io -> nrsprcvd++; /* he is a rcvd ! */ 384: } 385: else 386: { /* no permission */ 387: io -> nrspdrop++; /* dropped */ 388: for (count2 = 0; count2 < count; count2++) 389: getc (infile); /* skip text */ 390: } 391: } 392: else 393: { /* copy already here */ 394: io -> nrspdrop++; /* on the floor */ 395: for (count2 = 0; count2 < count; count2++) 396: getc (infile); /* skip text */ 397: printf ("Duplicate response id=%ld@%s to note id=%ld@%s\n", 398: respid.uniqid, respid.sys, noteid.uniqid, noteid.sys); 399: } 400: if (lockit) 401: unlocknf (io, DSCRLOCK); /* no longer critical */ 402: }