|
|
1.1 ! root 1: #include "parms.h" ! 2: #include "structs.h" ! 3: #include <sys/types.h> ! 4: #include <sys/stat.h> ! 5: ! 6: #ifdef RCSIDENT ! 7: static char rcsid[] = "$Header: buildnf.c,v 1.7 85/01/18 15:05:13 notes Rel $"; ! 8: #endif RCSIDENT ! 9: ! 10: /* ! 11: * buildnf ! 12: * ! 13: * A subroutine which creates notesfiles. Given the (1) name of ! 14: * the new notesfile and (2) the anonymous, open, and ! 15: * networked flags this routine will create a new notesfile, ! 16: * provided that it does not exist already. ! 17: * ! 18: * This routine will blindly create the notesfile. It does not ! 19: * check the real uid to see if it should create a notesfile or ! 20: * not. ! 21: * ! 22: * Returns: 0 Notesfile created ! 23: * -1 Error in notesfile creation ! 24: * -2 Notesfile exists ! 25: * ! 26: * Extracted from old "mknf" mainline. Modified mknf so it ! 27: * calls this routine. ! 28: * Also put conditional code into newsinput.c to create the ! 29: * new notesfile if desired. ! 30: * ! 31: * Original Coding: Ray Essick October 13, 1982 ! 32: */ ! 33: #define N_UMASK 0 /* when making nf's */ ! 34: ! 35: buildnf (nfname, basedir, Aflag, Oflag, Nflag) ! 36: char *nfname; ! 37: char *basedir; /* nf directory */ ! 38: int Aflag, ! 39: Oflag, ! 40: Nflag; ! 41: { ! 42: struct io_f io; ! 43: char *p; /* misc. pointer */ ! 44: int i; /* misc counter */ ! 45: int fid; /* misc file id */ ! 46: struct daddr_f freetext; /* for writing */ ! 47: struct descr_f descr; /* for writing, too */ ! 48: struct perm_f perms[NPERMS]; ! 49: struct perm_f pentry; /* single entry */ ! 50: struct auth_f me; /* for access list */ ! 51: char cmdline[WDLEN]; /* for mkdir */ ! 52: char pathname[WDLEN]; /* for filenames */ ! 53: char filename[WDLEN]; /* for filenames */ ! 54: FILE * seqfile; ! 55: FILE * pfile; /* access list mods */ ! 56: struct stat statval; /* testing existence */ ! 57: int old_umask; /* save his mask */ ! 58: ! 59: globuid = Notesuid; /* must be notes to work */ ! 60: /* users can't see this */ ! 61: if (chkpath (nfname)) ! 62: { ! 63: printf ("Invalid notesfile name: `%s'\n", nfname); ! 64: return (-1); /* bad return */ ! 65: } ! 66: ! 67: if (stat (basedir, &statval) == -1) /* can we read basedir? */ ! 68: { ! 69: printf ("can't stat (assumed directory) %s\n", basedir); ! 70: return (-1); /* error in creation */ ! 71: } ! 72: ! 73: sprintf (pathname, "%s/%s", basedir, nfname); ! 74: if (stat (pathname, &statval) == 0) /* check existence */ ! 75: { ! 76: printf ("Notesfile already exists\n"); ! 77: /* ! 78: * Could talk about whether it's a file or directory... ! 79: * but probably not worth it. ! 80: */ ! 81: return (-2); /* already exists */ ! 82: } ! 83: ! 84: old_umask = umask (N_UMASK); /* clear mask */ ! 85: #ifdef BSD42 ! 86: { ! 87: /* ! 88: * take advantage of 4.2 bsd system call... ! 89: */ ! 90: mkdir (pathname, 0770); /* make the directory */ ! 91: } ! 92: #else ! 93: { ! 94: /* ! 95: * do it the hard way ... by forking children ! 96: */ ! 97: #ifndef FASTFORK ! 98: sprintf (cmdline, "mkdir %s", pathname); /* build command */ ! 99: dounix (cmdline, 1, 0); /* execute, captain */ ! 100: sprintf (cmdline, "chmod 0770 %s", pathname); /* protect him */ ! 101: dounix (cmdline, 1, 0); /* really do it */ ! 102: #else ! 103: dounix (1, 0, "/bin/mkdir", pathname, 0, 0, 0); ! 104: dounix (1, 0, "/bin/chmod", "0770", pathname, 0, 0); ! 105: #endif FASTFORK ! 106: } ! 107: #endif BSD42 ! 108: ! 109: /* ! 110: * Now build the files within the directory ! 111: * Build a default notesfile descriptor and then override with ! 112: * his specific values. ! 113: */ ! 114: ! 115: ! 116: initdescr (&descr); /* make default */ ! 117: ! 118: glocknf (&io, SEQLOCK); /* grab sequence # */ ! 119: sprintf (cmdline, "%s/%s", Mstdir, SEQ); ! 120: x ((seqfile = fopen (cmdline, "r")) == NULL, "mknf: open unique"); ! 121: x (fscanf (seqfile, "%d", &i) != 1, "mknf: unique read"); ! 122: descr.d_nfnum = i++; ! 123: fclose (seqfile); /* close it and */ ! 124: x ((seqfile = fopen (cmdline, "w")) == NULL, "mknf: reopen unique"); ! 125: fprintf (seqfile, "%d\n", i); /* update */ ! 126: fclose (seqfile); ! 127: gunlocknf (&io, SEQLOCK); /* release file */ ! 128: ! 129: strncpy (descr.d_title, nfname, NNLEN); ! 130: descr.d_title[NNLEN - 1] = '\0'; /* null it */ ! 131: ! 132: if (Aflag) /* he wants anon */ ! 133: descr.d_stat |= ANONOK; ! 134: if (Oflag) /* open */ ! 135: descr.d_stat |= OPEN; ! 136: if (Nflag) /* networkable */ ! 137: descr.d_stat |= NETWRKD; ! 138: ! 139: ! 140: sprintf (filename, "%s/%s", pathname, INDEXN); /* make the file */ ! 141: x ((fid = creat (filename, 0660)) < 0, "build: Cant create note.indx"); ! 142: x (write (fid, &descr, sizeof descr) != sizeof descr, ! 143: "build: Cant write note.indx"); ! 144: x (close (fid) < 0, "build: bad note.indx close"); ! 145: ! 146: /* ! 147: * Now create the text file ! 148: */ ! 149: ! 150: sprintf (filename, "%s/%s", pathname, TEXT); ! 151: x ((fid = creat (filename, 0660)) < 0, "build: Cant create text"); ! 152: freetext.addr = sizeof freetext; /* past address slot */ ! 153: if (freetext.addr & 1) /* odd (shouldn't be) */ ! 154: freetext.addr++; /* make it even */ ! 155: x (write (fid, &freetext, sizeof freetext) != sizeof freetext, ! 156: "build: Cant write text"); ! 157: ! 158: x (close (fid) < 0, "build: bad text close"); ! 159: ! 160: /* ! 161: * Now the response index file. ! 162: */ ! 163: ! 164: sprintf (filename, "%s/%s", pathname, INDEXR); ! 165: x ((fid = creat (filename, 0660)) < 0, "build: Cant create resp.indx"); ! 166: i = 0; /* resp 0 slot free */ ! 167: x (write (fid, &i, sizeof i) != sizeof i, "build: Cant write resp.indx"); ! 168: x (close (fid) < 0, "build: bad close of resp.indx"); ! 169: ! 170: /* ! 171: * Build the access list. This is a two phase operation. ! 172: * The first phase builds a default access list. This ! 173: * is set up with one director (the notes signon) and ! 174: * a group "Other" with read/write. System "Other" also ! 175: * has read/write privileges. This is basically a wide-open ! 176: * policy. ! 177: * The second phase is customization. This step uses the ! 178: * contents of the file ..../notes/.utilities/access-template ! 179: * as a batch of access specifications (like nfaccess) ! 180: * to add/modify specific permissions. ! 181: */ ! 182: ! 183: sprintf (filename, "%s/%s", pathname, ACCESS); /* build simple */ ! 184: x ((fid = creat (filename, 0660)) < 0, "build: couldnt create access"); ! 185: getname (&me, 0); /* grab "notes" */ ! 186: perms[0].ptype = PERMUSER; ! 187: strcpy (perms[0].name, me.aname); ! 188: perms[0].perms = READOK + WRITOK + RESPOK + DRCTOK; ! 189: perms[1].ptype = PERMGROUP; ! 190: strcpy (perms[1].name, "Other"); ! 191: perms[1].perms = DFLTPERMS; ! 192: perms[2].ptype = PERMSYSTEM; ! 193: strcpy (perms[2].name, "Other"); ! 194: perms[2].perms = DFLTPERMS; ! 195: ! 196: x (write (fid, perms, 3 * sizeof pentry) != 3 * sizeof pentry, ! 197: "build: bad access write"); ! 198: x (close (fid) < 0, "build: close access broke"); ! 199: ! 200: /* ! 201: * Now, process any extra specifications from utilities/access-template ! 202: * Don't do anything unless the file exists. ! 203: */ ! 204: ! 205: sprintf (filename, "%s/%s/%s-template", Mstdir, UTILITY, ACCESS); ! 206: if ((pfile = fopen (filename, "r")) != NULL) ! 207: { ! 208: char pline[BUFSIZ]; ! 209: int nmodes, ! 210: zapindex; ! 211: ! 212: ! 213: nmodes = 0; /* load perms[] */ ! 214: while (fgets (pline, sizeof pline, pfile) != NULL) ! 215: { ! 216: if (pline[0] == '#') /* comment */ ! 217: continue; ! 218: if (nmodes == NPERMS) /* full list */ ! 219: break; ! 220: zapindex = strlen (pline); ! 221: if (pline[zapindex] == '\n') ! 222: pline[zapindex] = '\0'; /* zap newline */ ! 223: if (parsemode (pline, &perms[nmodes], 0) == 0)/* worked? */ ! 224: nmodes++; /* bump counter */ ! 225: } ! 226: fclose (pfile); /* done with template */ ! 227: if (init (&io, pathname) >= 0) /* open the nf */ ! 228: { ! 229: addmodes (&io, nmodes, perms, 0); /* add them */ ! 230: closenf (&io); ! 231: } ! 232: } ! 233: ! 234: x (umask (old_umask) != N_UMASK, "buildnf: reset umask");/* restore umask */ ! 235: return 0; /* all's well */ ! 236: } ! 237: ! 238: /* ! 239: * initdescr(&descr_f) ! 240: * ! 241: * Load a descriptor with a lot of default information ! 242: * Other people will load things like titles and specific ! 243: * values of flags. ! 244: */ ! 245: ! 246: initdescr (descr) ! 247: struct descr_f *descr; ! 248: { ! 249: register int i; ! 250: register char *p; ! 251: ! 252: descr -> d_format = DBVERSION; /* version */ ! 253: strcpy (descr -> d_title, "** Notesfile Title **"); ! 254: strcpy (descr -> d_drmes, "** director message **"); ! 255: descr -> d_plcy = 0; /* no policy note */ ! 256: descr -> d_id.uniqid = 0; /* unique within nf */ ! 257: strcpy (descr -> d_id.sys, System); /* and system name */ ! 258: ! 259: gettime (&descr -> d_lstxmit); /* last network xmit */ ! 260: gettime (&descr -> d_lastm); /* last modified now */ ! 261: gettime (&descr -> d_created); /* creation date */ ! 262: gettime (&descr -> d_lastuse); /* for days online */ ! 263: descr -> d_daysused = 1; /* count making it ! */ ! 264: descr -> d_stat = 0; /* no special status */ ! 265: descr -> d_nnote = 0; /* no notes in file */ ! 266: descr -> d_delnote = descr -> d_delresp = 0; /* no holes */ ! 267: descr -> d_archtime = 0; /* default time */ ! 268: descr -> d_workset = 0; /* working set */ ! 269: descr -> d_archkeep = KEEPDFLT; /* keep/delete */ ! 270: descr -> d_dmesgstat = DIRDFLT; /* dirmsg to expire */ ! 271: ! 272: descr -> d_rspwrit = descr -> d_notwrit = 0; /* initialize stats */ ! 273: descr -> d_rspread = descr -> d_notread = 0; ! 274: descr -> d_notdrop = descr -> d_rspdrop = 0; ! 275: descr -> d_orphans = 0; /* orphan chains */ ! 276: descr -> d_adopted = 0; /* chains adopted */ ! 277: descr -> entries = 0; /* user entries */ ! 278: descr -> walltime = 0; ! 279: descr -> d_rspxmit = descr -> d_notxmit = 0; /* network activity */ ! 280: descr -> d_rsprcvd = descr -> d_notrcvd = 0; ! 281: descr -> netwrkouts = descr -> netwrkins = 0; ! 282: descr -> d_longnote = MAXMSG; /* longest permitted */ ! 283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.