home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msr313src.zip / msnlib.c < prev    next >
C/C++ Source or Header  |  1993-07-12  |  8KB  |  327 lines

  1. /* File MSNLIB.C
  2.  * Replacement for C library for use with MS-DOS Kermit.
  3.  *
  4.  * Copyright (C) 1985, 1993, Trustees of Columbia University in the 
  5.  * City of New York.  Permission is granted to any individual or institution
  6.  * to use this software as long as it is not sold for profit.  This copyright
  7.  * notice must be retained.  This software may not be included in commercial
  8.  * products without written permission of Columbia University.
  9.  *
  10.  * Last edit
  11.  * 27 August 1992 v3.13
  12.  *  Authors: J.R.Doupnik, USU, Frank da Cruz, Columbia Univ.
  13.  * Contains:
  14.  * strchr, strcat, strncat, strcpy, strncpy, strlen, strcmp, stricmp, strncmp
  15.  * atoi, itoa, ltoa, isdigit, ntoa.
  16. */
  17. #include "msntcp.h"
  18. #include "msnlib.h"
  19.  
  20. #ifndef MSDOS
  21. /*
  22.  In MS-DOS Kermit, these are assembler routines to avoid math library.
  23. */
  24. #define ourmod(a,b)   (a % b)
  25. #define ourdiv(a, b)  (a / b)
  26. #define ourlmod(a,b)  (a % b)
  27. #define ourldiv(a, b) (a / b)
  28. #endif /* MSDOS */
  29.  
  30. #ifndef NULL
  31. #define NULL 0
  32. #endif /* NULL */
  33.  
  34. /*
  35.  By the way, there is probably no point in the next #ifndef,
  36.  because size_t is either built into to the compiler or typedef'd,
  37.  rather than defined.  So the #define below will always happen.
  38. */
  39. #ifndef size_t
  40. #define size_t int
  41. #endif /* size_t */
  42.  
  43. int _acrtused;            /* MS C compiler startup file quantity */
  44.  
  45. /*
  46.   _strchr
  47.   Finds first occurence of character c in string s.
  48.   Returns pointer to it if found, NULL if not found.
  49. */
  50. byte *
  51. strchr(byte *s, const byte c) {
  52.     while ((*s != (byte)'\0') && (*s != (byte)(c & 0xff))) s++;
  53.     if (*s == '\0') return(NULL);
  54.     else return(s);
  55. }
  56.  
  57. byte FAR *
  58. strchrf(byte FAR *s, const byte c) {
  59.     while ((*s != (byte)'\0') && (*s != (byte)(c & 0xff))) s++;
  60.     if (*s == '\0') return(NULL);
  61.     else return(s);
  62. }
  63.  
  64. /*
  65.   _strcat
  66.   Appends entire string s2 to string s1.
  67.   Assumes there is room for s2 after end of s1.
  68.   Returns pointer to s1 or NULL if s1 is a null pointer.
  69. */
  70. byte *
  71. strcat(byte *s1, byte *s2) {
  72.     register byte *p;
  73.  
  74.     if (s1 == NULL) return(NULL);
  75.     if (s2 == NULL || *s2 == '\0') return(s1);
  76.     p = s1;                /* Make copy */
  77.     while (*p) p++;            /* Find end */
  78.     while (*p++ = *s2++) ;        /* Copy thru terminating NUL */
  79.     return(s1);                /* Return original */
  80. }
  81.  
  82. /*
  83.   _strncat
  84.   Appends up to n chars of string s2 to string s1.
  85.   Returns pointer to string1 or NULL if s1 is a null pointer.
  86. */
  87. byte *
  88. strncat(byte *s1, byte *s2, size_t n) {
  89.     register byte * p;
  90.  
  91.     if (s1 == NULL) return(NULL);
  92.     if (s2 == NULL || *s2 == '\0') return(s1);
  93.     p = s1;                /* Copy pointer */
  94.     while (*p) p++;            /* Step to end of s1 */
  95.     while ((*p++ = *s2++) && (--n > 0)) ; /* Copy up to n bytes of s2 */
  96.     return(s1);                /* Return original pointer */
  97. }
  98.  
  99. /*
  100.   _strcpy
  101.   Copies s2 to s1, returns pointer to s1 or NULL if s1 was NULL.
  102. */
  103. byte *
  104. strcpy(byte *s1, byte *s2) {
  105.     register byte *p;
  106.  
  107.     if (s1 == NULL) return(NULL);
  108.     if (s2 == NULL) s2 = "";
  109.     p = s1;                /* Copy pointer */
  110.     while (*p++ = *s2++) ;        /* Copy thru terminating NUL */
  111.     return(s1);                /* Return original pointer */
  112. }
  113.  
  114. /*
  115.   _strncpy
  116.   Copies at most n characters from s2 to to s1, returns pointer to s1.
  117.   Returns s1 or NULL if s1 was NULL.
  118. */
  119. byte *
  120. strncpy(byte *s1, byte *s2, size_t n) {
  121.     register int s2len;
  122.     register byte *p1;
  123.  
  124.     if (s1 == NULL) return(NULL);
  125.     if (s2 == NULL) s2 = "";
  126.     if ((s2len = strlen(s2)) > n) s2len = n;
  127.     p1 = s1;
  128.  
  129.     while (s2len-- > 0)            /* Copy */
  130.       *p1++ = *s2++;
  131.     *p1 = '\0';                /* Terminate */
  132.     return(s1);                /* No need to pad out, one's enuf */
  133. }
  134.  
  135. /*
  136.   _strlen
  137.   Returns length of null-terminated string not including '\0'
  138. */
  139. size_t
  140. strlen(byte *s) {
  141.     register int i = 0;
  142.  
  143.     if (s == NULL) return(0);
  144.     while (*s++) i++;
  145.     return(i);
  146. }
  147.  
  148. /*
  149.   _strcmp
  150.   Compare null-terminated strings using ASCII values.
  151.   Case matters.  Returns:
  152.   < 0 if s1 < s2,
  153.   = 0 if s1 = s2,
  154.   > 0 if s1 > s2
  155. */
  156. int
  157. strcmp(byte *s1, byte *s2) {
  158.     if (s1 == NULL) s1 = "";
  159.     if (s2 == NULL) s2 = "";
  160.     do {
  161.     if (*s1 < *s2) return(-1);
  162.     if (*s1 > *s2) return(1);
  163.     if (*s2 == '\0') return(0);
  164.     s2++;
  165.     } while (*s1++);
  166.     return(0);
  167. }
  168.  
  169. /*
  170.   _stricmp
  171.   Like strcmp but case insenstive
  172. */
  173. int
  174. stricmp(byte *s1, byte *s2) {
  175.     register byte c1, c2;
  176.  
  177.     if (s1 == NULL) s1 = "";
  178.     if (s2 == NULL) s2 = "";
  179.     do {
  180.     c1 = *s1; c2 = *s2;
  181.     if ('a' <= c1 && c1 <= 'z') c1 = c1 - (byte)('a' - 'A');
  182.     if ('a' <= c2 && c2 <= 'z') c2 = c2 - (byte)('a' - 'A');
  183.     if (c1 < c2) return(-1);
  184.     if (c1 > c2) return(1);
  185.     if (c2 == '\0') return(0);
  186.     s1++; s2++;
  187.     } while (c1 != '\0');
  188.     return(0);
  189. }
  190.  
  191. /*
  192.   _strncmp
  193.   Compares at most n characters of strings s1 and s2.
  194. */
  195. int
  196. strncmp(byte *s1, byte *s2, size_t n) {    
  197.  
  198.     if (s1 == NULL) s1 = "";
  199.     if (s2 == NULL) s2 = "";
  200.     while (n-- > 0 && *s1) {
  201.     if (*s1 < *s2) return(-1);
  202.     if (*s1 > *s2) return(1);
  203.     s1++; s2++;
  204.     }
  205.     return(0);
  206. }
  207.  
  208. /*
  209.   _atoi
  210.   Converts decimal numeric string to integer.
  211.   Breaks on first non-digit or end of string.
  212.   Returns integer.
  213. */
  214. int
  215. atoi(byte *s) {
  216.     register int i, count;
  217.     count = 0;
  218.     for (i = 0; i < 18; i++) {
  219.     if (*s < '0' || *s > '9') break;
  220.     count *= 10;
  221.     count += *s - '0';        /* ascii to binary */
  222.     s++;
  223.     }
  224.     return(count);
  225. }
  226.  
  227. /*
  228.   _itoa
  229.   Converts integer value to ASCII digits (up to 18 characters long),
  230.   stores in string, null terminated.  Returns NULL on failure,
  231.   pointer to result on success.
  232. */
  233. byte *
  234. itoa(int value, byte *string, int radix) { /* From K & R */
  235.     int c, j, sign;
  236.     register int i;
  237.     register byte *s;
  238.  
  239.     if (string == NULL) return(NULL);
  240.     
  241.     s = string;
  242.  
  243.     if ((sign = value) < 0)        /* Save sign */
  244.       value = - value;            /* Force value positive */
  245.     i = 0;
  246.     do {
  247.     s[i++] = (byte)(ourmod(value, radix) + '0');
  248.     } while ((value = ourdiv(value, radix)) > 0);
  249.  
  250.     if (sign < 0)
  251.       s[i++] = '-';
  252.     s[i] = '\0';
  253.     j = strlen(s) -1;
  254.     for (i = 0; i < j; i++, j--) {
  255.     c = s[i];
  256.     if (c > '9') c = c - '9' + 'A' -1;
  257.     s[i] = s[j];
  258.     s[j] = (byte)(c & 0xff);
  259.     }
  260.     return(string);
  261. }
  262.  
  263. /*
  264.   _ltoa (in pcdbug.c)
  265.   Like itoa() but using long value ( < 34 ).
  266. */
  267. byte *
  268. ltoa(long value, byte *string, int radix) { /* K & R */
  269.     int c, j;
  270.     register int i;
  271.     long sign;
  272.     register byte * s;
  273.  
  274.     if (string == NULL) return(NULL);
  275.     s = string;
  276.  
  277.     if ((sign = value) < 0) value = - value; /* value to positive*/
  278.     i = 0;
  279.     do {
  280.     s[i++] = (byte)(ourlmod(value, radix) + '0');
  281.     } while ((value = ourldiv(value, radix)) > 0);
  282.  
  283.     if (sign < 0)
  284.       s[i++] = '-';
  285.     s[i] = '\0';
  286.  
  287.     j = strlen(s) - 1;
  288.     for (i = 0; i < j; i++, j--) {
  289.     c = s[i];
  290.     if (c > '9') c = c - '9' + 'A' -1;
  291.     s[i] = s[j];
  292.     s[j] = (byte)(c & 0xff);
  293.     }
  294.     return(string);
  295. }
  296.  
  297. /*
  298.   _isdigit
  299.   Returns 1 if argument is a decimal digit, 0 otherwise.
  300. */
  301. int
  302. isdigit(const byte c) {
  303.     if ((c & 0xff) < '0' || (c & 0xff) > '9')
  304.       return(0);            /* say is not a digit */
  305.     return(1);
  306. }
  307.  
  308. /* 
  309.    Convert long val to dotted decimal string at pointer p, does high order
  310.    byte first. Intended to yield dotted decimal IP addresses from longs.
  311. */
  312. void
  313. ntoa(byte *p, unsigned long val)
  314. {
  315.     register byte *ptr;
  316.     register int i;
  317.     
  318.     ptr = p;
  319.     for (i = 24; i >= 0; i -= 8)
  320.         {
  321.         itoa((int)((val >> i) & 0xff), ptr, 10); /* convert a byte */
  322.         strcat(ptr, ".");            /* dot separator */
  323.         ptr = p + strlen(p);
  324.         }
  325.     *(--ptr) = '\0';            /* remove trailing dot */
  326. }
  327.