home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / fido / pup_v2b.zip / SUPPORT.C < prev    next >
C/C++ Source or Header  |  1988-01-28  |  10KB  |  450 lines

  1. #include <puppy.h>
  2. #include <ascii.h>
  3. #include <pupmem.h>
  4.  
  5. /*
  6. Various low level and extremely important support routines. These
  7. do not need to be customized generally to fit the target machine. 
  8.  
  9.  
  10. append(fname)    Open or create file fname for appending.
  11.  
  12. logoff(code,disc)
  13.         Terminate this call; disconnect from the modem if
  14.         disc is true; sets code as the DOS ERRORLEVEL for this
  15.         connect. This writes out the caller record as necessary, 
  16.         etc.
  17.  
  18. makefname(buf,name)
  19.         Creates a full pathname from the current (Msg, File,
  20.         Upload, pup.bbs) area. NOTE: If 'ovpath' is not blank,
  21.         it is used instead of the one from the area.
  22.  
  23. rline(f,line,len)
  24.         Read a line of text; a line is defined as characters
  25.         delimited by a CR. See the code for special cases. Returns
  26.         0 if end of file.
  27.  
  28. int num_args(string)    Returns the number of args in the string, seperated
  29.             by delims (see delim(), below). Leading delimiters
  30.             are ignored.
  31.  
  32. char *next_arg(string) Returns a pointer to the next arg, delimited 
  33.             by a delim, skipping over the current arg. Use via
  34.             ptr= nextarg(ptr) to skip to each argument. All 
  35.             switches at the end of the current arg are skipped.
  36.  
  37.  
  38. char *skip_delim(string) Skips leading delims in a string. returns a pointer.
  39.  
  40. cpyarg(to,from)    Copies a string, up to the next delim or switch.
  41.             Leading and trailing delimiters are stripped (from 
  42.             the output string) and a null terminator is added.
  43.  
  44.             after cpyarg()        FROM: foo/b foobar fipple
  45.                         TO: foo
  46.  
  47. char *strip_path(out,in) Copies the disk specifier or pathname to the output
  48.             array, and returns a pointer to the name in the input
  49.             string.    Drive specs are considered a path, and are
  50.             treated as such by DOS. Stripping "a:foo" and
  51.             "bin/foo/framis.asm" result in:
  52.  
  53.                 IN:    "A:"
  54.                 IN:    "bin\foo"
  55.  
  56.                 OUT:    "A:"
  57.                 OUT:    "bin\"
  58.  
  59. stolower(s)    Convert a string to all lower case
  60.  
  61. stoupper(s)    Convert a string to all upper case
  62.  
  63. atoi(s)        Convert a string of digits into a numeric value; stops
  64.         when the first non-digit character is found.
  65.  
  66.  
  67.  
  68. str_time(s,t)    Generates a static string expression of date or time, and
  69. str_date(s,t)    returns a pointer to it. Through a kludge it can be 
  70.         called up to 4 times without overwriting a previous 
  71.         invokation.
  72.  
  73. same_node(n1,n2) Returns true if the two nodes are the same.
  74.  
  75. cpy_node(&dest,&src)
  76.         Copies one node into another.
  77.  
  78. delim(c)    Returns true if the character is a delimiter.
  79.  
  80. char *str_node(&node)
  81.         Generates a static string expression of the node, and 
  82.         returns a pointer to it. Through a kludge it can be 
  83.         called up to 4 times without overwriting a previous 
  84.         invokation.
  85.  
  86. set_nn(string,&node)
  87.         Parse the string into various zone:net/node numbers. 
  88.         This accepts "zone:net/node" format. If zone or net 
  89.         isnt specified, it is left untouched.
  90.  
  91. */
  92.  
  93. /* Display the date. */
  94.  
  95. str_date(t)
  96. WORD t;
  97. {
  98. static char work[2][sizeof("31 Dec 143 ")];    /* where we keep them */
  99. static int k;                    /* which one as are on */
  100.  
  101.     k = ++k % 2;        /* select next ... */
  102.     *work[k]= NUL;        /* empty it */
  103.  
  104.     sprintf(work[k],"%u %s %02u",        /* the format, */
  105.         t & 0x1f,                /* the day, */
  106.         months[(t >> 5) & 0x0f],        /* the month name */
  107.         ((t >> 9) & 0x3f) + 80);        /* the year */
  108.     return(work[k]);
  109. }
  110.  
  111. /* Display the time. */
  112.  
  113. str_time(t)
  114. WORD t;
  115. {
  116. static char work[2][sizeof("23:59PM ")];    /* where we keep them */
  117. static int k;                    /* which one as are on */
  118. char hour;
  119.  
  120.     k = ++k % 2;        /* select next ... */
  121.     *work[k]= NUL;        /* empty it */
  122.  
  123.     hour= t >> 11; if (!hour) hour= 12;
  124.     sprintf(work[k],"%d:%02d",hour,(t >> 5) & 0x3f);
  125.     if (hour >= 12) strcat(work[k],"PM"); else strcat(work[k],"AM");
  126.     return(work[k]);
  127. }
  128.  
  129. /* Open a file for appending, creating it if necessary. Return the
  130. open handle, or -1 if error. */
  131.  
  132. append(s)
  133. char *s;
  134. {
  135. int h;
  136. char c;
  137.  
  138.     h= open(s,2);                /* open or create the */
  139.     if (h == -1) h= creat(s,2);        /* file, if opened OK */
  140.     else lseek(h,0L,2);            /* seek to the end */
  141.     return(h);                /* handle or error */
  142. }
  143.  
  144. /* Log a caller off the system; disconnect and force a termination. */
  145.  
  146. logoff(code,disc)
  147. int code,disc;
  148. {
  149. int f;
  150. char buff[SS];
  151. long p;
  152.  
  153.     limit= 0;                /* disable time limits */
  154.     doscode= code;                /* set result code, */
  155.     if (!test && disc) discon();        /* do disconnect, */
  156.     frc_abort();                /* force rturn to main */
  157. }
  158.  
  159. /* Copy the path prefix, append one filename from the input string. */
  160.  
  161. makefname(d,s)
  162. char *d,*s;
  163. {
  164.     strcpy(d,pup.filepref);        /* the path prefix, */
  165.     d= next_arg(d);            /* point to its end, */
  166.     cpyarg(d,s);            /* add one filename */
  167. }
  168.  
  169. /* Display a text file. */
  170.  
  171. dspfile(filename)
  172. char *filename;
  173. {
  174. int f;
  175.  
  176.     f= open(filename,0);
  177.     if (f == -1) return(0);
  178.     dumptext(f);
  179.     close(f);
  180.     return(1);
  181. }
  182.  
  183. /* Output the contents of a text file to the console. The handle of 
  184. an open file is passed. Output ceases when EOF or a Control-Z is found. */
  185.  
  186. dumptext(file)
  187. int file;
  188. {
  189. char lastc,c,buff[512];                /* local buffering */
  190. unsigned index,count;
  191.  
  192.     if (file == -1) return;                /* be serious */
  193.  
  194.     index= count= 0;                /* buffer is empty */
  195.     while (1) {
  196.         if (index >= count) {            /* read some if */
  197.             index= 0;            /* the local buffer */
  198.             count= read(file,buff,sizeof(buff)); /* is empty */
  199.         }
  200.         if (! count) break;            /* stop if empty file */
  201.         if (abort) break;            /* stop if aborted */
  202.  
  203.         c= buff[index++];            /* get a character, */
  204.         if (c == LF) continue;            /* ignore LFs */
  205.         if (c == CR + 128) {            /* special case soft CRs */
  206.             if (lastc == ' ') continue;
  207.             c= ' ';
  208.         }
  209.  
  210.         lastc= c;                /* remember it, */
  211.         if (c == CR) mputs("\r\n");        /* CR becomes CR/LF */
  212.         else fmconout(c);            /* else output text */
  213.         if (c == SUB) break;            /* ^Z is end of file */
  214.     }
  215.     mputs("\r\n");
  216. }
  217.  
  218. /* Write the system file out to disk. */
  219.  
  220. putsys() {
  221.  
  222. int f;
  223.  
  224.     f= open("puppy.sys",2);
  225.     if (f == -1) {
  226.         printf("Can't open PUPPY.SYS!\r\n");
  227.         return;
  228.     }
  229.     write(f,&pup,sizeof(struct _pup));
  230.     close(f);
  231. }
  232.  
  233. /* Read a line of text from the file, null terminate it.  Function returns
  234. zero if EOF. Deletes all CRs and Control-Zs from the stream. Lines are
  235. terminated by LFs. */
  236.  
  237. rline(file,buf,len)
  238. int file;
  239. char *buf;
  240. int len;
  241. {
  242. int i;
  243. char notempty,c;
  244.  
  245.     i= 0; notempty= 0;
  246.     --len;                        /* compensate for added NUL */
  247.     while (i < len) {
  248.         if (! read(file,&c,1)) break;        /* stop if empty */
  249.         if (c == 0x1a) continue;        /* totally ignore ^Z, */
  250.         notempty= 1;                /* not empty */
  251.         if (c == '\r') continue;        /* skip CR, */
  252.         if (c == '\r' + 128) continue;        /* skip soft CR, */
  253.         if (c == '\n') break;            /* stop if LF */
  254.         buf[i++]= c;
  255.     }
  256.     buf[i]= '\0';
  257.     return(notempty);
  258. }
  259.  
  260. /* Return the number of args left in the string. */
  261.  
  262. num_args(s)
  263. char *s;
  264. {
  265. int count;
  266.  
  267.     count= 0;
  268.     s= skip_delim(s);            /* skip leading blanks, */
  269.     while (*s) {
  270.         ++count;            /* count one, */
  271.         s= next_arg(s);            /* find next, */
  272.     }
  273.     return(count);
  274. }
  275.  
  276. /* Return a pointer to the next argument in the string. */
  277.  
  278. char *next_arg(s)
  279. char *s;
  280. {
  281.     while ((!delim(*s)) && *s)        /* skip this one, */
  282.         ++s;                /* up to delim, */
  283.     s= skip_delim(s);            /* then skip delims, */
  284.     return(s);
  285. }
  286.  
  287. /* Skip over the leading delimiters in a string. */
  288.  
  289. char *skip_delim(s)
  290. char *s;
  291. {
  292.     while (delim(*s) && *s) {
  293.         ++s;
  294.     }
  295.     return(s);
  296. }
  297.  
  298. /* Copy the string to the destination array, stopping if we find one
  299. of our delimiters. */
  300.  
  301. cpyatm(to,from)
  302. char *to;
  303. char *from;
  304. {
  305.     while ( (!delim(*from)) && *from) 
  306.         *to++= *from++;
  307.     *to= '\0';
  308. }
  309.  
  310. /* Copy the string to the destination array, stopping if we find one
  311. of our delimiters. */
  312.  
  313. cpyarg(to,from)
  314. char *to;
  315. char *from;
  316. {
  317.     while (*from) {
  318.         if (delim(*from)) break;
  319.         *to++= *from++;
  320.     }
  321.     *to= '\0';
  322. }
  323.  
  324. /* Strip the pathname or disk specifier from a filename, return it in a
  325. seperate array. We do this by initially copying the entire name in, then
  326. searching for the colon or slash. Right after the last one we find,
  327. stuff a null, removing the name part. 
  328.  
  329. Also return a pointer to the name part in the input name. */
  330.  
  331. char *strip_path(out,in)
  332. char *out;
  333. char *in;
  334. {
  335. char *name;
  336. char *endpath;
  337.  
  338.     strcpy(out,in);            /* duplicate, for working, */
  339.     name= in;            /* point to name, */
  340.     endpath= out;            /* and end of path part, */
  341.  
  342.     while (*in) {            /* look for slashes or colons, */
  343.         if (*in == ':')    {    /* if a colon, */
  344.             endpath= ++out;    /* point to name, */
  345.             name= ++in;
  346.  
  347.         } else if ((*in == '/') || (*in == '\\')) {
  348.             endpath= ++out;    /* move the pointer up, */
  349.             name= ++in;
  350.         } else {
  351.             ++in;
  352.             ++out;
  353.         }
  354.     }
  355.     *endpath= '\0';            /* delete the name part, */
  356.     return(name);            /* return ptr to name part. */
  357. }
  358.  
  359. /* Convert a string to lower case. */
  360.  
  361. stolower(s)
  362. char *s;
  363. {
  364.     while (*s) {
  365.         *s= tolower(*s);
  366.         ++s;
  367.     }
  368. }
  369.  
  370. /* Convert a string to upper case. */
  371.  
  372. stoupper(s)
  373. char *s;
  374. {
  375.     while (*s) {
  376.         *s= toupper(*s);
  377.         ++s;
  378.     }
  379. }
  380.  
  381. /* atoi() function missing from Lattice C. From Kernighan and Richie. */
  382.  
  383. atoi(s)
  384. char *s;
  385. {
  386. int n;
  387.     n= 0;
  388.     while ((*s >= '0') && (*s <= '9')) {
  389.         n *= 10;
  390.         n += *s - '0';
  391.         ++s;
  392.     }
  393.     return(n);
  394. }
  395.  
  396. /* Return true if the two nodes are the same. */
  397.  
  398. same_node(n1,n2)
  399. struct _node *n1,*n2;
  400. {
  401.     return(
  402.         (n1-> number == n2-> number) &&
  403.         (n1-> net == n2-> net) &&
  404.         (n1-> zone == n2-> zone)
  405.     );
  406. }
  407.  
  408. /* Copy one node structure into another. */
  409.  
  410. cpy_node(d,s)
  411. struct _node *d,*s;
  412. {
  413.     d-> zone= s-> zone;
  414.     d-> net= s-> net;
  415.     d-> number= s-> number;
  416. }
  417.  
  418. /* Return a pointer to a string of the zone:net/node. */
  419.  
  420. char *str_node(n)
  421. struct _node *n;
  422. {
  423. #define KLUDGE 4        /* strings we can make at once */
  424. static char work[KLUDGE][40];    /* where we keep them */
  425. static int k;            /* which one as are on */
  426.  
  427.     k = ++k % KLUDGE;    /* select next ... */
  428.     *work[k]= NUL;        /* empty it */
  429.     sprintf(work[k],"%d:",n-> zone);
  430.     sprintf(&work[k][strlen(work[k])],"%d/%d",n-> net,n-> number);
  431.     return(work[k]);
  432. }
  433.  
  434.  
  435. /* Return true if the character is a delimiter. */
  436.  
  437. delim(c)
  438. char c;
  439. {
  440. int i;
  441.     switch (c) {
  442.         case ';': 
  443.         case ' ': 
  444.         case ',': 
  445.         case ':': 
  446.             return(1);
  447.         default: return(0);
  448.     }
  449. }
  450.