⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.c

📁 同步软件源码,作者 Jeroen C. Kessels Internet Engineer
💻 C
字号:
#include "version.h"

#include <stdio.h>
#include <string.h>
#include <sys/stat.h>                                             /* stat(). */

#include "md5.h"
#include "common.h"




/* Translate character to lowercase. */
char LowerCase(char c) {
  if ((c >= 'A') && (c <= 'Z')) return((c - 'A') + 'a');
  return(c);
  }




/* Return the last position in a string of any character from
   collection. The haystack string is scanned from end to begin until a
   character is found from the needle string. The pointer to the found
   character is returned, or NULL if not found. This subroutine is
   designed to find a directory separator in a path, where the directory
   separator can be '\\' (DOS) or '/' (Unix). */
char *strrchrs(char *haystack, char *needle) {
  char *h_here;
  char *n_here;
  long h_length;

  if ((haystack == NULL) || (needle == NULL)) return(NULL);

  for (h_length = 0, h_here = haystack; *h_here != '\0'; h_here++, h_length++);
  while (h_length > 0) {
    h_here--;
    h_length--;
    n_here = needle;
    while (*n_here != '\0') {
      if (*n_here == *h_here) return(h_here);
      n_here++;
      }
    }

  return(NULL);
  }




/* Search case-insensitive for a substring. */
char *stristr(char *Haystack, char *Needle) {
  register char *p1;
  register int i;

  if ((Haystack == NULL) || (Needle == NULL)) return(NULL);

  p1 = Haystack;
  i = strlen(Needle);
  while (*p1 != '\0') {
    if (strnicmp(p1,Needle,i) == 0) return(p1);
    p1++;
    }

  return(NULL);
  }




/* Strip trailing whitespace. Whitespace is: space, horizontal tab, newline,
   carriage return, form feed. */
char *striptw(char *s_out, char *s_in) {
  register char *s_in_here;
  register char *s_out_here;
  register long i;

  if ((s_in == NULL) || (s_out == NULL)) {
    return NULL;
    }

  for (i = 0, s_in_here = s_in; *s_in_here++; i++) ;
  for (s_in_here--, s_in_here--;
       (i > 0) &&  ((*s_in_here == ' ') ||
                    (*s_in_here == '\t') ||
                    (*s_in_here == '\n') ||
                    (*s_in_here == '\r') ||
                    (*s_in_here == '\f'));
       s_in_here--, i--) ;
  for (s_in_here = s_in, s_out_here = s_out; i > 0; i--) {
    *s_out_here++ = *s_in_here++;
    }
  *s_out_here = '\0';

  return s_out;
  }




/* Copy a string into a buffer with a specified length. If the input string
   has more characters then it will be truncated. */
void StringCopyBuf(char *In, char *Out, long int Width) {

  if (Out == NULL) return;
  if (In == NULL) {
    if (Width > 0) *Out = '\0';
    return;
    }

  while ((*In != '\0') && (Width > 1)) {
    *Out++ = *In++;
    Width--;
    }
  if (Width > 0) *Out = '\0';
  }




/* Accept a single word from a string. The word may optionally be
   enclosed in single or double quotes, which will be stripped.
   Words are delimited by whitespace (space, tab, carriage return,
   linefeed, formfeed). The output will not contain carriage return,
   linefeed, formfeed. */
char *AcceptWord(char *In, char *Out, int Width) {
  char Quote;

  Quote = '\0';
  if ((*In == '"') || (*In == '\'')) Quote = *In++;
  while ((*In != '\0') && (*In != '\n') && (*In != '\r') && (*In != '\f')) {
    if (Quote != '\0') {
        if (*In == Quote) {
          In++;
          break;
          }
      } else {
        if ((*In == ' ') || (*In == '\t')) break;
        }
    if ((Out != NULL) && (Width > 1)) {
        *Out++ = *In++;
        Width--;
      } else {
        In++;
        }
    }
  if ((Out != NULL) && (Width > 0)) *Out = '\0';
  while ((*In == ' ') || (*In == '\t') || (*In == '\n') ||
         (*In == '\r') || (*In == '\f')) In++;
  return(In);
  }




/* Compare a string with a mask, case-insensitive. If it matches then return
   YES, otherwise NO. The mask may contain wildcard characters '?' (any
   character) '*' (any characters). */
int MatchMask(char *String, char *Mask) {
  char *m;
  char *s;

  if (String == NULL) return NO;                /* Just to speed up things. */
  if (Mask == NULL) return NO;
  if (strcmp(Mask,"*") == 0) return YES;

  m = Mask;
  s = String;

  while ((*m != '\0') && (*s != '\0')) {
    if ((LowerCase(*m) != LowerCase(*s)) && (*m != '?')) {
      if (*m != '*') return NO;
      m++;
      if (*m == '\0') return YES;
      while (*s != '\0') {
        if (MatchMask(s,m) == YES) return YES;
        s++;
        }
      return NO;
      }
    m++;
    s++;
    }

  while (*m == '*') m++;
  if ((*s == '\0') && (*m == '\0')) return YES;
  return NO;
  }




/* Translate a path. The separator '/' or '\' is translated into the
   directory separator ('/' for Unix, '\' for DOS). */
void FixupPath(char *In) {

  if ((In == NULL) || (*In == '\0')) return;

  while (*In != '\0') {
    if ((*In == '/') || (*In == '\\')) {
        *In++ = *DIRSEP;
      } else {
        In++;
        }
    }
  }




/* I had to write my own stat() function because of a bug in Turbo-C (memory
   leak). */
int MyStat(char *Path, struct stat *statbuf) {
  FILE *Fin;
  int Result;

  Fin = fopen(Path,"r");
  if (Fin != NULL) {
    Result = fstat(fileno(Fin),statbuf);
    fclose(Fin);
    return(Result);
    }
  return(stat(Path,statbuf));
  }





/* Translate a binary buffer into Base64 encoding. The output is automatically
   split into lines with a maximum width of 70 characters (51 input characters).
   Worst-case size of the output is: InWidth * 4 / 3 + 2 * InWidth / 54 + 6
   WARNING: if you are encoding a large block of data in successive calls
   (blocking), then make sure the blocks have a size that is a multiple of 3!
   */
void Base64encode(
    unsigned char *In,
    unsigned long int InWidth,
    unsigned char *Out,
    unsigned long int OutWidth) {
  char Trans[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  unsigned char *p1;
  char *p2;
  int c;
  int Column;

  if ((In == NULL) || (InWidth == 0)) return;
  if ((Out == NULL) || (OutWidth == 0)) return;

  p1 = In;
  p2 = Out;
  Column = 0;
  while (InWidth > 0) {
    if (OutWidth > 1) {
      *p2++ = Trans[(*p1 >> 2) & 0x3F];
      OutWidth--;
      }
    c = ((*p1 & 0x03) << 4);
    p1++;
    InWidth--;
    if (InWidth > 0) {
        c = (c | ((*p1 >> 4) & 0x0F));
        if (OutWidth > 1) {
          *p2++ = Trans[c];
          OutWidth--;
          }
        c = ((*p1 & 0x0F) << 2);
        p1++;
        InWidth--;
        if (InWidth > 0) {
            c = (c | ((*p1 >> 6) & 0x03));
            if (OutWidth > 2) {
              *p2++ = Trans[c];
              *p2++ = Trans[*p1 & 0x3F];
              OutWidth = OutWidth - 2;
              }
            p1++;
            InWidth--;
          } else {
            if (OutWidth > 2) {
              *p2++ = Trans[c];
              *p2++ = '=';
              OutWidth = OutWidth - 2;
              }
            }
      } else {
        if (OutWidth > 3) {
          *p2++ = Trans[c];
          *p2++ = '=';
          *p2++ = '=';
          OutWidth = OutWidth - 3;
          }
        }
    Column++;
    if ((InWidth > 0) && (Column >= 18)) {
      if (OutWidth > 2) {
        *p2++ = '\r';
        *p2++ = '\n';
        OutWidth = OutWidth - 2;
        }
      Column = 0;
      }
    }
  *p2 = '\0';
  }




/* Translate a Base64-encoded string into binary. Return the number of
   bytes in the output. A trailing zero is added (but not counted), so
   the output can be used as a string. Because of this, the minimum size
   of the output buffer must be at least 1 more than the maximum number
   of bytes expected. */
unsigned long int Base64decode(
    unsigned char *In,               /* The base-64 encoded input string. */
    unsigned char *Out,              /* Where the output will be stored. */
    unsigned long int Width) {       /* Size of the output buffer. */
  short RTrans[256] = {
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    62, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    };
  unsigned long int Bytes;
  int ch;
  int i;

  /* Test the input parameters. */
  if (Out == NULL) return(0);
  if ((In == NULL) || (Width <= 1)) {
    if (Width > 0) *Out = '\0';
    return(0);
    }

  /* Translate the base-64 encoded string. The input may contain characters
     like carriage-return and linefeed, which will be quietly skipped. */
  i = 0;
  *Out = '\0';
  Bytes = 0;
  while (*In != '\0') {
    ch = RTrans[*In++];
    if (ch == -2) break;
    if (ch < 0) continue;
    if (i == 0) {
      *Out = ch << 2;
      Bytes = Bytes + 1;
      }
    if (i == 1) {
      *Out++ |= ch >> 4;
      Width--;
      if (Width <= 1) break;
      *Out = (ch & 0x0f) << 4;
      Bytes = Bytes + 1;
      if (RTrans[*In] == -2) break;
      }
    if (i == 2) {
      *Out++ |= ch >>2;
      Width--;
      if (Width <= 1) break;
      *Out = (ch & 0x03) << 6;
      Bytes = Bytes + 1;
      if (RTrans[*In] == -2) break;
      }
    if (i == 3) {
      *Out++ |= ch;
      *Out = '\0';
      Width--;
      if (Width <= 1) break;
      }
    i++;
    if (i > 3) i = 0;
    }
  if (Width > 1) Out++;
  *Out = '\0';
  return(Bytes);
  }





/* Password encoding.
   The algorithm uses a Challenge that was received from the remote
   and a password from the configuration file. Both strings are
   concatenated and then a checksum calculated using the MD5
   algorithm. We send this to the remote, it does the same with it's
   password, and compares the results. If both output strings are
   equal then it assumes the passwords to be equal. */
void PasswordEncode(char *Challenge, char *Password, char *Output) {
  md5_byte_t Digest[16];
  md5_state_t Context;
  int i;

  md5_init(&Context);
  md5_append(&Context,(unsigned char *)Challenge,strlen(Challenge));
  md5_append(&Context,(unsigned char *)Password,strlen(Password));
  md5_finish(&Context,Digest);
  for (i = 0; i < 16; i++) sprintf(Output+2*i,"%02x",Digest[i]);
  }




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -