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.0.2 86/05/22 11:19:09 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:     unsigned short  restoremode;
  58:     int     old_umask;                  /* save his mask */
  59: 
  60:     if (chkpath (nfname))
  61:     {
  62:     printf ("Invalid notesfile name: `%s'\n", nfname);
  63:     return (-1);                    /* bad return */
  64:     }
  65: 
  66:     if (stat (basedir, &statval) == -1)         /* can we read basedir? */
  67:     {
  68:     printf ("can't stat (assumed directory) %s\n", basedir);
  69:     return (-1);                    /* error in creation */
  70:     }
  71: 
  72:     sprintf (pathname, "%s/%s", basedir, nfname);
  73:     if (stat (pathname, &statval) == 0)         /* check existence */
  74:     {
  75:     printf ("Notesfile already exists\n");
  76: /*
  77:  *	Could talk about whether it's a file or directory...
  78:  *	but probably not worth it.
  79:  */
  80:     return (-2);                    /* already exists */
  81:     }
  82: 
  83:     old_umask = umask (N_UMASK);            /* clear mask */
  84: #ifdef  BSD42
  85:     {
  86:     /*
  87: 	 * take advantage of 4.2 bsd system call...
  88: 	 */
  89:     mkdir (pathname, 0770);             /* make the directory */
  90:     }
  91: #else
  92:     {
  93:     /*
  94: 	 * do it the hard way ... by forking children
  95: 	 */
  96: #ifdef  USG
  97:     /*
  98: 	 * make sure we can create the directory; restore it later
  99: 	 */
 100:     if (stat (basedir, &statval) == 0)
 101:         restoremode = statval.st_mode;
 102:     else
 103:         restoremode = 0775;
 104:     chmod (basedir, 0777);
 105: #else
 106:     /*
 107: 	 * under non-USG boxes, we can do setuid(geteuid()) and have it
 108: 	 * make the real uid match the effective uid
 109: 	 */
 110:     globuid = Notesuid;             /* must be notes to work */
 111: #endif	USG
 112: 
 113: #ifndef FASTFORK
 114:     sprintf (cmdline, "mkdir %s", pathname);    /* build command */
 115:     dounix (cmdline, 1, 0);             /* execute, captain */
 116: #ifdef  USG
 117:     /*
 118: 	 * fix owner on USG boxes where setuid(geteuid()) doesn't do
 119: 	 * what it does on V7 and BSd boxes (set both to the effective)
 120: 	 */
 121:     sprintf (cmdline, "chgrp %s %s", NOTESGRP, pathname);/* fix group */
 122:     dounix (cmdline, 1, 0);
 123:     sprintf (cmdline, "chown %s %s", NOTES, pathname);/* fix owner */
 124:     dounix (cmdline, 1, 0);
 125: #endif	USG
 126: #else
 127:     dounix (1, 0, "/bin/mkdir", pathname, 0, 0, 0);
 128: #ifdef  USG
 129:     /*
 130: 	 * atone for the USG behavior of setuid(geteuid())
 131: 	 */
 132:     dounix (1, 0, "/bin/chgrp", NOTESGRP, pathname, 0, 0);
 133:     dounix (1, 0, "/bin/chown", NOTES, pathname, 0, 0);
 134: #endif	USG
 135: #endif	FASTFORK
 136:     /*
 137: 	 * done making things. set the right permissions on
 138: 	 * basedir (if we screwed with it) and pathname.
 139: 	 */
 140: #ifdef  USG
 141:     chmod (basedir, restoremode);
 142: #endif	USG
 143:     chmod (pathname, 0770);
 144:     }
 145: #endif	BSD42
 146: 
 147: /*
 148:  *	Now build the files within the directory
 149:  *	Build a default notesfile descriptor and then override with
 150:  *	his specific values.
 151:  */
 152: 
 153: 
 154:     initdescr (&descr);                 /* make default */
 155: 
 156:     glocknf (&io, SEQLOCK);             /* grab sequence # */
 157:     sprintf (cmdline, "%s/%s", Mstdir, SEQ);
 158:     x ((seqfile = fopen (cmdline, "r")) == NULL, "mknf: open unique");
 159:     x (fscanf (seqfile, "%d", &i) != 1, "mknf: unique read");
 160:     descr.d_nfnum = i++;
 161:     fclose (seqfile);                   /* close it and */
 162:     x ((seqfile = fopen (cmdline, "w")) == NULL, "mknf: reopen unique");
 163:     fprintf (seqfile, "%d\n", i);           /* update */
 164:     fclose (seqfile);
 165:     gunlocknf (&io, SEQLOCK);               /* release file */
 166: 
 167:     strncpy (descr.d_title, nfname, NNLEN);
 168:     descr.d_title[NNLEN - 1] = '\0';            /* null it */
 169: 
 170:     if (Aflag)                      /* he wants anon */
 171:     descr.d_stat |= ANONOK;
 172:     if (Oflag)                      /* open */
 173:     descr.d_stat |= OPEN;
 174:     if (Nflag)                      /* networkable */
 175:     descr.d_stat |= NETWRKD;
 176: 
 177: 
 178:     sprintf (filename, "%s/%s", pathname, INDEXN);  /* make the file */
 179:     x ((fid = creat (filename, 0660)) < 0, "build:  Cant create note.indx");
 180:     x (write (fid, &descr, sizeof descr) != sizeof descr,
 181:         "build:  Cant write note.indx");
 182:     x (close (fid) < 0, "build: bad note.indx close");
 183: 
 184: /*
 185:  *	Now create the text file
 186:  */
 187: 
 188:     sprintf (filename, "%s/%s", pathname, TEXT);
 189:     x ((fid = creat (filename, 0660)) < 0, "build:  Cant create text");
 190:     freetext.addr = sizeof freetext;            /* past address slot */
 191:     if (freetext.addr & 1)              /* odd (shouldn't be) */
 192:     freetext.addr++;                /* make it even */
 193:     x (write (fid, &freetext, sizeof freetext) != sizeof freetext,
 194:         "build:  Cant write text");
 195: 
 196:     x (close (fid) < 0, "build: bad text close");
 197: 
 198: /*
 199:  *	Now the response index file.
 200:  */
 201: 
 202:     sprintf (filename, "%s/%s", pathname, INDEXR);
 203:     x ((fid = creat (filename, 0660)) < 0, "build:  Cant create resp.indx");
 204:     i = 0;                      /* resp 0 slot free */
 205:     x (write (fid, &i, sizeof i) != sizeof i, "build:  Cant write resp.indx");
 206:     x (close (fid) < 0, "build: bad close of resp.indx");
 207: 
 208: /*
 209:  *	Build the access list.  This is a two phase operation.
 210:  *	The first phase builds a default access list.  This
 211:  *	is set up with one director (the notes signon) and
 212:  *	a group "Other" with read/write.  System "Other" also
 213:  *	has read/write privileges.  This is basically a wide-open
 214:  *	policy.
 215:  *	The second phase is customization.  This step uses the
 216:  *	contents of the file ..../notes/.utilities/access-template
 217:  *	as a batch of access specifications (like nfaccess)
 218:  *	to add/modify specific permissions.
 219:  */
 220: 
 221:     sprintf (filename, "%s/%s", pathname, ACCESS);  /* build simple */
 222:     x ((fid = creat (filename, 0660)) < 0, "build: couldnt create access");
 223:     getname (&me, 0);                   /* grab "notes" */
 224:     perms[0].ptype = PERMUSER;
 225:     strcpy (perms[0].name, me.aname);
 226:     perms[0].perms = READOK + WRITOK + RESPOK + DRCTOK;
 227:     perms[1].ptype = PERMGROUP;
 228:     strcpy (perms[1].name, "Other");
 229:     perms[1].perms = DFLTPERMS;
 230:     perms[2].ptype = PERMSYSTEM;
 231:     strcpy (perms[2].name, "Other");
 232:     perms[2].perms = DFLTPERMS;
 233: 
 234:     x (write (fid, perms, 3 * sizeof pentry) != 3 * sizeof pentry,
 235:         "build: bad access write");
 236:     x (close (fid) < 0, "build: close access broke");
 237: 
 238: /*
 239:  *	Now, process any extra specifications from utilities/access-template
 240:  *	Don't do anything unless the file exists.
 241:  */
 242: 
 243:     sprintf (filename, "%s/%s/%s-template", Mstdir, UTILITY, ACCESS);
 244:     if ((pfile = fopen (filename, "r")) != NULL)
 245:     {
 246:     char    pline[BUFSIZ];
 247:     int     nmodes,
 248:             zapindex;
 249: 
 250: 
 251:     nmodes = 0;                 /* load perms[] */
 252:     while (fgets (pline, sizeof pline, pfile) != NULL)
 253:     {
 254:         if (pline[0] == '#')            /* comment */
 255:         continue;
 256:         if (nmodes == NPERMS)           /* full list */
 257:         break;
 258:         zapindex = strlen (pline);
 259:         if (pline[zapindex] == '\n')
 260:         pline[zapindex] = '\0';         /* zap newline */
 261:         if (parsemode (pline, &perms[nmodes], 0) == 0)/* worked? */
 262:         nmodes++;               /* bump counter */
 263:     }
 264:     fclose (pfile);                 /* done with template */
 265:     if (init (&io, pathname) >= 0)          /* open the nf */
 266:     {
 267:         addmodes (&io, nmodes, perms, 0);       /* add them */
 268:         closenf (&io);
 269:     }
 270:     }
 271: 
 272:     x (umask (old_umask) != N_UMASK, "buildnf: reset umask");/* restore umask */
 273:     return 0;                       /* all's well */
 274: }
 275: 
 276: /*
 277:  *	initdescr(&descr_f)
 278:  *
 279:  *	Load a descriptor with a lot of default information
 280:  *	Other people will load things like titles and specific
 281:  *	values of flags.
 282:  */
 283: 
 284: initdescr (descr)
 285: struct descr_f *descr;
 286: {
 287:     register int    i;
 288:     register char  *p;
 289: 
 290:     descr -> d_format = DBVERSION;          /* version */
 291:     strcpy (descr -> d_title, "** Notesfile Title **");
 292:     strcpy (descr -> d_drmes, "** director message **");
 293:     descr -> d_plcy = 0;                /* no policy note */
 294:     descr -> d_id.uniqid = 0;               /* unique within nf */
 295:     strcpy (descr -> d_id.sys, System);         /* and system name */
 296: 
 297:     gettime (&descr -> d_lstxmit);          /* last network xmit */
 298:     gettime (&descr -> d_lastm);            /* last modified now */
 299:     gettime (&descr -> d_created);          /* creation date */
 300:     gettime (&descr -> d_lastuse);          /* for days online */
 301:     descr -> d_daysused = 1;                /* count making it ! */
 302:     descr -> d_stat = 0;                /* no special status */
 303:     descr -> d_nnote = 0;               /* no notes in file */
 304:     descr -> d_delnote = descr -> d_delresp = 0;    /* no holes */
 305:     descr -> d_archtime = 0;                /* default time */
 306:     descr -> d_workset = 0;             /* working set */
 307:     descr -> d_archkeep = KEEPDFLT;         /* keep/delete */
 308:     descr -> d_dmesgstat = DIRDFLT;         /* dirmsg to expire */
 309: 
 310:     descr -> d_rspwrit = descr -> d_notwrit = 0;    /* initialize stats */
 311:     descr -> d_rspread = descr -> d_notread = 0;
 312:     descr -> d_notdrop = descr -> d_rspdrop = 0;
 313:     descr -> d_orphans = 0;             /* orphan chains */
 314:     descr -> d_adopted = 0;             /* chains adopted */
 315:     descr -> entries = 0;               /* user entries */
 316:     descr -> walltime = 0;
 317:     descr -> d_rspxmit = descr -> d_notxmit = 0;    /* network activity */
 318:     descr -> d_rsprcvd = descr -> d_notrcvd = 0;
 319:     descr -> netwrkouts = descr -> netwrkins = 0;
 320:     descr -> d_longnote = MAXMSG;           /* longest permitted */
 321: }

Defined functions

initdescr defined in line 284; used 1 times

Defined variables

rcsid defined in line 7; never used

Defined macros

N_UMASK defined in line 33; used 2 times
Last modified: 1986-05-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3376
Valid CSS Valid XHTML 1.0 Strict