# 2.11BSD#431 - /usr/src/new/nntp/server/misc.c

##### Functions

    bcmp              X
    bcopy             X
    bzero             X
    check_ngperm      X
    close_crnt        X
    dup2              X
    findart           X
    findhfdigit       X
    get_distlist      X
    get_id            X
    gethistent        X
    histfile          X
    lower             X
    open_valid_art    X
    openartbyid       X
    spew              X

##### Macros

    USGHIST           X

       1: #ifndef lint
       2: static char *sccsid = "@(#)misc.c	1.25	(Berkeley) 2/6/88";
       3: #endif
       4:
       5: #include "../common/conf.h"
       6:
       7: #include "common.h"
       8:
       9: /*
      10:  * open_valid_art -- determine if a given article name is valid;
      11:  *		if it is, return a file pointer to the open article,
      12:  *		along with a unique id of the article.
      13:  *
      14:  *	Parameters:	"artname" is a string containing the
      15:  *			name of the article.
      16:  *			"id" is space for us to put the article
      17:  *			id in.
      18:  *
      19:  *	Returns:	File pointer to the open article if the
      20:  *			article is valid; NULL otherwise
      21:  *
      22:  *	Side effects:	None.
      23:  */
      24:
      25: FILE *
      26: open_valid_art(artname, id)
      27:     char        *artname;
      28:     char        *id;
      29: {
      30:     static int  crnt_art_num;
      31:     static char crnt_art_id[MAXBUFLEN];
      32:     int     fd;
      33:     struct stat statbuf;
      34:
      35:     if (art_fp != NULL) {
      36:         if (crnt_art_num == atoi(artname)) {
      37:             if (fseek(art_fp, (long) 0, 0) < 0)
      38:                 close_crnt();
      39:             else {
      40:                 (void) strcpy(id, crnt_art_id);
      41:                 return (art_fp);
      42:             }
      43:         } else
      44:             close_crnt();
      45:     }
      46:
      47:     art_fp = fopen(artname, "r");
      48:
      49:     if (art_fp == NULL)
      50:         return (NULL);
      51:
      52:     fd = fileno(art_fp);
      53:
      54:     if (fstat(fd, &statbuf) < 0) {
      55:         close_crnt();
      56:         return (NULL);
      57:     }
      58:
      59:     if ((statbuf.st_mode & S_IFREG) != S_IFREG) {
      60:         close_crnt();
      61:         return (NULL);
      62:     }
      63:
      64:     get_id(art_fp, id);
      65:     (void) strcpy(crnt_art_id, id);
      66:     crnt_art_num = atoi(artname);
      67:     return (art_fp);
      68: }
      69:
      70:
      71: /*
      72:  * gethistent -- return the path name of an article if it's
      73:  * in the history file.
      74:  *
      75:  *	Parameters:	"msg_id" is the message ID of the
      76:  *			article, enclosed in <>'s.
      77:  *
      78:  *	Returns:	A char pointer to a static data area
      79:  *			containing the full pathname of the
      80:  *			article, or NULL if the message-id is not
      81:  *			in thef history file.
      82:  *
      83:  *	Side effects:	opens dbm database
      84:  *			(only once, keeps it open after that).
      85:  *			Converts "msg_id" to lower case.
      86:  */
      87:
      88: #ifndef NDBM
      89: # ifndef DBM
      90: #  ifndef USGHIST
      91: #   define USGHIST
      92: #  endif not USGHIST
      93: # endif not DBM
      94: #endif not DBM
      95:
      96: char *
      97: gethistent(msg_id)
      98:     char        *msg_id;
      99: {
     100:     char        line[MAXBUFLEN];
     101:     char        *tmp;
     102:     register char   *cp;
     103:     long        ltmp;
     104:     static char path[MAXPATHLEN];
     105: #ifdef USGHIST
     106:     char        *histfile();
     107:     register int    len;
     108: #else not USGHIST
     109: #ifdef DBM
     110:     static int  dbopen = 0;
     111:     datum       fetch();
     112: #else not DBM
     113:     static DBM  *db = NULL; /* History file, dbm version */
     114: #endif DBM
     115:     datum        key, content;
     116: #endif USGHIST
     117:     static FILE *hfp = NULL;    /* history file, text version */
     118:
     119:     for (cp = msg_id; *cp != '\0'; ++cp)
     120:         if (isupper(*cp))
     121:             *cp = tolower(*cp);
     122:
     123: #ifdef USGHIST
     124:     hfp = fopen(histfile(msg_id), "r");
     125:     if (hfp == NULL) {
     126: #ifdef SYSLOG
     127:         syslog(LOG_ERR, "gethistent: histfile: %m");
     128: #endif SYSLOG
     129:         return (NULL);
     130:     }
     131:
     132:     len = strlen(msg_id);
     133:     while (fgets(line, sizeof (line), hfp))
     134:         if (!strncasecmp(msg_id, line, len))
     135:             break;
     136:
     137:     if (feof(hfp)) {
     138:         (void) fclose(hfp);
     139:         return (NULL);
     140:     }
     141: #else not USGHIST
     142: #ifdef DBM
     143:     if (!dbopen) {
     144:         if (dbminit(historyfile) < 0) {
     145: #ifdef SYSLOG
     146:             syslog(LOG_ERR, "openartbyid: dbminit %s: %m",
     147:                 historyfile);
     148: #endif SYSLOG
     149:             return (NULL);
     150:         } else
     151:             dbopen = 1;
     152:     }
     153: #else   /* ndbm */
     154:     if (db == NULL) {
     155:         db = dbm_open(historyfile, O_RDONLY, 0);
     156:         if (db == NULL) {
     157: #ifdef SYSLOG
     158:             syslog(LOG_ERR, "openartbyid: dbm_open %s: %m",
     159:                 historyfile);
     160: #endif SYSLOG
     161:             return (NULL);
     162:         }
     163:     }
     164: #endif DBM
     165:
     166:     key.dptr = msg_id;
     167:     key.dsize = strlen(msg_id) + 1;
     168:
     169: #ifdef DBM
     170:     content = fetch(key);
     171: #else   /* ndbm */
     172:     content = dbm_fetch(db, key);
     173: #endif DBM
     174:     if (content.dptr == NULL)
     175:         return (NULL);
     176:
     177:     if (hfp == NULL) {
     178:         hfp = fopen(historyfile, "r");
     179:         if (hfp == NULL) {
     180: #ifdef SYSLOG
     181:             syslog(LOG_ERR, "message: fopen %s: %m",
     182:                 historyfile);
     183: #endif SYSLOG
     184:             return (NULL);
     185:         }
     186:     }
     187:
     188:     bcopy(content.dptr, (char *)&ltmp, sizeof (long));
     189:     if (fseek(hfp, ltmp, 0) < 0) {
     190: #ifdef SYSLOG
     191:         syslog(LOG_ERR, "message: fseek: %m");
     192: #endif SYSLOG
     193:         return (NULL);
     194:     }
     195:
     196:     (void) fgets(line, sizeof(line), hfp);
     197: #endif USGHIST
     198:
     199:     if ((cp = index(line, '\n')) != NULL)
     200:         *cp = '\0';
     201:     cp = index(line, '\t');
     202:     if (cp != NULL)
     203:         cp = index(cp+1, '\t');
     204:     if (cp == NULL) {
     205: #ifdef SYSLOG
     206:         syslog(LOG_ERR,
     207:         "message: malformed line in history file at %ld bytes, id %s",
     208:             ltmp, msg_id);
     209: #endif SYSLOG
     210:         return (NULL);
     211:     }
     212:     tmp = cp+1;
     213:
     214:     if ((cp = index(tmp, ' ')) != NULL)
     215:         *cp = '\0';
     216:
     217:     while ((cp = index(tmp, '.')) != NULL)
     218:         *cp = '/';
     219:
     220:     (void) strcpy(path, spooldir);
     221:     (void) strcat(path, "/");
     222:     (void) strcat(path, tmp);
     223:
     224:     return (path);
     225: }
     226:
     227: /*
     228:  * openartbyid -- open an article by message-id.
     229:  *
     230:  *	Arguments:	"msg_id" is the message-id of the article
     231:  *			to open.
     232:  *
     233:  *	Returns:	File pointer to opened article, or NULL if
     234:  *			the article was not in the history file or
     235:  *			could not be opened.
     236:  *
     237:  *	Side effects:	Opens article.
     238:  */
     239:
     240: FILE *
     241: openartbyid(msg_id)
     242:     char    *msg_id;
     243: {
     244:     char    *path;
     245:
     246:     path = gethistent(msg_id);
     247:     if (path != NULL)
     248:         return (fopen(path, "r"));
     249:     else
     250:         return (NULL);
     251: }
     252:
     253:
     254: /*
     255:  * check_ngperm -- check to see if they're allowed to see this
     256:  * article by matching Newsgroups: and Distribution: line.
     257:  *
     258:  *	Parameters:	"fp" is the file pointer of this article.
     259:  *
     260:  *	Returns:	0 if they're not allowed to see it.
     261:  *			1 if they are.
     262:  *
     263:  *	Side effects:	None.
     264:  */
     265:
     266: check_ngperm(fp)
     267:     register FILE   *fp;
     268: {
     269:     char        buf[MAXBUFLEN];
     270:     register char   *cp;
     271:     static char **ngarray;
     272:     int     ngcount;
     273:
     274:     if (ngpermcount == 0)
     275:         return (1);
     276:
     277:     while (fgets(buf, sizeof (buf), fp) != NULL) {
     278:         if (buf[0] == '\n')     /* End of header */
     279:             break;
     280:         if (buf[0] != 'N' && buf[0] != 'n')
     281:             continue;
     282:         cp = index(buf, '\n');
     283:         if (cp)
     284:             *cp = '\0';
     285:         cp = index(buf, ':');
     286:         if (cp == NULL)
     287:             continue;
     288:         *cp = '\0';
     289:         if (!strcasecmp(buf, "newsgroups")) {
     290:             ngcount = get_nglist(&ngarray, cp+2);
     291:             break;
     292:         }
     293:     }
     294:
     295:     (void) rewind(fp);
     296:
     297:     if (ngcount == 0)   /* Either no newgroups or null entry */
     298:         return (1);
     299:
     300:     return (ngmatch(s1strneql, ALLBUT,
     301:         ngpermlist, ngpermcount, ngarray, ngcount));
     302: }
     303:
     304:
     305: /*
     306:  * spew -- spew out the contents of a file to stdout, doing
     307:  * the necessary cr-lf additions at the end.  Finish with
     308:  * a "." on a line by itself, and an fflush(stdout).
     309:  *
     310:  *	Parameters:	"how" tells what part of the file we
     311:  *			want spewed:
     312:  *				ARTICLE   The entire thing.
     313:  *				HEAD	  Just the first part.
     314:  *				BODY	  Just the second part.
     315:  *			"fp" is the open file to spew from.
     316:  *
     317:  *	Returns:	Nothing.
     318:  *
     319:  *	Side effects:	Changes current position in file.
     320:  */
     321:
     322: spew(fp, how)
     323:     FILE        *fp;
     324:     int     how;
     325: {
     326:     char        line[NNTP_STRLEN];
     327:     register char   *cp;
     328:
     329: #ifdef LOG
     330:     ++arts_acsd;
     331: #endif
     332:
     333:     if (how == STAT) {
     334:         (void) fflush(stdout);
     335:         return;
     336:     }
     337:
     338:     while (fgets(line, sizeof(line)-6, fp) != NULL && *line != '\n') {
     339:         if (how == BODY)    /* We need to skip this anyway */
     340:             continue;
     341:         cp = index(line, '\n');
     342:         if (cp != NULL)
     343:             *cp = '\0';
     344:         if (*line == '.')
     345:             putchar('.');
     346:         putline(line);
     347:         if (cp == NULL) {
     348:             for (;;) {
     349:                 if ((fgets(line, sizeof(line)-6, fp) == NULL)
     350:                     || (index(line, '\n') != NULL))
     351:                     break;
     352:             }
     353:         }
     354:     }
     355:
     356:     if (how == HEAD) {
     357:         putchar('.');
     358:         putchar('\r');
     359:         putchar('\n');
     360:         (void) fflush(stdout);
     361:         return;
     362:     } else if (how == ARTICLE) {
     363:         putchar('\r');
     364:         putchar('\n');
     365:     }
     366:
     367:     while (fgets(line, sizeof(line)-6, fp) != NULL) {
     368:         cp = index(line, '\n');
     369:         if (cp != NULL)
     370:             *cp = '\0';
     371:         if (*line == '.')
     372:             putchar('.');
     373:         putline(line);
     374:
     375:         if (cp == NULL) {
     376:             for (;;) {
     377:                 if ((fgets(line, sizeof(line)-6, fp) == NULL)
     378:                     || (index(line, '\n') != NULL))
     379:                     break;
     380:             }
     381:         }
     382:     }
     383:     putchar('.');
     384:     putchar('\r');
     385:     putchar('\n');
     386:     (void) fflush(stdout);
     387: }
     388:
     389:
     390: /*
     391:  * get_id -- get the message id of the current article.
     392:  *
     393:  *	Parameters:	"art_fp" is a pointer to the open file.
     394:  *			"id" is space for the message ID.
     395:  *
     396:  *	Returns:	Nothing.
     397:  *
     398:  *	Side effects:	Seeks and rewinds on "art_fp".
     399:  *			Changes space pointed to by "id".
     400:  */
     401:
     402: get_id(art_fp, id)
     403:     register FILE   *art_fp;
     404:     char        *id;
     405: {
     406:     char        line[MAXBUFLEN];
     407:     register char   *cp;
     408:
     409:     while (fgets(line, sizeof(line), art_fp) != NULL) {
     410:         if (*line == '\n')
     411:             break;
     412:         if (*line == 'M' || *line == 'm') { /* "Message-ID" */
     413:             if ((cp = index(line, ' ')) != NULL) {
     414:                 *cp = '\0';
     415:                 if (!strcasecmp(line, "Message-ID:")) {
     416:                     (void) strcpy(id, cp + 1);
     417:                     if ((cp = index(id, '\n')) != NULL)
     418:                         *cp = '\0';
     419:                     (void) rewind(art_fp);
     420:                     return;
     421:                 }
     422:             }
     423:         }
     424:     }
     425:     (void) rewind(art_fp);
     426:     (void) strcpy(id, "<0>");
     427: }
     428:
     429:
     430: /*
     431:  * close_crnt -- close the current article file pointer, if it's
     432:  *	open.
     433:  *
     434:  *	Parameters:	None.
     435:  *
     436:  *	Returns:	Nothing.
     437:  *
     438:  *	Side effects:	Closes "art_fp" if it's open; sets "art_fp" to NULL.
     439:  */
     440:
     441: close_crnt()
     442: {
     443:     if (art_fp != NULL)
     444:         (void) fclose(art_fp);
     445:     art_fp = NULL;
     446: }
     447:
     448:
     449: /*
     450:  * findart -- find an article number in the article array.
     451:  *
     452:  *	Parameters:	"artname" is a string containing
     453:  *			the name of the article.
     454:  *
     455:  *	Returns:	An index into "art_array",
     456:  *			or -1 if "artname" isn't in "art_array".
     457:  *
     458:  *	Side effects:	None.
     459:  *
     460:  *	Improvement:	Replace this linear search with a binary one.
     461:  */
     462:
     463: findart(artname)
     464:     char        *artname;
     465: {
     466:     register int    i, artnum;
     467:
     468:     artnum = atoi(artname);
     469:
     470:     for (i = 0; i < num_arts; ++i)
     471:         if (art_array[i] == artnum)
     472:             return(i);
     473:
     474:     return (-1);
     475: }
     476:
     477:
     478: /*
     479:  * get_distlist -- return a nicely set up array of distribution groups
     480:  * along with a count, when given an NNTP-spec distribution list
     481:  * in the form <dist1,dist2,...,distn>.
     482:  *
     483:  *	Parameters:		"array" is storage for our array,
     484:  *				set to point at some static data.
     485:  *				"list" is the NNTP distribution list.
     486:  *
     487:  *	Returns:		Number of distributions found.
     488:  *				-1 on error.
     489:  *
     490:  *	Side effects:		Changes static data area.
     491:  */
     492:
     493: get_distlist(array, list)
     494:     char        ***array;
     495:     char        *list;
     496: {
     497:     char        *cp;
     498:     int     distcount;
     499:     static char **dist_list = (char **) NULL;
     500:
     501:     if (list[0] != '<')
     502:         return (-1);
     503:
     504:     cp = index(list + 1, '>');
     505:     if (cp != NULL)
     506:         *cp = '\0';
     507:     else
     508:         return (-1);
     509:
     510:     for (cp = list + 1; *cp != '\0'; ++cp)
     511:         if (*cp == ',')
     512:             *cp = ' ';
     513:     distcount = parsit(list + 1, &dist_list);
     514:     *array = dist_list;
     515:     return (distcount);
     516: }
     517:
     518:
     519: /*
     520:  * lower -- convert a character to lower case, if it's upper case.
     521:  *
     522:  *	Parameters:	"c" is the character to be
     523:  *			converted.
     524:  *
     525:  *	Returns:	"c" if the character is not
     526:  *			upper case, otherwise the lower
     527:  *			case eqivalent of "c".
     528:  *
     529:  *	Side effects:	None.
     530:  */
     531:
     532: char
     533: lower(c)
     534:     register char   c;
     535: {
     536:     if (isascii(c) && isupper(c))
     537:         c = c - 'A' + 'a';
     538:     return (c);
     539: }
     540:
     541:
     542: /* the following is from news 2.11 */
     543:
     544: #ifdef USG
     545: /*
     546: ** Generate the appropriate history subfile name
     547: */
     548: char *
     549: histfile(hline)
     550: char *hline;
     551: {
     552:     char chr;   /* least significant digit of article number */
     553:     static char subfile[BUFSIZ];
     554:
     555:     chr = findhfdigit(hline);
     556:     sprintf(subfile, "%s.d/%c", HISTORY_FILE, chr);
     557:     return subfile;
     558: }
     559:
     560: findhfdigit(fn)
     561: char *fn;
     562: {
     563:     register char *p;
     564:     register int chr;
     565:
     566:     p = index(fn, '@');
     567:     if (p != NULL && p > fn)
     568:         chr = *(p - 1);
     569:     else
     570:         chr = '0';
     571:     if (!isdigit(chr))
     572:         chr = '0';
     573:     return chr;
     574: }
     575: bcopy(s, d, l)
     576:     register char *s, *d;
     577:     register int l;
     578: {
     579:     while (l-- > 0)
     580:         *d++ = *s++;
     581: }
     582:
     583: bcmp(s1, s2, l)
     584:     register char *s1, *s2;
     585:     register int l;
     586: {
     587:     if (l == 0)
     588:         return (0);
     589:
     590:     do
     591:         if (*s1++ != *s2++)
     592:             break;
     593:     while (--l);
     594:
     595:     return (l);
     596: }
     597:
     598: bzero(p, l)
     599:     register char *p;
     600:     register int l;
     601: {
     602:     while (l-- > 0)
     603:         *p++ = 0;
     604: }
     605:
     606: dup2(x,y)
     607: int x,y;
     608: {
     609:     close(y);
     610:     return(fcntl(x, F_DUPFD,y ));
     611: }
     612: #endif USG

#### Defined functions

bcmp defined in line 583; never used
bcopy defined in line 575; used 3 times

- in line 188
- in /usr/src/new/nntp/server/access.c line 101
- in /usr/src/new/nntp/server/main.c line 106

bzero defined in line 598; used 1 times

- in /usr/src/new/nntp/server/netaux.c line 113

check_ngperm defined in line 266; used 1 times

- in /usr/src/new/nntp/server/ahbs.c line 52

close_crnt defined in line 441; used 5 times

- in line 38, 44, 55-60(2)
- in /usr/src/new/nntp/server/group.c line 64

dup2 defined in line 606; used 11 times

- in /usr/src/new/nntp/server/netaux.c line 60-61(2), 74-78(3), 166-170(3)
- in /usr/src/new/nntp/server/spawn.c line 154-157(2), 164

findart defined in line 463; used 2 times

- in /usr/src/new/nntp/server/ahbs.c line 127
- in /usr/src/new/nntp/server/nextlast.c line 85

findhfdigit defined in line 560; used 1 times

- in line 555

get_distlist defined in line 493; used 2 times

- in /usr/src/new/nntp/server/newgroups.c line 74
- in /usr/src/new/nntp/server/newnews.c line 118

get_id defined in line 402; used 1 times

- in line 64

gethistent defined in line 96; used 3 times

- in line 246
- in /usr/src/new/nntp/server/common.h line 101
- in /usr/src/new/nntp/server/ihave.c line 33

histfile defined in line 548; used 2 times

- in line 106, 124

lower defined in line 532; never used
open_valid_art defined in line 25; used 3 times

- in /usr/src/new/nntp/server/ahbs.c line 104
- in /usr/src/new/nntp/server/common.h line 99
- in /usr/src/new/nntp/server/nextlast.c line 70

openartbyid defined in line 240; used 3 times

- in /usr/src/new/nntp/server/ahbs.c line 45
- in /usr/src/new/nntp/server/common.h line 100
- in /usr/src/new/nntp/server/xhdr.c line 57

spew defined in line 322; used 2 times

- in /usr/src/new/nntp/server/ahbs.c line 61, 124

#### Defined variables

sccsid defined in line 2; never used

#### Defined macros

USGHIST defined in line 91; used 5 times

- in line 90, 105-108(2), 123, 141

Last modified: 1988-02-07 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1963 |