|
|
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.