📄 netutil.c
字号:
return(str);
}
/* Check whether a sequence value lies within two others, return 0 if not */
int in_limits(LWORD val, LWORD lo, LWORD hi)
{
long lodiff, hidiff;
lodiff = val - lo;
hidiff = hi - val;
return(lodiff>=0 && hidiff>=0);
}
/* Return total length of data in buffer */
WORD buff_dlen(CBUFF *bp)
{
return((WORD)((bp->in - bp->out) & (bp->len - 1)));
}
/* Return length of untried (i.e. unsent) data in buffer */
WORD buff_untriedlen(CBUFF *bp)
{
return((WORD)((bp->in - bp->trial) & (bp->len - 1)));
}
/* Return length of trial data in buffer (i.e. data sent but unacked) */
WORD buff_trylen(CBUFF *bp)
{
return((WORD)((bp->trial - bp->out) & (bp->len - 1)));
}
/* Return length of free space in buffer */
WORD buff_freelen(CBUFF *bp)
{
return(bp->len ? bp->len - 1 - buff_dlen(bp) : 0);
}
/* Set all the buffer pointers to a starting value */
void buff_setall(CBUFF *bp, LWORD start)
{
bp->out = bp->in = bp->trial = start;
}
/* Rewind the trial pointer by the given byte count, return actual count */
WORD buff_retry(CBUFF *bp, WORD len)
{
len = minw(len, buff_trylen(bp));
bp->trial -= len;
return(len);
}
/* Pre-load data into buffer, i.e. copy into the given buffer location
** Check that existing data isn't overwritten, return byte count if OK.
** If data pointer is null, do check but don't transfer data */
WORD buff_preload(CBUFF *bp, LWORD oset, BYTE *data, WORD len)
{
WORD in, n=0, n1, n2, free;
long inoff;
inoff = oset - bp->in; /* Offset of data from I/P ptr */
in = (WORD)oset & (bp->len-1); /* Mask I/P ptr to buffer area */
free = buff_freelen(bp); /* Free space in buffer */
if (inoff>=0 && inoff<(free)) /* If start is in free space.. */
{
n = minw(len, free); /* Get max allowable length */
n1 = minw(n, (WORD)(bp->len - in)); /* Length up to end of buff */
n2 = n - n1; /* Length from start of buff */
if (n1 && data) /* If anything to copy.. */
memcpy(&bp->data[in], data, n1);/* ..copy up to end of buffer.. */
if (n2 && data) /* ..and maybe also.. */
memcpy(bp->data, &data[n1], n2);/* ..copy into start of buffer */
}
return(n);
}
/* Load data into buffer, return byte count that could be accepted
** If data pointer is null, adjust pointers but don't transfer data */
WORD buff_in(CBUFF *bp, BYTE *data, WORD len)
{
WORD in, n, n1, n2;
in = (WORD)bp->in & (bp->len-1); /* Mask I/P ptr to buffer area */
n = minw(len, buff_freelen(bp)); /* Get max allowable length */
n1 = minw(n, (WORD)(bp->len - in)); /* Length up to end of buff */
n2 = n - n1; /* Length from start of buff */
if (n1 && data) /* If anything to copy.. */
memcpy(&bp->data[in], data, n1); /* ..copy up to end of buffer.. */
if (n2 && data) /* ..and maybe also.. */
memcpy(bp->data, &data[n1], n2); /* ..copy into start of buffer */
bp->in += n; /* Bump I/P pointer */
return(n);
}
/* Load string into buffer, return num of chars that could be accepted */
WORD buff_instr(CBUFF *bp, char *str)
{
return(buff_in(bp, (BYTE *)str, (WORD)strlen(str)));
}
/* Load file into buffer, return byte count */
WORD buff_infile(CBUFF *bp, FILE *fp, WORD len)
{
WORD in, n, n1, n2=0;
int count=0;
in = (WORD)bp->in & (bp->len-1); /* Mask I/P ptr to buffer area */
n = minw(len, buff_freelen(bp)); /* Get max allowable length */
n1 = minw(n, (WORD)(bp->len - in)); /* Length up to end of buff */
if (n1) /* If anything to read.. */
{ /* ..get 1st block from file */
count = fread(&bp->data[in], 1, n1, fp);
n2 = len<n1 ? 0 : n-n1; /* Check for end of file */
}
if (n2) /* Maybe also get 2nd block */
count += fread(bp->data, 1, n2, fp);
bp->in += count; /* Bump I/P pointer */
return((WORD)count);
}
/* Remove trial data from buffer, return byte count.
** If data pointer is null, adjust pointers but don't transfer data */
WORD buff_try(CBUFF *bp, BYTE *data, WORD maxlen)
{
WORD trial, n, n1, n2;
trial = (WORD)bp->trial & (bp->len-1); /* Mask trial ptr to buffer area */
n = minw(maxlen, buff_untriedlen(bp)); /* Get max allowable length */
n1 = minw(n, (WORD)(bp->len - trial)); /* Length up to end of buff */
n2 = n - n1; /* Length from start of buff */
if (n1 && data) /* If anything to copy.. */
memcpy(data, &bp->data[trial], n1); /* ..copy up to end of buffer.. */
if (n2 && data) /* ..and maybe also.. */
memcpy(&data[n1], bp->data, n2); /* ..copy from start of buffer */
bp->trial += n; /* Bump trial pointer */
return(n);
}
/* Remove data from buffer, return byte count
** If data pointer is null, adjust pointers but don't transfer data */
WORD buff_out(CBUFF *bp, BYTE *data, WORD maxlen)
{
WORD out, n, n1, n2;
out = (WORD)bp->out & (bp->len-1); /* Mask O/P ptr to buffer area */
n = minw(maxlen, buff_dlen(bp)); /* Get max allowable length */
n1 = minw(n, (WORD)(bp->len - out)); /* Length up to end of buff */
n2 = n - n1; /* Length from start of buff */
if (n1 && data) /* If anything to copy.. */
memcpy(data, &bp->data[out], n1); /* ..copy up to end of buffer.. */
if (n2 && data) /* ..and maybe also.. */
memcpy(&data[n1], bp->data, n2); /* ..copy from start of buffer */
bp->out += n; /* Bump O/P pointer */
if (buff_untriedlen(bp) > buff_dlen(bp))/* ..and maybe trial pointer */
bp->trial = bp->out;
return(n);
}
/* Return length of null-delimited string in buffer, 0 if no null terminator */
WORD buff_strlen(CBUFF *bp)
{
return(buff_chrlen(bp, 0));
}
/* Return length of string in buffer given delimiter char, 0 if no match */
WORD buff_chrlen(CBUFF *bp, char c)
{
WORD out, n, n1, n2;
BYTE *p, *q=0;
out = (WORD)bp->out & (bp->len-1); /* Mask O/P ptr to buffer area */
n = buff_dlen(bp); /* Get max length */
n1 = minw(n, (WORD)(bp->len - out)); /* Length up to end of buff */
n2 = n - n1; /* Length from start of buff */
if (n1) /* Check up to end of buffer */
q = memchr(p=&bp->data[out], c, n1);
if (!q && n2)
q = memchr(p=bp->data, c, n2); /* ..check data at buffer start */
else
n1 = 0;
return(q ? (WORD)(q - p) + n1 : 0);
}
/* Do TCP-style checksum. Improved algorithm is from RFC 1071 */
WORD csum(void *dp, WORD count)
{
register LWORD total=0L;
register WORD n, *p, carries;
n = count / 2;
p = (WORD *)dp;
while (n--)
total += *p++;
if (count & 1)
total += *(BYTE *)p;
while ((carries=(WORD)(total>>16))!=0)
total = (total & 0xffffL) + carries;
return((WORD)total);
}
/* Safe versions of the min() & max() macros for use on re-entrant code
** Ensures that any function arguments aren't called twice */
WORD minw(WORD a, WORD b)
{
return(a<b ? a : b);
}
WORD maxw(WORD a, WORD b)
{
return(a>b ? a : b);
}
int mini(int a, int b)
{
return(a<b ? a : b);
}
int maxi(int a, int b)
{
return(a>b ? a : b);
}
/* Return byte-swapped word */
WORD swapw(WORD w)
{
return(((w<<8)&0xff00) | ((w>>8)&0x00ff));
}
/* Return byte-swapped longword */
LWORD swapl(LWORD lw)
{
return(((lw<<24)&0xff000000L) | ((lw<<8 )&0x00ff0000L) |
((lw>>8 )&0x0000ff00L) | ((lw>>24)&0x000000ffL));
}
/* Check for timeout on a given tick counter, return non-zero if true */
int timeout(WORD *timep, int sec)
{
WORD tim, diff;
int tout=0;
tim = (WORD)time(0);
diff = tim - *timep;
if (sec==0 || diff>=sec)
{
*timep = tim;
tout = 1;
}
return(tout);
}
/* Check for timeout on a given tick counter, return non-zero if true */
int mstimeout(LWORD *timep, int msec)
{
LWORD tim;
long diff;
int tout=0;
tim = mstime();
diff = tim - *timep;
if (msec==0 || diff>=msec)
{
*timep = tim;
tout = 1;
}
return(tout);
}
#ifndef WIN32
/* Return approximate millisecond count (DOS only) */
LWORD mstime(void)
{
return(biostime(0, 0) * 55L); /* Should be 54.945! */
}
#endif
/* Crude delay in case delay() isn't in the C library
** Derives timing from I/O cycles accessing the interrupt controller
** Slow CPUs (sub-100MHz) will be significantly slower than the given time */
void msdelay(WORD millisec)
{
int n;
while (millisec--)
{
for (n=0; n<1500; n++)
inp(0x61);
}
}
/* Print a hex dump of a buffer */
void hexdump(BYTE *buff, WORD len)
{
BYTE c, str[17];
WORD j, n=0;
while (n < len) /* For each line of 16 bytes... */
{
printf(" %04x:", n);
for (j=0; j<16; j++) /* For each byte of 16... */
{
printf("%c", j==8 ? '-':' '); /* Put '-' after 8 bytes */
if (n++ >= len) /* If no bytes left... */
{
printf(" "); /* Fill out space */
str[j] = 0;
}
else /* If bytes left... */
{
printf("%02x", c = *buff++);/* Print byte value */
str[j] = c>=' '&&c<='~' ? c : '.';
} /* Save char if valid */
}
str[j] = 0; /* Print char string */
printf(" %s\n", str);
}
}
/* Directory 'findfirst' for both DOS and Win32; returns string, or null */
char *find_first(char *path)
{
#if WIN32
if (dir_handle != -1L)
_findclose(dir_handle);
return((dir_handle=_findfirst(path, &dir_block))!=-1L ? dir_block.name : 0);
#else
return(findfirst(path, &dir_block, 0)==0 ? dir_block.ff_name : 0);
#endif
}
/* Directory 'findnext' for both DOS and Win32; returns string, or null */
char *find_next(void)
{
#if WIN32
char *s=0;
if (_findnext(dir_handle, &dir_block)==0)
s = dir_block.name;
else
{
_findclose(dir_handle);
dir_handle = -1L;
}
return(s);
#else
return(findnext(&dir_block)==0 ? dir_block.ff_name : 0);
#endif
}
/* Return the length of a file that has been found */
long find_filesize(void)
{
#if WIN32
return(dir_block.size);
#else
return(dir_block.ff_fsize);
#endif
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -