📄 common.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 + -