sockio.c

来自「LINUX下的收发E-MAIL的程序」· C语言 代码 · 共 203 行

C
203
字号

#include "sockio.h"

unsigned int emlTimeout = 60;	// timeout in seconds


int Resolve(Server * server)
{
    struct hostent *ptr_host;

    if ((ptr_host = gethostbyname(server->hostname)) == NULL)
	return ERROR;

    memcpy(&server->sin.sin_addr, ptr_host->h_addr, ptr_host->h_length);
    snprintf(server->ip, sizeof(server->ip), "%s",
	     inet_ntoa(server->sin.sin_addr));
    return SUCCESS;
}


void strip(char *string, char c)
{
    char *src, *ptr;

    for (src = string; *src != '\0'; src++)
	if (*src == c)
	    for (ptr = src; *ptr != '\0'; ptr++)
		*ptr = *(ptr + 1);
    *src = '\0';
}


int find_string(char *haystack, char *needle)
{
    // determines if one string exists inside another string.
    // returns the location of the string if found, -1 if it is not found. 
    int index, i;
    int len;
    int same;
    int found = FALSE;

    len = strlen(haystack) - strlen(needle);
    index = -1;
    do {
	index++;
	if (haystack[index] == needle[0]) {
	    i = 0;
	    do {
		same = FALSE;
		if (haystack[index + i] == needle[i])
		    same = TRUE;
		i++;
	    } while (same && (i < strlen(needle)));
	    if (same)
		found = TRUE;
	}
    } while (!found && (index < len));

    if (found) {
	return (index);
    } else {
	return (-1);
    }
}


Sigfunc *signal(int signo, Sigfunc * func)
{
    struct sigaction act, oact;

    act.sa_handler = func;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    if (signo == SIGALRM) {
#ifdef SA_INTERRUPT
	act.sa_flags |= SA_INTERRUPT;	/* SunOS 4.x */
#endif
    } else {
#ifdef SA_RESTART
	act.sa_flags |= SA_RESTART;	/* SVR4 and 4.4BSD */
#endif
    }
    if (sigaction(signo, &act, &oact) < 0)
	return (SIG_ERR);
    return (oact.sa_handler);
}


static void sockio_alarm(int signo)
{
    return;
}


int connect_timeo(int sockfd, const struct sockaddr *saptr,
		  unsigned int salen, int nsec)
{
    Sigfunc *sigfunc;
    int n;

    sigfunc = signal(SIGALRM, sockio_alarm);
    if (alarm(nsec) != 0)
	fprintf(stderr, "connect_timeo: alarm was already set\n");

    if ((n = connect(sockfd, (struct sockaddr *) saptr, salen)) < 0) {
	close(sockfd);
	if (errno == EINTR)
	    errno = ETIMEDOUT;
    }
    alarm(0);
    signal(SIGALRM, sigfunc);	/* restore previous signal handler */

    return n;
}


ssize_t recvch(int sock, char *ptr)
{
    static int read_cnt = 0;
    static char *read_ptr;
    static char read_buf[512];

    if (read_cnt <= 0) {
      again:
	if ((read_cnt = read(sock, read_buf, sizeof(read_buf))) < 0) {
	    if (errno == EINTR)
		goto again;
	    return -1;
	} else if (read_cnt == 0)
	    return 0;
	read_ptr = read_buf;
    }
    read_cnt--;
    *ptr = *read_ptr++;
    return 1;
}


ssize_t recvline(int sock, void *vptr, size_t maxlen)
{
    int n, rc;
    char c, *ptr;

    ptr = vptr;
    for (n = 1; n < maxlen; n++) {
	if ((rc = recvch(sock, &c)) == 1) {
	    *ptr++ = c;
	    if (c == '\n')
		break;		// newline is stored, like fgets() 
	} else if (rc == 0) {
	    if (n == 1)
		return 0;	// EOF, no data read 
	    else
		break;		// EOF, some data read 
	} else
	    return -1;		// error, errno set by read() 
    }

    *ptr = 0;			// null terminate like fgets() 
    return n;
}


int sockfd_readable_timeo(int sockfd, unsigned int nsec)
{
    fd_set rset;
    struct timeval tv;

    FD_ZERO(&rset);
    FD_SET(sockfd, &rset);

    tv.tv_sec = nsec;
    tv.tv_usec = 0;

    return (select(sockfd + 1, &rset, NULL, NULL, &tv));
}


ssize_t recvline_timeo(int sockfd, void *vptr, size_t maxlen,
		       unsigned int nsec)
{
    int n = 0;
    struct timeval tv;
    char *ptr;

    tv.tv_sec = nsec;
    tv.tv_usec = 0;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));

    ptr = vptr;

    n = recvfrom(sockfd, ptr, maxlen, 0, NULL, NULL);
    if (n < 0) {
	if (errno == EWOULDBLOCK)
	    errno = 0;
	return -1;
    }

    *(ptr + n) = 0;

    return n;
}

⌨️ 快捷键说明

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