|
|
1.1 root 1: /*
2: * This software is Copyright (c) 1986 by Rick Adams.
3: *
4: * Permission is hereby granted to copy, reproduce, redistribute or
5: * otherwise use this software as long as: there is no monetary
6: * profit gained specifically from the use or reproduction or this
7: * software, it is not sold, rented, traded or otherwise marketed, and
8: * this copyright notice is included prominently in any copy
9: * made.
10: *
11: * The author make no claims as to the fitness or correctness of
12: * this software for any use whatsoever, and it is provided as is.
13: * Any use of this software is at the user's own risk.
14: *
15: * This function initializes all the strings used for the various
16: * filenames. They cannot be compiled into the program, since that
17: * would be non-portable. With this convention, the netnews sub-system
18: * can be owned by any non-privileged user. It is also possible
19: * to work when the administration randomly moves users from one
20: * filesystem to another. The convention is that a particular user
21: * (HOME, see Makefile) is searched for in /etc/passwd and all files
22: * are presumed relative to there. This method also allows one copy
23: * of the object code to be used on ANY machine. (this code runs
24: * un-modified on 50+ machines at IH!!)
25: *
26: * The disadvantage to using this method is that all netnews programs
27: * (inews, readnews, rnews, checknews) must first search /etc/passwd
28: * before they can start up. This can cause significant overhead if
29: * you have a big password file.
30: *
31: * Some games are played with ifdefs to get four .o files out of this
32: * one source file. INEW is defined for inews, READ for readnews,
33: * CHKN for checknews, and EXP for expire.
34: */
35:
36: #ifdef SCCSID
37: static char *SccsId = "@(#)pathinit.c 1.24 10/7/87";
38: #endif /* SCCSID */
39:
40: #if defined(INEW) || defined(EXP)
41: #include "iparams.h"
42: #endif /* INEW || EXP */
43:
44: #ifdef READ
45: #include "rparams.h"
46: #endif /* READ */
47:
48: #if defined(CHKN)
49: #include "params.h"
50: #endif /* CHKN */
51:
52:
53: char *FROMSYSNAME, *PATHSYSNAME, *LOCALSYSNAME, *LOCALPATHSYSNAME;
54: char *SPOOL, *LIB, *BIN, *ACTIVE, *SUBFILE, *ARTFILE,
55: *username = "Unknown", *userhome;
56:
57: #ifdef INEW
58: char *LOCKFILE, *SEQFILE, *ARTICLE, *INFILE, *TELLME;
59:
60: int c_cancel(), c_newgroup(), c_ihave(), c_sendme(), c_rmgroup(),
61: c_sendsys(), c_version(), c_checkgroups(), c_unimp();
62:
63: struct msgtype msgtype[] = {
64: "cancel", NULL, c_cancel,
65: "newgroup", NULL, c_newgroup,
66: "ihave", NULL, c_ihave,
67: "sendme", NULL, c_sendme,
68: "sendbad", NULL, c_sendme,
69: "rmgroup", NULL, c_rmgroup,
70: "sendsys", NULL, c_sendsys,
71: "version", NULL, c_version,
72: "checkgroups", NULL, c_checkgroups,
73: "delsub", NULL, c_unimp,
74: NULL, NULL, NULL
75: };
76: #endif /* INEW */
77:
78: #if defined(INEW) || defined(READ)
79: char *ALIASES;
80: #endif /* INEW || READ */
81:
82: #ifdef EXP
83: char *OLDNEWS;
84: #endif /* EXP */
85:
86: #ifdef READ
87: char *MAILPARSER;
88: #endif /* READ */
89:
90:
91: struct passwd *getpwnam();
92: char *rindex();
93:
94: #define Sprintf(where,fmt,arg) (void) sprintf(bfr,fmt,arg); where = AllocCpy(bfr)
95:
96: char *
97: AllocCpy(cp)
98: register char *cp;
99: {
100: register char *mp;
101: char *malloc();
102:
103: mp = malloc((unsigned)strlen(cp) + 1);
104:
105: if (mp == NULL)
106: xerror("malloc failed on %s", cp);
107:
108: (void) strcpy(mp, cp);
109: return mp;
110: }
111:
112: pathinit()
113: {
114: #ifndef ROOTID
115: struct passwd *pw; /* struct for pw lookup */
116: #endif /* !ROOTID */
117: #ifdef EXP
118: char *p;
119: #endif /* EXP */
120: #ifndef CHKN
121: struct utsname ubuf;
122: char buf[BUFLEN];
123: extern char *mydomain();
124:
125: uname(&ubuf);
126:
127: #ifdef HIDDENNET_IN_LOCALSYSNAME
128: /* old compatibility code, remove when HIDDENNET is used no more */
129: if (STRCMP(ubuf.nodename, HIDDENNET) != 0)
130: (void) sprintf(buf, "%s.%s%s", ubuf.nodename, HIDDENNET,
131: mydomain());
132: else
133: #endif
134: (void) sprintf(buf, "%s%s", ubuf.nodename, mydomain());
135: LOCALSYSNAME = AllocCpy(buf);
136:
137: #ifdef GENERICFROM
138: (void) sprintf(buf, GENERICFROM, ubuf.nodename, mydomain());
139: FROMSYSNAME = AllocCpy(buf);
140: #else /* !GENERICFROM */
141: FROMSYSNAME = LOCALSYSNAME;
142: #endif /* !GENERICFROM */
143:
144: LOCALPATHSYSNAME = AllocCpy(ubuf.nodename);
145:
146: #ifdef GENERICPATH
147: (void) sprintf(buf, GENERICPATH, ubuf.nodename, mydomain());
148: PATHSYSNAME = AllocCpy(buf);
149: #else /* !GENERICPATH */
150: PATHSYSNAME = LOCALPATHSYSNAME;
151: #endif /* !GENERICPATH */
152:
153: #endif /* !CHKN */
154:
155: #ifdef HOME
156: /* Relative to the home directory of user HOME */
157: (void) sprintf(bfr, "%s/%s", logdir(HOME), SPOOLDIR);
158: SPOOL = AllocCpy(bfr);
159: (void) sprintf(bfr, "%s/%s", logdir(HOME), LIBDIR);
160: LIB = AllocCpy(bfr);
161: #else /* !HOME */
162: /* Fixed paths defined in Makefile */
163: SPOOL = AllocCpy(SPOOLDIR);
164: LIB = AllocCpy(LIBDIR);
165: #endif /* !HOME */
166:
167: #ifdef LOGDIR
168: (void) sprintf(bfr, "%s/%s", logdir(HOME), BINDIR);
169: BIN = AllocCpy(bfr);
170: #else /* !LOGDIR */
171: Sprintf(BIN, "%s", BINDIR);
172: #endif /* !LOGDIR */
173:
174: Sprintf(ACTIVE, "%s/active", LIB);
175:
176: #ifdef EXP
177: (void) strcpy(bfr, SPOOL);
178: p = rindex(bfr, '/');
179: if (p) {
180: strcpy(++p, "oldnews");
181: OLDNEWS = AllocCpy(bfr);
182: } else
183: OLDNEWS = AllocCpy("oldnews");
184: #endif /* EXP */
185:
186: #ifndef CHKN
187: Sprintf(SUBFILE, "%s/sys", LIB);
188: Sprintf(ARTFILE, "%s/history", LIB);
189: # endif /* !CHKN */
190:
191: # ifdef READ
192: #ifdef SENDMAIL
193: Sprintf(MAILPARSER, "%s -oi -oem", SENDMAIL);
194: #else /* !SENDMAIL */
195: Sprintf(MAILPARSER, "%s/recmail", LIB);
196: #endif /* !SENDMAIL */
197: # endif /* READ */
198:
199: # if defined(READ) || defined(INEW)
200: Sprintf(ALIASES, "%s/aliases", LIB);
201: # endif /* READ || INEW */
202: # ifdef INEW
203: Sprintf(LOCKFILE, "%s/LOCK", LIB);
204: Sprintf(SEQFILE, "%s/seq", LIB);
205: Sprintf(ARTICLE, "%s/.arXXXXXX", SPOOL);
206: Sprintf(INFILE, "%s/.inXXXXXX", SPOOL);
207: /*
208: * The person notified by the netnews sub-system. Again, no name is
209: * compiled in, but instead the information is taken from a file.
210: * If the file does not exist, a "default" person will get the mail.
211: * If the file exists, but is empty, nobody will get the mail. This
212: * may seem backwards, but is a better fail-safe.
213: */
214: # ifdef NOTIFY
215: parse_notify();
216: # endif /* NOTIFY */
217:
218: /*
219: * Since the netnews owner's id number is different on different
220: * systems, we'll extract it from the /etc/passwd file. If no entry,
221: * default to root. This id number seems to only be used to control who
222: * can input certain control messages or cancel any message. Note that
223: * entry is the name from the "notify" file as found above if possible.
224: * Defining ROOTID in defs.h hardwires in a number and avoids
225: * another search of /etc/passwd.
226: */
227: # ifndef ROOTID
228: if ((pw = getpwnam(TELLME)) != NULL)
229: ROOTID = pw->pw_uid;
230: else if ((pw = getpwnam(HOME)) != NULL)
231: ROOTID = pw->pw_uid;
232: else
233: ROOTID = 0; /* nobody left, let only root */
234: # endif /* !ROOTID */
235: #endif /* INEW */
236: }
237:
238: #ifdef INEW
239: #ifdef NOTIFY
240: /*
241: * Attempt to parse the LIB/notify file into the global structure msgtype[].
242: */
243: parse_notify()
244: {
245: FILE *nfd;
246: int valid = 0, done = 0;
247: register struct msgtype *mp;
248: char mtype[BUFLEN], addr[BUFLEN];
249:
250: (void) sprintf(bfr, "%s/notify", LIB);
251: #ifndef ROOTID
252: TELLME = AllocCpy(NOTIFY);
253: #endif /* !ROOTID */
254: if ( (nfd = fopen(bfr, "r")) == NULL) {
255: /*
256: * Set defaults to NOTIFY
257: */
258: #ifdef debug
259: log("parse_notify: %s/notify not found", LIB);
260: #endif /* debug */
261: (void)setmsg("all", NOTIFY);
262: return;
263: }
264: do {
265: mtype[0] = addr[0] = 0;
266: switch( get_notify(nfd, mtype, addr) ) {
267: case 0:
268: continue;
269: case 1:
270: valid += setmsg(mtype, "");
271: break;
272: case 2:
273: valid += setmsg(mtype, addr);
274: break;
275: case -1:
276: if( !valid ) {
277: #ifdef debug
278: log("parse_notify: no valid entries found.");
279: #endif /* debug */
280: setmsg("all", ""); /* send mail to no one */
281: }
282: done = 1;
283: }
284: } while( !done );
285:
286: /*
287: * point to zero length string for all entries we haven't touched
288: */
289: for(mp=msgtype; mp->m_name; mp++)
290: if(mp->m_who_to == 0)
291: mp->m_who_to = "";
292: }
293:
294: setmsg(what, to)
295: char *what, *to;
296: {
297: register struct msgtype *mp;
298: #ifdef debug
299: log("setmsg: what='%s', to='%s'", what, to);
300: #endif /* debug */
301: /*
302: * Special case for "all"
303: */
304: if(STRCMP(what, "all") == 0) {
305: for(mp=msgtype; mp->m_name; mp++) {
306: mp->m_who_to = AllocCpy(to);
307: #ifdef debug
308: log("setmsg: '%s'='%s'", mp->m_name, mp->m_who_to);
309: #endif /* debug */
310: }
311: return 1;
312: }
313:
314: for(mp=msgtype; mp->m_name; mp++)
315: if(STRCMP(mp->m_name, what) == 0) {
316: mp->m_who_to = AllocCpy(to);
317: #ifdef debug
318: log("setmsg: '%s'='%s'", mp->m_name, mp->m_who_to);
319: #endif /* debug */
320: return 1;
321: }
322: return 0;
323: }
324:
325: static
326: get_notify(fp, s, t)
327: FILE *fp;
328: register char *s, *t;
329: {
330: register char *cp;
331: char buf[BUFSIZ];
332:
333: if( cp=fgets(buf, sizeof(buf), fp ) ) {
334: if( *cp == '\n' )
335: return 0;
336: while(*cp && *cp != ' ' && *cp != '\t' && *cp != '\n')
337: *s++ = *cp++;
338: *s = '\0'; /* terminate first string */
339:
340: while(*cp && (*cp == ' ' || *cp == '\t' || *cp == '\n') )
341: cp++; /* look for start of second */
342: if( !*cp || *cp == '\n' )
343: return 1; /* no second string */
344:
345: while( *cp && *cp != '\n' )
346: *t++ = *cp++;
347: *t = '\0';
348: return 2;
349: } else
350: return -1;
351: }
352: #endif /* NOTIFY */
353: #endif /* INEW */
354:
355: #ifndef CHKN
356: /*
357: * At sites where the are many mail domains within the support area of a single
358: * news administrator, it is much nicer to be able to read the local domain of
359: * a machine from a file. What we do here is:
360: * 1) Check for the presence of a LIBDIR/localdomain file. If it doesn't
361: * exist,assume that MYDOMAIN should be used instead.
362: * 2) If it does exist, we make the following assumptions:
363: * a) If it is empty, has only comments, or only blank lines; we assume
364: * the domain is desired to be a zero length string ( ie ""). (this
365: * implies that the domain name is contained in the hostname.)
366: * b) If it is not empty, we assume the first line not beginning with a
367: * '#', blank/tab, or newline is the desired domain name.
368: * A like '.UUCP' or '.TEK.COM' should be used. We could insure that
369: * the line begin with a '.' to be a valid domain name, but I don't
370: * think it is necessary to put that restriction on it.
371: */
372: char *
373: mydomain()
374: {
375: static char *md = NULL;
376: register char *cp;
377: FILE *fp = NULL;
378: char fbuf[BUFLEN];
379: extern char *malloc(), *strcpy(), *index();
380:
381: if(md) /* we've been here before, so just return what we found */
382: return(md);
383:
384: (void) sprintf(fbuf,"%s/localdomain", LIBDIR);
385: if ( (fp = fopen(fbuf,"r")) == NULL) {
386: md = MYDOMAIN; /* No localdomain file, use MYDOMAIN instead */
387: } else {
388: while(fgets(fbuf, sizeof(fbuf), fp) ) {
389: if( *fbuf == '\n' || *fbuf == '#'
390: || *fbuf == ' ' || *fbuf == '\t')
391: continue;
392:
393: if( cp = index(fbuf, '\n') )
394: *cp = '\0';
395:
396: if ( (md = malloc(strlen(fbuf) + 1)) == NULL)
397: md = MYDOMAIN; /* punt here */
398: else
399: (void)strcpy(md, fbuf);
400: break;
401: }
402: }
403:
404: if(fp)
405: (void)fclose(fp);
406:
407: if( md == NULL)
408: md = "";
409:
410: return md;
411: }
412: #endif /* !CHKN */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.