home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / x25 / nrs.shar.Z / nrs.shar / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-27  |  9.8 KB  |  485 lines

  1. # include    "nrs.h"
  2.  
  3. # ifndef lint
  4. static char RCSid[]="@(#)$Header: misc.c,v 3.6 88/09/08 17:39:18 pb Exp $";
  5. # endif
  6.  
  7. /***********************************************************************\
  8. *                                     *
  9. * The various miscellaneous routines that one finds in almost        *
  10. * any program, but there are probably too many!                *
  11. *                                     *
  12. * Copyright 1986, Piete Brooks, Julian Onions & Adrian Pell        *
  13. * pb@cl.cam.ac.uk, jpo@hcig.nott.ac.uk, Adrian.R.Pell@reading.ac.uk    *
  14. *                                    *
  15. * This program may be copied as long as you don't remove this notice,    *
  16. * try to make any money off of it, or pretend that you wrote it.    *
  17. *                                     *
  18. \***********************************************************************/
  19.  
  20. extern errno;
  21.  
  22. static_f void pmesg_3();
  23. static_f void getversion();
  24. static_f void verprint();
  25.  
  26. /* VARARGS 1 */
  27. void fatal_2(fmt, a1,a2)    /* a fatal error */
  28. char    *fmt;
  29. universaldec(a1)
  30. universaldec(a2)
  31. {
  32.     pmesg_3(fmt,a1,a2,universaluse(0));
  33.     exit(exit_rc(1));
  34. }
  35.  
  36. /* VARARGS 1 */
  37. void warn_3(level, fmt, a1, a2, a3)    /* a warning message */
  38. char    *fmt;
  39. universaldec(a1)
  40. universaldec(a2)
  41. universaldec(a3)
  42. {
  43.     char    buffer[128];
  44.  
  45.     warns += level;
  46.  
  47.     if (warns <= level*5 || warns > max_warns)
  48.     {    VOID sprintf( buffer, "warning - %s", fmt);
  49.         pmesg_3(buffer, a1, a2, a3);
  50.     }
  51.  
  52.     if (warns > max_warns)
  53.     {
  54.         pmesg_3("Too many warnings (%d > %d), aborting",
  55.             warns, max_warns, 0);
  56.         pmesg_3("Fix the problem, or try running with \"level %d\"",
  57.             warns*2, 0, 0);
  58.         exit(exit_rc(1));
  59.     }
  60. }
  61.  
  62. /* VARARGS 1 */
  63. static_f void pmesg_3(fmt, a1,a2,a3)    /* print a message */
  64. char    *fmt;
  65. universaldec(a1)
  66. universaldec(a2)
  67. universaldec(a3)
  68. {
  69.     extern    noshare int errno;
  70. #ifndef PRIME
  71.     extern    noshare int sys_nerr;
  72.     extern  noshare char *sys_errlist[];
  73. #endif    PRIME
  74.  
  75.     fprintf( stderr, "%s : ", invo_name);
  76.     fprintf( stderr, fmt, a1, a2, a3);
  77. #ifdef PRIME
  78.     if (errno > 0)
  79.     {    putc(' ', stderr);
  80.         perror("");
  81.     }
  82.     else    putc('\n', stderr);
  83. #else PRIME
  84.     if( errno > 0 && errno < sys_nerr)
  85.         fprintf(stderr, " [%s]", sys_errlist[errno]);
  86.     putc('\n', stderr);
  87. #endif
  88.     errno = 0;
  89. }
  90.  
  91. /* VARARGS 1 */
  92. void vprintf_3(level, fmt, a1,a2,a3)    /* a warning message */
  93. int    level;
  94. char    *fmt;
  95. universaldec(a1)
  96. universaldec(a2)
  97. universaldec(a3)
  98. {
  99.     if( level > verbose )
  100.         return;
  101.     fprintf( stderr, fmt, a1, a2, a3);
  102. }
  103.  
  104. int getint(fp, n)    /* get an int from a field on n */
  105. register FILE    *fp;
  106. register int    n;
  107. {
  108.     register int    value = 0, c;
  109.  
  110.     while(( c = getc(fp)) == '\n' || c == '\r')
  111.         ;
  112.     while(n -- > 0)
  113.     {
  114.         if( isdigit(c) )
  115.             value = value * 10 + (c - '0');
  116.         else if (c == '\n')
  117.         {    VOID ungetc(c, fp);
  118.             break;    
  119.         }
  120.         if( n > 0)
  121.             c = getc(fp);
  122.     }
  123.     return value;
  124. }
  125.  
  126. /* get a string of len chars, skipping skip chars first */
  127. void getstr(fp, cp, skip, len)
  128. register FILE    *fp;
  129. register char    *cp;
  130. int    skip;
  131. int    len;
  132. {
  133.     char *base=cp;
  134.     int    c;
  135.  
  136.     while((c = getc(fp)) == '\n' || c == '\r')
  137.         ;
  138.     VOID ungetc(c, fp);
  139.     while( skip -- > 0)
  140.         c = getc(fp);
  141.     for(; len -- > 0; cp++)
  142.     {    *cp = getc(fp);
  143.         if (*cp == '\n')
  144.         {    ungetc(*cp, stdin);
  145.             *cp = '\0';
  146.             errno = 0;    /* no perror() ... */
  147.             warn2(1,
  148.     "Inconsistant database -- string '%s' too short by %d characters",
  149.             base, len+1);
  150.             break;
  151.         }
  152.     }
  153.     *cp = '\0';
  154. }
  155.  
  156. void freeoff( ap )    /* throw away an atomic record */
  157. register Atomic    *ap;
  158. {
  159.     int    i;
  160.     char    **p;
  161.  
  162.     if( ap->dte )
  163.     {
  164.         if (ap->dte != nullstring) free(ap->dte);
  165.         ap->dte = (char *) 0;
  166.     }
  167.     if( ap->ybts)
  168.     {
  169.         if (ap->ybts != nullstring) free(ap->ybts);
  170.         ap->ybts = (char *) 0;
  171.     }
  172.     for( i = 0, p = ap->ar; i < ap->n_relays; i++, p++)
  173.     {
  174.         if (*p != nullstring) free(*p);
  175.         *p = (char *) 0;
  176.     }
  177.     ap->n_relays = 0;
  178.     for( i = 0, p = ap->desc; i < ap->n_descs; i++, p++)
  179.     {
  180.         if (*p != nullstring) free(*p);
  181.         *p = (char *) 0;
  182.     }
  183.     ap->n_descs = 0;
  184. }
  185.  
  186. #ifndef    gettab
  187. Table    *gettab(n)    /* find a table given a file number */
  188. register int    n;
  189. {
  190.     register Table    *tp;
  191.  
  192.     if (n > fnumb)
  193.     {    vprintf2(4, "gettab passed %d (%d)\n", n, fnumb);    
  194.         n += 2 - fnumb;
  195.     }
  196.     if (n < MAX_FNUMB)    return fnumb2trip[n].f_tp;
  197.  
  198.     for( tp = tablist; tp->T_name != NULL; tp++)
  199.     {
  200.         if( tp->hdr.fnumber == n)
  201.             return tp;
  202.     }
  203.     return (Table *)0;
  204. }
  205. #endif    gettab
  206.  
  207. char    *strdup(s)    /* malloc a string */
  208. char    *s;
  209. {
  210.     int    len = strlen(s);
  211.     char    *p;
  212.  
  213.     if( (p = malloc((unsigned) (len + 1))) == NULL)
  214.         fatal0("Out of core/moss/memory");
  215.     return    strcpy(p,s);
  216. }
  217.  
  218. static char    chartab[] = {    /* table for case independant comparisons */
  219.     '\0', '\1', '\2', '\3', '\4', '\5', '\6', '\7',
  220.     '\10', '\t', '\n', '\13', '\14', '\r', '\16', '\17',
  221.     '\20', '\21', '\22', '\23', '\24', '\25', '\26', '\27',
  222.     '\30', '\31', '\32', '\33', '\34', '\35', '\36', '\37',
  223.     ' ', '!', '"', '#', '$', '%', '&', '\47',
  224.     '(', ')', '*', '+', ',', '-', '.', '/',
  225.     '0', '1', '2', '3', '4', '5', '6', '7',
  226.     '8', '9', ':', ';', '<', '=', '>', '?',
  227.     '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  228.     'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  229.     'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  230.     'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
  231.     '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  232.     'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  233.     'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  234.     'X', 'Y', 'Z', '{', '|', '}', '~', '\177',
  235. };
  236.  
  237. int lexequ(s1,s2,n)    /* = strncmp + case insensitive */
  238. register char    *s1, *s2;
  239. register int    n;
  240. {
  241.     while( chartab[(*s1++) & 0177]  == chartab[(*s2++) & 0177] && --n > 0)
  242.         ;
  243.     return n == 0;
  244. }
  245.  
  246.  
  247. char    *vlookup(val, table) /* lookup up int a give corresponding str */
  248. register int    val;
  249. register Lookup    *table;
  250. {
  251.     while( table->str != 0)
  252.     {
  253.         if( table->value == val)
  254.             return table->str;
  255.         table++;
  256.     }
  257.     return (char *)0;
  258. }
  259.  
  260. int slookup(str, table) /* lookup string in table */
  261. register char    *str;
  262. register Lookup    *table;
  263. {
  264.     register int    len1;
  265.     register int    len2;
  266.  
  267.     if (str == 0)
  268.         return -1;
  269.     else
  270.         len1 = strlen(str);
  271.     while( table->str != 0)
  272.     {
  273.         len2 = strlen(table->str);
  274.         if( lexequ(str, table->str, max(len1,len2) ) )
  275.             return table->value;
  276.         table++;
  277.     }
  278.     return    -1;
  279. }
  280.  
  281. char    *lowerfy(s)    /* tr A-Z a-z */
  282. register char    *s;
  283. {
  284.     register char    *p = s;
  285.  
  286.     while(*p)
  287.     {
  288.         if( isupper(*p) )
  289.             *p = tolower(*p);
  290.         p++;
  291.     }
  292.     return s;
  293. }
  294.  
  295. char    *getfpath(str)    /* get full pathname + allocate storage */
  296. char    *str;
  297. {
  298.     char    pathname[256];
  299. /* We may be supplied with an absolute pathname, or a name relative to
  300.  * the tailor variable directory (null -> don't prefix!).
  301.  * Decide whether & how to prefix (suffix ?) str with pathname.
  302.  */
  303.  
  304. #ifdef    VMS21
  305.     /* dev:     -> full pathname    LEAVE ALONE
  306.      * [name]   -> full pathname    LEAVE ALONE
  307.      * sym$name -> symbolic name    LEAVE ALONE
  308.      * <else>   -> normal        PREFIX with directory
  309.      */
  310.     if (directory == NULL ||
  311.         index(str, ':') || index(str, '[') || index(str, '$'))
  312.         return strdup(str);
  313.     else    VOID sprintf( pathname, "%s%s", directory, str);
  314.     return    strdup(pathname);
  315. #else    VMS21
  316. # ifdef PRIME
  317.     /* >        -> full pathname    LEAVE ALONE
  318.      * <else>   -> normal        PREFIX with directory>
  319.      */
  320.     if (directory == NULL || index(str, '>'))
  321.         return strdup(str);
  322.     else    VOID sprintf( pathname, "%s>%s", directory, str);
  323.     return    strdup(pathname);
  324. # else  PRIME
  325.     /* Not VMS or PRIME -> must be UNIX !! */
  326.  
  327.     /* /      -> full pathname    LEAVE ALONE
  328.      * ./ ../ -> relative pathname    LEAVE ALONE
  329.      * <else> -> Normal        PREFIX with directory/
  330.      */
  331.     if( *str == '/' || directory == NULL ||
  332.         lexequ(str, "../", 3) || lexequ(str,"./", 2) )
  333.         return strdup(str);
  334.     else    VOID sprintf( pathname, "%s/%s", directory, str);
  335.     return    strdup(pathname);
  336. # endif PRIME
  337. #endif    VMS21
  338. }
  339.  
  340. void skipnl(fp)    /* skip to to next line */
  341. register FILE    *fp;
  342. {
  343.     register int c;
  344.  
  345.     while((c = getc(fp)) != '\n' && c != EOF)
  346.         ;
  347.     if( c == EOF)
  348.         fatal0("Unexpected end of file");
  349. }
  350.  
  351. void
  352. consistant(fp, file)    /* check headers for consistancy */
  353. FILE    *fp;
  354. char    *file;
  355. {
  356.     Version    temp;
  357.  
  358.     if( thisversion.day == 0 )    /* not initialised yet */
  359.     {
  360.         getversion(&thisversion, fp);
  361.         if( verbose )
  362.         {
  363.             vprintf0(1, "NRS database - ");
  364.             verprint( stderr, &thisversion);
  365.             putc('\n', stderr);
  366.         }
  367.         return;
  368.     }
  369.     getversion(&temp, fp);
  370.     if( thisversion.hours != temp.hours
  371.         || thisversion.minutes != temp.minutes
  372.         || thisversion.day != temp.day
  373.         || thisversion.month != temp.month
  374.         || thisversion.year != temp.year
  375.         || thisversion.format != temp.format)
  376.     {
  377.         fprintf( stderr, "Versions differ - reference ");
  378.         verprint(stderr, &thisversion);
  379.         fprintf( stderr, "File %s ", file);
  380.         verprint(stderr, &temp );
  381.         fatal0("\nFiles are out of sync");
  382.     }
  383. }
  384.  
  385. static_f void
  386. getversion(vp, fp)
  387. Version    *vp;
  388. FILE    *fp;
  389. {
  390.     int    c;
  391.  
  392.     while( isspace(c = getc(fp)) )
  393.             ;
  394.     VOID ungetc(c, fp);
  395.     /* Parse ``hh.mm  ddmmyyFORMAT f''*/
  396.     vp->hours    = getint(fp, 2);
  397.     vp->minutes     = getint(fp, 3);
  398.     vp->day        = getint(fp, 3);
  399.     vp->month    = getint(fp, 2);
  400.     vp->year    = getint(fp, 2);
  401.     vp->format    = getint(fp, 8);
  402. }
  403.  
  404. static_f void
  405. verprint(fp, vp)
  406. Version    *vp;
  407. FILE    *fp;
  408. {
  409.     fprintf(fp, "version %02d:%02d %2d/%02d/19%02d format%2d",
  410.             vp->hours,
  411.             vp->minutes,
  412.             vp->day,
  413.             vp->month,
  414.             vp->year,
  415.             vp->format);
  416. }
  417.  
  418. void
  419. addcomments(fp, name, rest)
  420. FILE    *fp;
  421. char    *name, *rest;
  422. {
  423.     FILE    *cfp;
  424.     char    buffer[256], *p, *ctime();
  425.  
  426.     if((cfp = fopen(commentfile, "r")) == NULL)
  427.     {
  428.         warn1(1, "Can't open comments file %s", commentfile);
  429.         return;
  430.     }
  431.     while( fgets(buffer, sizeof buffer, cfp) != NULL)
  432.     {
  433.         for(p = buffer; *p; p++)
  434.         {
  435.             if( *p != MAGIC )
  436.             {
  437.                 putc(*p, fp);
  438.                 continue;
  439.             }
  440.             if( *(p + 2) != MAGIC || *(p+1) == '\0')
  441.             {
  442.                 putc(*p, fp);
  443.                 continue;
  444.             }
  445.             switch(*(p+1))
  446.             {
  447.             case 'D':    /* the date */
  448.             {
  449.                 time_t    now;
  450.  
  451.                 VOID time(&now);
  452.                 fprintf(fp, "%.24s", ctime(&now));
  453.                 break;
  454.             }
  455.             case    'H':    /* the hostname */
  456.                 if( hostname )
  457.                     fputs(hostname, fp);
  458.                 break;
  459.             case    'N':    /* the nrs data */
  460.                 verprint(fp, &thisversion);
  461.                 break;
  462.             case    'F':    /* the file    */
  463.                 fputs(name, fp);
  464.                 break;
  465.             case    'C':    /* any other string */
  466.                 fputs(rest, fp);
  467.                 break;
  468.             }
  469.             p += 2;
  470.         }
  471.     }
  472.     VOID fclose(cfp);
  473. }
  474.  
  475. #ifdef    VMS21
  476. char *
  477. index(string, ch)
  478. register char *string;
  479. register char ch;
  480. {
  481.     while (*string) if (*string++ == ch) return --string;
  482.     return (char *) 0;
  483. }
  484. #endif    VMS21
  485.