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:  * funcs - functions used by many programs
  16:  */
  17: 
  18: #ifdef SCCSID
  19: static char *SccsId = "@(#)funcs.c	2.31	1/17/86";
  20: #endif /* SCCSID */
  21: 
  22: /*LINTLIBRARY*/
  23: 
  24: #include "params.h"
  25: #include <errno.h>
  26: #if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
  27: #include <fcntl.h>
  28: #endif /* !v7 */
  29: 
  30: extern char *Progname;
  31: 
  32: /*
  33:  * News group matching.
  34:  *
  35:  * nglist is a list of newsgroups.
  36:  * sublist is a list of subscriptions.
  37:  * sublist may have "meta newsgroups" in it.
  38:  * All fields are NGDELIM separated,
  39:  * and there is an NGDELIM at the end of each argument.
  40:  *
  41:  * Currently implemented glitches:
  42:  * sublist uses 'all' like shell uses '*', and '.' like shell '/'.
  43:  * If subscription X matches Y, it also matches Y.anything.
  44:  */
  45: ngmatch(nglist, sublist)
  46: register char *nglist, *sublist;
  47: {
  48:     register char *n, *s;
  49:     register int rc;
  50: 
  51:     rc = FALSE;
  52:     for (n = nglist; *n != '\0' && rc == FALSE;) {
  53:         for (s = sublist; *s != '\0';) {
  54:             if (*s != NEGCHAR)
  55:                 rc = rc || ptrncmp(s, n);
  56:             else
  57:                 rc = rc && !ptrncmp(s+1, n);
  58:             while (*s++ != NGDELIM && *s != '\0')
  59:                 ;
  60:         }
  61:         while (*n++ != NGDELIM && *n != '\0')
  62:             ;
  63:     }
  64:     return rc;
  65: }
  66: 
  67: /*
  68:  * Compare two newsgroups for equality.
  69:  * The first one may be a "meta" newsgroup.
  70:  */
  71: ptrncmp(ng1, ng2)
  72: register char *ng1, *ng2;
  73: {
  74:     while (*ng1 != NGDELIM && *ng1 != '\0') {
  75:         if (ng1[0]=='a' && ng1[1]=='l' && ng1[2]=='l') {
  76:             ng1 += 3;
  77:             while (*ng2 != NGDELIM && *ng2 != '.' && *ng2 != '\0')
  78:                 if (ptrncmp(ng1, ng2++))
  79:                     return(TRUE);
  80:             return ptrncmp(ng1, ng2);
  81:         } else if (*ng1++ != *ng2++)
  82:             return FALSE;
  83:     }
  84:     return *ng2 == '.' || *ng2 == NGDELIM || *ng2 == '\0';
  85: }
  86: 
  87: /*
  88:  * Exec the shell.
  89:  * This version resets uid, gid, and umask.
  90:  * Called with fsubr(ushell, s, NULL)
  91:  */
  92: /* ARGSUSED */
  93: ushell(s, dummy)
  94: char *s, *dummy;
  95: {
  96:     (void) umask(savmask);
  97:     (void) setgid(gid);
  98:     (void) setuid(uid);
  99:     xshell(s);
 100: }
 101: 
 102: /*
 103:  * Exec the shell.
 104:  */
 105: 
 106: #ifdef lint
 107: char    **environ;
 108: #else /* !lint */
 109: extern char **environ;
 110: #endif /* !lint */
 111: 
 112: xshell(s)
 113: char *s;
 114: {
 115:     char *env[100], **envp;
 116:     char a[BUFLEN + 2];
 117:     extern char filename[];
 118:     /* set $A */
 119:     (void) sprintf(a, "A=%s", filename);
 120:     env[0] = a;
 121:     for (envp = env + 1 ; *environ != NULL && envp < env + 98 ; environ++)
 122:         if ((*environ)[0] != 'A' || (*environ)[1] != '=')
 123:             *envp++ = *environ;
 124:     *envp = NULL;
 125: 
 126:     execle(SHELL, SHELL, "-c", s, (char *)0, env);
 127:     xerror("No shell!");
 128: }
 129: 
 130: /*
 131:  * Fork and call a subroutine with two args.
 132:  * Return pid without waiting.
 133:  */
 134: fsubr(f, s1, s2)
 135: int (*f)();
 136: char *s1, *s2;
 137: {
 138:     register int pid;
 139: 
 140:     while ((pid = fork()) == -1)
 141:         sleep((unsigned)1);
 142:     if (pid == 0) {
 143:         (*f)(s1, s2);
 144:         exit(0);
 145:     }
 146:     return pid;
 147: }
 148: 
 149: /*
 150:  * Wait on a child process.
 151:  */
 152: fwait(pid)
 153: register int pid;
 154: {
 155:     register int w;
 156:     int status;
 157:     int (*onhup)(), (*onint)();
 158: 
 159:     onint = signal(SIGINT, SIG_IGN);
 160:     onhup = signal(SIGHUP, SIG_IGN);
 161:     while ((w = wait(&status)) != pid && w != -1)
 162:         ;
 163:     if (w == -1)
 164:         status = -1;
 165:     (void) signal(SIGINT, onint);
 166:     (void) signal(SIGHUP, onhup);
 167:     return status;
 168: }
 169: 
 170: /*
 171:  * Strip trailing newlines, blanks, and tabs from 's'.
 172:  * Return TRUE if newline was found, else FALSE.
 173:  */
 174: nstrip(s)
 175: register char *s;
 176: {
 177:     register char *p;
 178:     register int rc;
 179: 
 180:     rc = FALSE;
 181:     p = s;
 182:     while (*p)
 183:         if (*p++ == '\n')
 184:             rc = TRUE;
 185:     while (--p >= s && (*p == '\n' || *p == ' ' || *p == '\t'));
 186:     *++p = '\0';
 187:     return rc;
 188: }
 189: 
 190: /*
 191:  * Local open routine.
 192:  */
 193: FILE *
 194: xfopen(name, fmode)
 195: register char *name, *fmode;
 196: {
 197:     register FILE *fp;
 198:     char    *fname;
 199:     extern int errno;
 200: 
 201:     if ((fp = fopen(name, fmode)) == NULL) {
 202: #ifdef IHCC
 203:         /*
 204: 		 * IHCC users only see the "filename" that was in trouble,
 205: 		 * not the whole path.  (for security!)
 206: 		 */
 207:         fname = rindex(name, '/') + 1;
 208: #else
 209:         fname = name;
 210: #endif
 211:         xerror("Cannot open %s (%s): %s", fname, fmode, errmsg(errno));
 212:     }
 213:     /* kludge for setuid not being honored for root */
 214:     if ((uid == 0) && (duid != 0) && ((*fmode == 'a') || (*fmode == 'w')))
 215:         (void) chown(name, duid, dgid);
 216:     return fp;
 217: }
 218: 
 219: char *
 220: errmsg(code)
 221: int code;
 222: {
 223:     extern int sys_nerr;
 224:     extern char *sys_errlist[];
 225:     static char ebuf[6+5+1];
 226: 
 227:     if (code > sys_nerr) {
 228:         (void) sprintf(ebuf, "Error %d", code);
 229:         return ebuf;
 230:     } else
 231:         return sys_errlist[code];
 232: }
 233: 
 234: prefix(full, pref)
 235: register char *full, *pref;
 236: {
 237:     register char fc, pc;
 238: 
 239:     while ((pc = *pref++) != '\0') {
 240:         fc = *full++;
 241:         if (isupper(fc))
 242:             fc = tolower(fc);
 243:         if (isupper(pc))
 244:             pc = tolower(pc);
 245:         if (fc != pc)
 246:             return FALSE;
 247:     }
 248:     return TRUE;
 249: }
 250: 
 251: char *
 252: dirname(ngname)
 253: char *ngname;
 254: {
 255:     static char rbuf[BUFLEN];
 256:     register char *p;
 257: 
 258:     (void) sprintf(rbuf, "%s/%s", SPOOL, ngname);
 259: 
 260:     for (p=rbuf+strlen(SPOOL); *p; p++)
 261:         if (*p == '.')
 262:             *p = '/';
 263:     return rbuf;
 264: }
 265: 
 266: /*
 267:  * Return TRUE iff ngname is a valid newsgroup name
 268:  */
 269: validng(ngname)
 270: char *ngname;
 271: {
 272:     register FILE *fp;
 273:     register char *p, *q;
 274:     char abuf[BUFLEN];
 275: 
 276:     fp = xfopen(ACTIVE, "r");
 277:     while(fgets(abuf, BUFLEN, fp) != NULL) {
 278:         p = abuf;
 279:         q = ngname;
 280:         while (*p++ == *q++)
 281:             ;
 282:         if (*--q == '\0' && *--p == ' ') {
 283:             (void) fclose(fp);
 284:             return TRUE;
 285:         }
 286:     }
 287:     (void) fclose(fp);
 288:     return FALSE;
 289: }
 290: 
 291: /* VARARGS1 */
 292: xerror(message, arg1, arg2, arg3)
 293: char *message;
 294: int arg1, arg2, arg3;
 295: {
 296:     char buffer[128];
 297: 
 298:     fflush(stdout);
 299:     (void) sprintf(buffer, message, arg1, arg2, arg3);
 300:     logerr(buffer);
 301:     xxit(1);
 302: }
 303: 
 304: /* VARARGS1 */
 305: log(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
 306: char *fmt;
 307: {
 308:     _dolog(0, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 309: }
 310: 
 311: /* VARARGS1 */
 312: logerr(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
 313: char *fmt;
 314: {
 315:     _dolog(1, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 316: }
 317: 
 318: char *lfsuffix[] = {
 319:     "log",
 320:     "errlog",
 321:     0
 322: };
 323: 
 324: /*
 325:  * Log the given message, with printf strings and parameters allowed,
 326:  * on the log file, if it can be written.  The date and an attempt at
 327:  * figuring out the remote system name are also logged.
 328:  */
 329: /* VARARGS1 */
 330: _dolog(which, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
 331: char *fmt;
 332: {
 333:     FILE *logfile;
 334:     register char *p, *logtime;
 335:     int i;
 336:     char logfname[BUFLEN];      /* the log file */
 337:     char rmtsys[BUFLEN];
 338:     char msg[BUFLEN];
 339:     time_t t;
 340: 
 341:     (void) strcpy(rmtsys, header.path);
 342:     p = index(rmtsys, '!');
 343:     if (p == NULL)
 344:         p = index(rmtsys, ':');
 345:     if (p)
 346:         *p = 0;
 347:     else {
 348:         p = rindex(rmtsys, '@');
 349:         if (p)
 350:             (void) strcpy(rmtsys, p+1);
 351:         else
 352:             (void) strcpy(rmtsys, "local");
 353:     }
 354: 
 355:     (void) time(&t);
 356:     logtime = ctime(&t);
 357:     logtime[16] = 0;
 358:     logtime += 4;
 359: 
 360: 
 361:     (void) sprintf(msg, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
 362: 
 363:     if (which)
 364:         fprintf(stderr,"%s: %s\n", Progname, msg);
 365: 
 366:     for (i=0; i<=which;i++) {
 367:         (void) sprintf(logfname, "%s/%s", LIB, lfsuffix[i]);
 368: 
 369:         if (access(logfname, 0) == 0 && (logfile = fopen(logfname, "a")) != NULL) {
 370: #if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
 371:             int flags;
 372:             flags = fcntl(fileno(logfile), F_GETFL, 0);
 373:             (void) fcntl(fileno(logfile), F_SETFL, flags|O_APPEND);
 374: #else /* v7 */
 375:             (void) lseek(fileno(logfile), 0L, 2);
 376: #endif /* v7 */
 377:             if (i)
 378:                 fprintf(logfile, "%s\t%s\t%s: %s\n", logtime,
 379:                     header.ident[0] ? header.ident : username, Progname, msg);
 380:             else
 381:                 fprintf(logfile, "%s\t%s\t%s\n", logtime,
 382:                     rmtsys, msg);
 383:             (void) fclose(logfile);
 384:         }
 385:     }
 386: }
 387: #ifdef VMS
 388: 
 389: /*
 390:  * vmslink allows simulation of file linking under VMS.
 391:  */
 392: vmslink(infile,outfile)
 393: char *infile, *outfile;
 394: {
 395:     FILE *fp;
 396: 
 397:     if (access(outfile,0) == 0) {
 398:         errno = EEXIST;
 399:         return -1;
 400:     }
 401: 
 402:     fp = fopen(outfile, "w");
 403:     if (fp == NULL) {
 404:         errno = EACCES;
 405:         return -1;
 406:     }
 407: 
 408:     (void) fprintf(fp, "%s", infile);
 409:     (void) fclose(fp);
 410: 
 411:     return 0;
 412: }
 413: 
 414: /*
 415:  * vmsdelete deletes all revisions of a file.  It attempts to
 416:  * appear as unlink(2) under conventional Unix in other respects.
 417:  */
 418: vmsdelete(file)
 419: char *file;
 420: {
 421:     int i;
 422: 
 423:     i = unlink(file);
 424:     if (i != 0)
 425:         return i;
 426: 
 427:     i = errno;
 428:     while (unlink(file) == 0)
 429:         ;
 430:     errno = i;
 431: 
 432:     return 0;
 433: }
 434: 
 435: /*
 436:  * Convert a Unix file to a VMS fixed record format file by
 437:  * executing the 'unixtovms' command.
 438:  */
 439: unixtovms(file)
 440: char *file;
 441: {
 442:     char buf[BUFLEN];
 443:     sprintf(buf, "exec /etc/unixtovms %s", file);
 444:     return system(buf);
 445: }
 446: 
 447: /*
 448:  * Convert a VMS fixed record format file to a Unix file by
 449:  * executing the 'vmstounix' command.
 450:  */
 451: vmstounix(file)
 452: char *file;
 453: {
 454:     char buf[BUFLEN];
 455:     sprintf(buf,"exec /etc/vmstounix %s", file);
 456:     return system(buf);
 457: }
 458: #endif /* VMS */
 459: 
 460: #if !defined(BSD4_2) && !defined(BSD4_1C)
 461: /*
 462:  * make a directory. Also make sure that the directory is owned
 463:  * by the right userid
 464:  */
 465: mkdir(path, perm)
 466: char *path;
 467: int perm;
 468: {
 469:     int pid, status;
 470: 
 471:     if (pid=fork()) {
 472:         status = fwait(pid);
 473: #if defined(USG) && !defined(CHEAP)
 474:         if (pid=fork())
 475:             (void) fwait(pid);
 476:         else {
 477:             setgid(gid);
 478:             setuid(uid);
 479:             if (chown(path, duid, dgid) == 0)
 480:                 (void) chmod(path, perm&(~N_UMASK));
 481:             _exit(0);
 482:         }
 483: #endif /* USG && !CHEAP */
 484:     } else {
 485:         (void) setgid(dgid);
 486:         if (setuid(duid) < 0)
 487:             (void) umask(0);
 488:         else
 489:             (void) umask(perm&N_UMASK);
 490:         (void) execlp("mkdir", "mkdir", path, (char *)NULL);
 491:         perror(path);
 492:         _exit(1);
 493:     }
 494:     return status;
 495: }
 496: #endif /* !BSD4_2 && ! BSD4_1C */
 497: #ifndef USG
 498: char *
 499: strpbrk(str, chars)
 500: register char *str, *chars;
 501: {
 502:     register char *cp;
 503: 
 504:     do {
 505:         cp = chars - 1;
 506:         while (*++cp) {
 507:             if (*str == *cp)
 508:                 return str;
 509:         }
 510:     } while (*str++);
 511:     return NULL;
 512: }
 513: #endif /* !USG */
 514: 
 515: #ifdef FASCIST
 516: /*
 517:  *  This routine checks to see if the posting user is allowed to
 518:  *  post to the given newsgroup.  If the username is not in the file
 519:  *  $LIBDIR/authorized then the default in the symbol FASCIST is used.
 520:  *
 521:  *  Format of the call:
 522:  *     fascist(user, newgroups)
 523:  *
 524:  *  Returns:
 525:  *     FALSE, if authorized
 526:  *     TRUE, if not
 527:  *
 528:  *  Format of the file "authorized" is:
 529:  *    user:allowed groups
 530:  *
 531:  *  Example:
 532:  *    root:net.all,mod.all
 533:  *    naughty_person:junk,net.politics
 534:  *    operator:!net.all,general,test,mod.unix
 535:  *
 536:  *  An open environment could have FASCIST set to "all"
 537:  *  and then individual entries could be made in the authorized file
 538:  *  to prevent certain individuals from posting to such a wide
 539:  *  area.
 540:  *
 541:  *  Note that a distribution of "all" does NOT mean to allow postings
 542:  *  only to local groups -- "all" includes "all.all".
 543:  *  Use "all,!all.all" to get this behavior
 544:  *
 545:  *	Eugene Spafford		spaf@gatech	May 22, 1985
 546:  */
 547: 
 548: fascist(user, newsgroups)
 549: register char *user, *newsgroups;
 550: {
 551:     FILE *facfd;
 552:     char facuser[BUFLEN], facgroups[BUFLEN], factemp[BUFLEN];
 553:     register char  *facptr;
 554: 
 555:     /* First, open the necessary file...$LIBDIR/authorized and see if there
 556: 	 * is an entry for this user
 557: 	 */
 558: 
 559:     (void) strncpy(facgroups, FASCIST, BUFLEN);
 560:     sprintf(factemp, "%s/%s", LIBDIR, "authorized");
 561:     facfd = fopen(factemp, "r");
 562: 
 563:     if (facfd != NULL) { /* If no such file, we go with the global default */
 564:         while (fscanf(facfd, "%[^:]:%s\n", facuser, factemp) != EOF)
 565:             if (strncmp(facuser, user, BUFLEN) == 0) {
 566:                 (void) strcat(facgroups, ",");
 567:                 (void) strcat(facgroups, factemp);
 568:                 break;
 569:             }
 570:         fclose (facfd);
 571:     }
 572: #ifdef DEBUG
 573:     fprintf(stderr, "facgroups = %s\n", facgroups);
 574:     fprintf(stderr, "newsgroups = %s\n", newsgroups);
 575: #endif DEBUG
 576: 
 577:     /* We step through the newsgroups being posted to and check each against
 578: 	 * the restriction list.  *ALL* posted groups must match the restriction
 579: 	 * list or we don't allow the posting.
 580: 	 */
 581: 
 582:     while (*newsgroups != '\0') {
 583:         facptr = factemp;
 584:         while (*newsgroups != '\0' && *newsgroups != NGDELIM)
 585:             *facptr++ = *newsgroups++;
 586:         *facptr = '\0';
 587:         if (*newsgroups == NGDELIM)
 588:             newsgroups++;
 589: 
 590: #ifdef DEBUG
 591:         fprintf(stderr, "Checking newsgroup '%s'\n", factemp);
 592: #endif
 593: 
 594:         if (ngmatch(factemp, facgroups) == FALSE)
 595:             return TRUE;
 596:     }
 597: 
 598:     /* must be okay -- return */
 599: #ifdef DEBUG
 600:     fprintf (stderr, "Newsgroups approved for this poster.\n");
 601: #endif DEBUG
 602:     return FALSE;
 603: }
 604: #endif FASCIST

Defined functions

_dolog defined in line 330; used 2 times
errmsg defined in line 219; used 6 times
fascist defined in line 548; used 2 times
ptrncmp defined in line 71; used 4 times
unixtovms defined in line 439; used 1 times
ushell defined in line 93; used 1 times
vmslink defined in line 392; used 2 times
vmstounix defined in line 451; used 1 times
xshell defined in line 112; used 1 times
  • in line 99

Defined variables

SccsId defined in line 19; never used
environ declared in line 109; defined in line 107; used 5 times
lfsuffix defined in line 318; used 1 times
Last modified: 1986-01-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1726
Valid CSS Valid XHTML 1.0 Strict