home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.muug.mb.ca
/
2014.06.ftp.muug.mb.ca.tar
/
ftp.muug.mb.ca
/
pub
/
src
/
gopher
/
gopher1.01
/
object
/
util.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-29
|
6KB
|
320 lines
/*
* Various useful utilities for gopher clients and servers
*
*/
#include "Malloc.h"
#include <string.h>
#include <ctype.h>
#include "boolean.h"
#include "util.h"
/* Read "n" bytes from a descriptor.
* Use in place of read() when fd is a stream socket
*
* Returns the number of total bytes read.
*/
int readn(fd, ptr, nbytes)
int fd;
char *ptr;
int nbytes;
{
int nleft, nread;
nleft = nbytes;
while (nleft > 0) {
nread = read(fd, ptr, nleft);
if (nread < 0)
return(nread); /* error, return <0 */
else if (nread == 0) /* EOF */
break;
nleft -= nread;
ptr += nread;
}
return(nbytes - nleft); /* return >= 0) */
}
/*
* Write "n" bytes to a descriptor.
* Use in place of write() when fd is a stream socket
*
* We return the number of bytes written
*/
int
writen(fd, ptr, nbytes)
int fd;
char *ptr;
int nbytes;
{
int nleft, nwritten;
nleft = nbytes;
while(nleft > 0) {
nwritten = write(fd, ptr, nleft);
if (nwritten <= 0)
return(nwritten); /* error */
nleft -= nwritten;
ptr += nwritten;
}
return(nbytes - nleft);
}
/*
* Writestring uses the writen and strlen calls to write a
* string to the file descriptor fd. If the write fails
* a -1 is returned. Otherwise zero is returned.
*/
int writestring(fd, stringptr)
int fd;
char *stringptr;
{
int length;
length = strlen(stringptr);
if (writen(fd, stringptr, length) != length) {
return(-1);
}
else
return(0);
}
/*
* Read a line from a descriptor. Read the line one byte at a time,
* looking for the newline. We store the newline in the buffer,
* then follow it with a null (the same as fgets(3)).
* We return the number of characters up to, but not including,
* the null (the same as strlen(3))
*/
int readline(fd, ptr, maxlen)
int fd;
char *ptr;
int maxlen;
{
int n;
int rc;
char c;
for (n=1; n < maxlen; n++) {
if ( (rc = read(fd, &c, 1)) == 1) {
*ptr++ = c;
if (c == '\n')
break;
}
else if (rc == 0) {
if (n == 1)
return(0); /* EOF, no data read */
else
break; /* EOF, some data was read */
}
else
return(-1); /* error */
}
*ptr = 0; /* Tack a NULL on the end */
return(n);
}
/*
* Readfield reads data up to a tab, (like readline above)
*/
int
readfield(fd, ptr, maxlen)
int fd;
char *ptr;
int maxlen;
{
int n;
int rc;
char c;
for (n=1; n < maxlen; n++) {
if ( (rc = read(fd, &c, 1)) == 1) {
*ptr++ = c;
if (c == '\t') {
*(ptr - 1) = '\0';
break;
}
}
else if (rc == 0) {
if (n == 1)
return(0); /* EOF, no data read */
else
break; /* EOF, some data was read */
}
else
return(-1); /* error */
}
*ptr = 0; /* Tack a NULL on the end */
return(n);
}
int
sreadword(input, output, maxlen)
char *input;
char *output;
int maxlen;
{
int n;
char c;
for (n=0; n < maxlen; n++) {
c = *input++;
*output++ = c;
if (isspace(c)) {
*(output - 1) = '\0';
break;
}
if (c == '\0') {
break;
}
}
*output = '\0'; /* Tack a NULL on the end */
return(n);
}
/*
* ZapCRLF removes all carriage returns and linefeeds from a C-string.
*/
void
ZapCRLF(inputline)
char *inputline;
{
char *cp;
cp = strchr(inputline, '\r'); /* Zap CR-LF */
if (cp != NULL)
*cp = '\0';
else {
cp = strchr(inputline, '\n');
if (cp != NULL)
*cp = '\0';
}
}
/*
* Utilities for dealing with HTML junk
*/
static boolean acceptable[256];
static boolean acceptable_inited = FALSE;
void init_acceptable()
{
unsigned int i;
char * good =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./-_$";
for(i=0; i<256; i++) acceptable[i] = FALSE;
for(;*good; good++) acceptable[(unsigned int)*good] = TRUE;
acceptable_inited = TRUE;
}
static char hex[17] = "0123456789abcdef";
char from_hex(c)
char c;
{
return (c>='0')&&(c<='9') ? c-'0'
: (c>='A')&&(c<='F') ? c-'A'+10
: (c>='a')&&(c<='f') ? c-'a'+10
: 0;
}
/*
* Finds out if a character is printable & non white space.
* if it is, then return a hex encoding of the char,
* otherwise, just return a reference to the character
*/
char *to_hex(c)
char c;
{
static char out[4];
if (acceptable_inited == FALSE)
init_acceptable();
out[0] = '\0';
if (acceptable[c] == TRUE) {
out[0] = c;
out[1] = '\0';
}
else {
out[0]='%';
out[1]=hex[c >> 4];
out[2]=hex[c & 15];
out[3]='\0';
}
}
/*
* Replace hex escape sequences with the proper codes...
*
* input and output can be the same if you want
*/
void
Fromhexstr(input, output)
char *input, *output;
{
char c;
unsigned int b;
while (*input) {
if (*input == '%') {
input++;
c = *input++;
b = from_hex(c);
c = *input++;
if (!c) break;
*output++ = (b<<4) + from_hex(c);
}
else
*output++ = *input++;
}
*output = '\0';
}
void
Tohexstr(input, output)
char *input, *output;
{
if (acceptable_inited == FALSE)
init_acceptable();
while (*input) {
if (acceptable[*input] == TRUE) {
*output++ = *input++;
}
else {
*output++ = '%';
*output++ = hex[*input >> 4];
*output++ = hex[*input & 15];
input++;
}
}
*output = '\0';
}