APUE函数笔记十四: 网络IPC:套接字

58 篇文章 0 订阅
49 篇文章 0 订阅

第十六章:  网络IPC:套接字:

#include <sys/socket.h>
int socket(int domain, int type, int protocol);
    domain:
        AF_INET, AF_INET6, AF_UNIX, AF_UNSPEC
    type:
        SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET, SOCK_STREAM
    if error return -1

#include <sys/socket.h>
int shutdown(int sockfd, int how);
    how:
        SHUT_RD, SHUT_WR, SHUT_RDWR
    if success return 0, else error return -1

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostint32);
uint16_t htons(uint16_t hostint16);
uint32_t ntohl(uint32_t netint32);
uint16_t ntohs(uint16_t netint16);

#include <arpa/inet.h>
const char * inet_ntop(int domain, const void * restrict addr, 
                       char * restrict str, socklen_t size);
int inet_pton(int domain, const char * restrict str, void * restrict addr);
    if error return -1

#include <netdb.h>
struct hostent * gethostent(void);
void sethostent(int stayopen);
void endhostent(void);

#include <netdb.h>
struct netent * getnetbyaddr(uint32_t net, int type);
struct netent * getnetbyname(const char * name);
struct netent * getnetent(void);
void setnetent(int stayopen);
void endnetent(void);

#include <netdb.h>
struct protoent * getprotobyname(const char * name);
struct protoent * getprotobynumber(int proto);
struct protoent * getprotoent(void);
void setprotoent(int stayopen);
void endprotoent(void);

#include <netdb.h>
struct servent * getservbyname(const char * name, const char * proto);
struct servent * getservbyport(int port, const char * proto);
struct servent * getservent(void);
void setservent(int stayopen);
void endservent(void);

#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo(const char * restrict host, 
                const char * restrict service, 
                const struct addrinfo * restrict hint, 
                struct addrinfo ** restrict res);
    if success return 0, else return error-no, not set errno
void freeaddrinfo(struct addrinfo * ai);

#include <netdb.h>
const char * gai_strerror(int error);

#include <sys/socket.h>
#include <netdb.h>
int getnameinfo(const struct sockaddr * restrict addr, socklen_t alen, 
                char * restrict host, socklen_t hostlen, 
                char * restrict service, socklen_t servlen, 
                unsigned int flags);
    if success return 0

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr * addr, socklen_t len);
    if success return 0, else error return -1

#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr * restrict addr, 
                socklen_t * restrict alenp);
    if success return 0, else error return -1

#include <sys/socket.h>
int getpeername(int sockfd, struct sockaddr * restrict addr, 
                socklen_t * restrict alenp);
    if success return 0, else error return -1

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr * addr, socklen_t len);
    if success return 0, else error return -1

#include <sys/socket.h>
int listen(int sockfd, int backlog);
    backlog <= SOMAXCONN
    if success return 0, else error return -1

#include <sys/socket.h>
int accept(int sockfd, struct sockaddr * restrict addr, 
           socklen_t * restrict len);
    if error return -1

#include <sys/socket.h>
ssize_t send(int sockfd, const void * buf, size_t nbytes, int flags);
    if success return nbytes, else error return -1

#include <sys/socket.h>
ssize_t sendto(int sockfd, const void * buf, size_t nbytes, int flags, 
               const struct sockaddr * destaddr, socklen_t destlen);
    flags:
        MSG_DONTROUTE, MSG_DONTWAIT, MSG_EOR, MSG_OOB
    if success return nbytes, else error return -1

#include <sys/socket.h>
ssize_t sendmsg(int sockfd, const struct msghdr * msg, int flags);
    if success return byte-count, else error return -1
    struct msghdr {
        void         * msg_name;
        socklen_t      msg_namelen;
        struct iovec * msg_iov;
        int            msg_iovlen;
        void         * msg_control;
        socklen_t      msg_controllen;
        int            msg_flags;
        ...
    };
    struct iovec {
        void * iov_base;
        size_t iov_len;
    };

#include <sys/socket.h>
ssize_t recv(int sockfd, void * buf, size_t nbytes, int flags);
    flags:
        MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL
    if error return -1

#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void * restrict buf, size_t len, int flags, 
                 struct sockaddr * restrict addr, 
                 socklen_t * restrict addrlen);
    if error return -1

#include <sys/socket.h>
ssize_t recvmsg(int sockfd, struct msghdr * msg, int flags);
    if error return -1

#include <sys/socket.h>
int setsockopt(int sockfd, int level, int option, 
               const void * val, socklen_t len);
    if success return 0, else error return -1

#include <sys/socket.h>
int getsockopt(int sockfd, int level, int option, 
               void * restrict val, socklen_t * restrict lenp);
    option:
        SO_ACCEPTCONN, SO_BROADCAST, SO_DEBUG,    SO_DONTROUTE, 
        SO_ERROR,      SO_KEEPALIVE, SO_LINGER,   SO_OOBINLINE, 
        SO_RCVBUF,     SO_RCVLOWAT,  SO_RCVTIMEO, SO_REUSEADDR, 
        SO_SNDBUF,     SO_SNDLOWAT,  SO_SNDTIMEO, SO_TYPE
    if success return 0, else error return -1

#include <sys/socket.h>
int sockatmark(int sockfd);
    if true return 1, else if false return 0, else error return -1

示例:

#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <arpa/inet.h>
#if defined(BSD) || defined(MACOS)
#include <sys/socket.h>
#include <netinet/in.h>
#endif

void 
print_family(struct addrinfo * aip)
{
    printf("  family  ");
    switch (aip->ai_family)
    {
        case AF_INET:
        {
            printf("inet");
            break;
        }
        case AF_INET6:
        {
            printf("inet6");
            break;
        }
        case AF_UNIX:
        {
            printf("unix");
            break;
        }
        case AF_UNSPEC:
        {
            printf("unspecified");
            break;
        }
        default:
        {
            printf("unknown");
            break;
        }
    }
}

void 
print_type(struct addrinfo * aip)
{
    printf("  type  ");
    switch (aip->ai_socktype)
    {
        case SOCK_STREAM:
        {
            printf("stream");
            break;
        }
        case SOCK_DGRAM:
        {
            printf("datagram");
            break;
        }
        case SOCK_SEQPACKET:
        {
            printf("seqpacket");
            break;
        }
        case SOCK_RAW:
        {
            printf("raw");
            break;
        }
        default:
        {
            printf("unknown (%d)", aip->ai_socktype);
            break;
        }
    }
}

void 
print_protocol(struct addrinfo * aip)
{
    printf("  protocol  ");
    switch (aip->ai_protocol)
    {
        case 0:
        {
            printf("default");
            break;
        }
        case IPPROTO_TCP:
        {
            printf("tcp");
            break;
        }
        case IPPROTO_UDP:
        {
            printf("udp");
            break;
        }
        case IPPROTO_RAW:
        {
            printf("raw");
            break;
        }
        default:
        {
            printf("unknown (%d)", aip->ai_protocol);
            break;
        }
    }
}

void 
print_flags(struct addrinfo * aip)
{
    printf("  flags  ");
    if (aip->ai_flags == 0) {
        printf("0");
    }
    else {
        if (aip->ai_flags & AI_PASSIVE) {
            printf("passive");
        }
        if (aip->ai_flags & AI_CANONNAME) {
            printf("cannon");
        }
        if (aip->ai_flags & AI_NUMERICHOST) {
            printf("numhost");
        }
#if defined(AI_NUMERICSERV)
        if (aip->ai_flags & AI_NUMERICSERV) {
            printf("mumserv");
        }
#endif
#if defined(AI_V4MAPPED)
        if (aip->ai_flags & AI_V4MAPPED) {
            printf("v4mapped");
        }
#endif
#if defined(AI_ALL)
        if (aip->ai_flags & AI_ALL) {
            printf("all");
        }
#endif
    }
}

int 
main(int argc, char * argv[])
{
    struct addrinfo    * ailist;
    struct addrinfo    * aip;
    struct addrinfo      hint;
    struct sockaddr_in * sinp;
    const char         * addr;
    int                  err;
    char                 abuf[INET_ADDRSTRLEN];

    if (argc != 3) {
        printf("usage: %s nodename service\n", argv[0]);
        exit(1);
    }
    hint.ai_flags = AI_CANONNAME;
    hint.ai_family = 0;
    hint.ai_socktype = 0;
    hint.ai_protocol = 0;
    hint.ai_addrlen = 0;
    hint.ai_canonname = NULL;
    hint.ai_addr = NULL;
    hint.ai_next = NULL;
    if ((err = getaddrinfo(argv[1], argv[2], &hint, &ailist)) != 0) {
        printf("getaddrinfo error: %s\n", gai_strerror(err));
        exit(1);
    }
    for (aip = ailist; aip != NULL; aip = aip->ai_next) {
        print_flags(aip);
        print_family(aip);
        print_type(aip);
        print_protocol(aip);
        printf("\n\thost %s", aip->ai_canonname ? aip->ai_canonname : "-");
        if (aip->ai_family == AF_INET) {
            sinp = (struct sockaddr_in *)aip->ai_addr;
            addr = inet_ntop(AF_INET, &sinp->sin_addr, abuf, INET_ADDRSTRLEN);
            printf(" address %s", addr ? addr : "unknown");
            printf(" port %d", ntohs(sinp->sin_port));
        }
        printf("\n");
    }
    exit(0);
}

#include <sys/socket.h>

#define MAXSLEEP 128

int 
connect_retry(int sockfd, const struct sockaddr * addr, socklen_t alen)
{
    int  nsec;

    /*
     * try to connect with exponential backoff
     */
    for (nsec = 1; nsec <= MAXSLEEP; nsec <<= 1) {
        if (connect(sockfd, addr, alen) == 0) {
            /*
             * connection accepted
             */
            return(0);
        }

        /*
         * delay before trying again
         */
        if (nsec <= MAXSLEEP / 2) {
            sleep(nsec);
        }
    }
    return(-1);
}

#include <errno.h>
#include <sys/socket.h>

int 
initserver(int type, const struct sockaddr * addr, socklen_t alen, int qlen)
{
    int  fd;
    int  err;
    int  reuse = 1;

    if ((fd = socket(addr->sa_family, type, 0)) == -1) {
        return(-1);
    }
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) == -1) {
        err = errno;
        goto errout;
    }
    if (bind(fd, addr, alen) == -1) {
        err = errno;
        goto errout;
    }
    if (type == SOCK_STREAM || type == SOCK_SEQPACKET) {
        if (listen(fd, qlen) == -1) {
            err = errno;
            goto errout;
        }
    }
    return(fd);

errout:
    close(fd);
    errno = err;
    return(-1);
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>

#include "connect_retry.h"

#define MAXADDRLEN  256
#define BUFLEN      128

#define MAXSLEEP 128

void 
print_uptime(int sockfd)
{
    int   n;
    char  buf[BUFLEN];

    while ((n = recv(sockfd, buf, BUFLEN, 0)) > 0) {
        write(STDOUT_FILENO, buf, n);
    }
    if (n < 0) {
        printf("recv error\n");
    }
}

int 
main(int argc, char * argv[])
{
    struct addrinfo * ailist;
    struct addrinfo * aip;
    struct addrinfo   hint;
    int               sockfd;
    int               err;

    if (argc != 2) {
        printf("usage: ruptime hostname\n");
        exit(1);
    }
    hint.ai_flags = 0;
    hint.ai_family = 0;
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_protocol = 0;
    hint.ai_addrlen = 0;
    hint.ai_canonname = NULL;
    hint.ai_addr = NULL;
    hint.ai_next = NULL;
    if ((err = getaddrinfo(argv[1], "ruptime", &hint, &ailist)) != 0) {
        printf("getaddrinfo error: %s\n", gai_strerror(err));
        exit(1);
    }
    for (aip = ailist; aip != NULL; aip = aip->ai_next) {
        if ((sockfd = socket(aip->ai_family, SOCK_STREAM, 0)) == -1) {
            err = errno;
        }
        else if (connect_retry(sockfd, aip->ai_addr, aip->ai_addrlen) < 0) {
            err = errno;
        }
        else {
            print_uptime(sockfd);
            exit(0);
        }
    }
    fprintf(stderr, "cannot connect to %s: %s\n", argv[1], strerror(err));
    exit(1);
}

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <syslog.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>

#include "initserver.h"
#include "daemon.h"

#define BUFLEN  128
#define QLEN    10

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX  256
#endif

void 
serve(int sockfd)
{
    int    clfd;
    FILE * fp;
    char   buf[BUFLEN];

    for (;;) {
        clfd = accept(sockfd, NULL, NULL);
        if (clfd < 0) {
            syslog(LOG_ERR, "ruptimed: accept error: %s", strerror(errno));
            exit(1);
        }
        if ((fp = popen("/usr/bin/uptime", "r")) == NULL) {
            sprintf(buf, "error: %s\n", strerror(errno));
            send(clfd, buf, strlen(buf), 0);
        }
        else {
            while (fgets(buf, BUFLEN, fp) != NULL) {
                send(clfd, buf, strlen(buf), 0);
            }
            pclose(fp);
        }
        close(clfd);
    }
}

int 
main(int argc, char * argv[])
{
    struct addrinfo * ailist;
    struct addrinfo * aip;
    struct addrinfo   hint;
    int               sockfd;
    int               err;
    int               n;
    char            * host;

    if (argc != 1) {
        printf("usage: ruptimed\n");
        exit(1);
    }
#ifdef _SC_HOST_NAME_MAX
    n = sysconf(_SC_HOST_NAME_MAX);
    if (n < 0) /* best guess */
#endif
        n = HOST_NAME_MAX;
    host = (char *)malloc(n);
    if (host == NULL) {
        printf("malloc error\n");
        exit(1);
    }
    if (gethostname(host, n) < 0) {
        printf("gethostname error\n");
        exit(1);
    }
    daemonize("ruptimed");
    hint.ai_flags = AI_CANONNAME;
    hint.ai_family = 0;
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_protocol = 0;
    hint.ai_addrlen = 0;
    hint.ai_canonname = NULL;
    hint.ai_addr = NULL;
    hint.ai_next = NULL;
    if ((err = getaddrinfo(argv[1], "ruptime", &hint, &ailist)) != 0) {
        syslog(LOG_ERR, "ruptimed: getaddrinfo error: %s\n", gai_strerror(err));
        exit(1);
    }
    for (aip = ailist; aip != NULL; aip = aip->ai_next) {
        if ((sockfd = initserver(SOCK_STREAM, aip->ai_addr, aip->ai_addrlen, 
                                 QLEN)) >= 0) {
            serve(sockfd);
            exit(0);
        }
    }
    exit(1);
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/wait.h>

#include "initserver.h"
#include "daemon.h"

#define QLEN    10

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX  256
#endif


void 
serve(int sockfd)
{
    int    clfd;
    int    status;
    pid_t  pid;

    for (;;) {
        clfd = accept(sockfd, NULL, NULL);
        if (clfd < 0) {
            syslog(LOG_ERR, "ruptimed: fork error: %s", strerror(errno));
            exit(1);
        }
        if ((pid = fork()) < 0) {
            syslog(LOG_ERR, "ruptimed: fork error: %s", strerror(errno));
            exit(1);
        }
        else if (pid == 0) { 
            /*
             * the parent called daemonize, so STDIN_FINENO, STDOUT_FINENO, 
             * STDERR_FINENO are already open to /dev/null, thus, the call
             * to close does not need to be protected by checks that clfd
             * is not already equal to one of these values
             */
            if (dup2(clfd, STDOUT_FILENO) != STDOUT_FILENO ||
                dup2(clfd, STDERR_FILENO) != STDERR_FILENO) {
                syslog(LOG_ERR, "ruptimed: unexpected error");
                exit(1);
            }
            close(clfd);
            execl("/usr/bin/uptime", "uptime", NULL);
            syslog(LOG_ERR, "ruptime: unexpected return from exec: %s", 
                   strerror(errno));
        }
        else {
            close(clfd);
            waitpid(pid, &status, 0);
        }
    }
}

int 
main(int argc, char * argv[])
{
    struct addrinfo * ailist;
    struct addrinfo * aip;
    struct addrinfo   hint;
    int               sockfd;
    int               err;
    int               n;
    char            * host;

    if (argc != 1) {
        printf("usage: ruptimed\n");
        exit(1);
    }
#ifdef _SC_HOST_NAME_MAX
    n = sysconf(_SC_HOST_NAME_MAX);
    if (n < 0) /* best guess */
#endif
        n = HOST_NAME_MAX;
    host = (char *)malloc(n);
    if (host == NULL) {
        printf("malloc error\n");
        exit(1);
    }
    if (gethostname(host, n) < 0) {
        printf("gethostname error\n");
        exit(1);
    }
    daemonize("ruptimed");
    hint.ai_flags = AI_CANONNAME;
    hint.ai_family = 0;
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_protocol = 0;
    hint.ai_addrlen = 0;
    hint.ai_canonname = NULL;
    hint.ai_addr = NULL;
    hint.ai_next = NULL;
    if ((err = getaddrinfo(argv[1], "ruptime", &hint, &ailist)) != 0) {
        syslog(LOG_ERR, "ruptimed: getaddrinfo error: %s\n", gai_strerror(err));
        exit(1);
    }
    for (aip = ailist; aip != NULL; aip = aip->ai_next) {
        if ((sockfd = initserver(SOCK_STREAM, aip->ai_addr, aip->ai_addrlen, 
                                 QLEN)) >= 0) {
            serve(sockfd);
            exit(0);
        }
    }
    exit(1);
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/wait.h>

#include "initserver.h"
#include "daemon.h"
#include "mysignal.h"

#define QLEN    10

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX  256
#endif

void sig_child(int signo)
{
    while (waitpid((pid_t)-1, NULL, WNOHANG) > 0) {
        
    }
}

void 
serve(int sockfd)
{
    int    clfd;
    int    status;
    pid_t  pid;

    if (my_signal(SIGCHLD, sig_child) == SIG_ERR) {
        printf("signal error\n");
        exit(1);
    }

    for (;;) {
        clfd = accept(sockfd, NULL, NULL);
        if (clfd < 0) {
            syslog(LOG_ERR, "ruptimed: fork error: %s", strerror(errno));
            exit(1);
        }
        if ((pid = fork()) < 0) {
            syslog(LOG_ERR, "ruptimed: fork error: %s", strerror(errno));
            exit(1);
        }
        else if (pid == 0) { 
            /*
             * the parent called daemonize, so STDIN_FINENO, STDOUT_FINENO, 
             * STDERR_FINENO are already open to /dev/null, thus, the call
             * to close does not need to be protected by checks that clfd
             * is not already equal to one of these values
             */
            if (dup2(clfd, STDOUT_FILENO) != STDOUT_FILENO ||
                dup2(clfd, STDERR_FILENO) != STDERR_FILENO) {
                syslog(LOG_ERR, "ruptimed: unexpected error");
                exit(1);
            }
            close(clfd);
            execl("/usr/bin/uptime", "uptime", NULL);
            syslog(LOG_ERR, "ruptime: unexpected return from exec: %s", 
                   strerror(errno));
        }
        else {
            close(clfd);
        }
    }
}

int 
main(int argc, char * argv[])
{
    struct addrinfo * ailist;
    struct addrinfo * aip;
    struct addrinfo   hint;
    int               sockfd;
    int               err;
    int               n;
    char            * host;

    if (argc != 1) {
        printf("usage: ruptimed\n");
        exit(1);
    }
#ifdef _SC_HOST_NAME_MAX
    n = sysconf(_SC_HOST_NAME_MAX);
    if (n < 0) /* best guess */
#endif
        n = HOST_NAME_MAX;
    host = (char *)malloc(n);
    if (host == NULL) {
        printf("malloc error\n");
        exit(1);
    }
    if (gethostname(host, n) < 0) {
        printf("gethostname error\n");
        exit(1);
    }
    daemonize("ruptimed");
    hint.ai_flags = AI_CANONNAME;
    hint.ai_family = 0;
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_protocol = 0;
    hint.ai_addrlen = 0;
    hint.ai_canonname = NULL;
    hint.ai_addr = NULL;
    hint.ai_next = NULL;
    if ((err = getaddrinfo(argv[1], "ruptime", &hint, &ailist)) != 0) {
        syslog(LOG_ERR, "ruptimed: getaddrinfo error: %s\n", gai_strerror(err));
        exit(1);
    }
    for (aip = ailist; aip != NULL; aip = aip->ai_next) {
        if ((sockfd = initserver(SOCK_STREAM, aip->ai_addr, aip->ai_addrlen, 
                                 QLEN)) >= 0) {
            serve(sockfd);
            exit(0);
        }
    }
    exit(1);
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <signal.h>

#define BUFLEN      128
#define TIMEOUT     20

void 
print_uptime(int sockfd, struct addrinfo * aip)
{
    int   n;
    char  buf[BUFLEN];

    buf[0] = '\0';
    if (sendto(sockfd, buf, 1, 0, aip->ai_addr, aip->ai_addrlen) < 0) {
        printf("sendto error\n");
        exit(1);
    }
    alarm(TIMEOUT);
    if ((n = recvfrom(sockfd, buf, BUFLEN, 0, NULL, NULL)) < 0) {
        if (errno != EINTR) {
            alarm(0);
        }
        printf("recv error\n");
        exit(1);
    }
    alarm(0);
    write(STDOUT_FILENO, buf, n);
}

void 
sig_alrm(int signo)
{
    
}

int 
main(int argc, char * argv[])
{
    struct addrinfo  * ailist;
    struct addrinfo  * aip;
    struct addrinfo    hint;
    int                sockfd;
    int                err;
    struct sigaction   sa;

    if (argc != 2) {
        printf("usage: ruptime hostname\n");
        exit(1);
    }
    sa.sa_handler = sig_alrm;
    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);
    if (sigaction(SIGALRM, &sa, NULL) < 0) {
        printf("sigaction error\n");
        exit(1);
    }
    hint.ai_flags = 0;
    hint.ai_family = 0;
    hint.ai_socktype = SOCK_DGRAM;
    hint.ai_protocol = 0;
    hint.ai_addrlen = 0;
    hint.ai_canonname = NULL;
    hint.ai_addr = NULL;
    hint.ai_next = NULL;
    if ((err = getaddrinfo(argv[1], "ruptime", &hint, &ailist)) != 0) {
        printf("getaddrinfo error: %s\n", gai_strerror(err));
        exit(1);
    }
    for (aip = ailist; aip != NULL; aip = aip->ai_next) {
        if ((sockfd = socket(aip->ai_family, SOCK_STREAM, 0)) == -1) {
            err = errno;
        }
        else {
            print_uptime(sockfd, aip);
            exit(0);
        }
    }
    fprintf(stderr, "cannot connect to %s: %s\n", argv[1], strerror(err));
    exit(1);
}

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <syslog.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>

#include "initserver.h"
#include "daemon.h"

#define BUFLEN         128
#define MAXADDRLEN     256

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX  256
#endif

void 
serve(int sockfd)
{
    int         n;
    socklen_t   alen;
    FILE      * fp;
    char        buf[BUFLEN];
    char        abuf[MAXADDRLEN];

    for (;;) {
        alen = MAXADDRLEN;
        if ((n = recvfrom(sockfd, buf, BUFLEN, 0, 
                          (struct sockaddr *)abuf, &alen)) < 0) {
            syslog(LOG_ERR, "ruptimed: recvfrom error: %s", strerror(errno));
            exit(1);
        }
        if ((fp = popen("/usr/bin/uptime", "r")) == NULL) {
            sprintf(buf, "error: %s\n", strerror(errno));
            sendto(sockfd, buf, strlen(buf), 0, 
                   (struct sockaddr *)abuf, alen);
        }
        else {
            if (fgets(buf, BUFLEN, fp) != NULL) {
                sendto(sockfd, buf, strlen(buf), 0, 
                       (struct sockaddr *)abuf, alen);
            }
            pclose(fp);
        }
    }
}

int 
main(int argc, char * argv[])
{
    struct addrinfo * ailist;
    struct addrinfo * aip;
    struct addrinfo   hint;
    int               sockfd;
    int               err;
    int               n;
    char            * host;

    if (argc != 1) {
        printf("usage: ruptimed\n");
        exit(1);
    }
#ifdef _SC_HOST_NAME_MAX
    n = sysconf(_SC_HOST_NAME_MAX);
    if (n < 0) /* best guess */
#endif
        n = HOST_NAME_MAX;
    host = (char *)malloc(n);
    if (host == NULL) {
        printf("malloc error\n");
        exit(1);
    }
    if (gethostname(host, n) < 0) {
        printf("gethostname error\n");
        exit(1);
    }
    daemonize("ruptimed");
    hint.ai_flags = AI_CANONNAME;
    hint.ai_family = 0;
    hint.ai_socktype = SOCK_DGRAM;
    hint.ai_protocol = 0;
    hint.ai_addrlen = 0;
    hint.ai_canonname = NULL;
    hint.ai_addr = NULL;
    hint.ai_next = NULL;
    if ((err = getaddrinfo(argv[1], "ruptime", &hint, &ailist)) != 0) {
        syslog(LOG_ERR, "ruptimed: getaddrinfo error: %s\n", gai_strerror(err));
        exit(1);
    }
    for (aip = ailist; aip != NULL; aip = aip->ai_next) {
        if ((sockfd = initserver(SOCK_DGRAM, aip->ai_addr, aip->ai_addrlen, 
                                 0)) >= 0) {
            serve(sockfd);
            exit(0);
        }
    }
    exit(1);
}

#include <fcntl.h>
#include <sys/ioctl.h>
#if defined(BSD) || defined(MACOS) || defined(SOLARIS)
#include <sys/filio.h>
#endif

int 
setasync(int sockfd)
{
    int n = 1;

    if (fcntl(sockfd, F_SETOWN, getpid()) < 0) {
        return(-1);
    }
    if (ioctl(sockfd, FIOASYNC, &n) < 0) {
        return(-1);
    }
    return(0);
}

int 
clrasync(int sockfd)
{
    int n = 0;

    if (ioctl(sockfd, FIOASYNC, &n) < 0) {
        return(-1);
    }
    return(0);
}

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

int 
main(void)
{
    uint32_t        i;
    unsigned char * cp;

    i = 0x04030201;
    cp = (unsigned char *)&i;
    if (*cp == 1) {
        printf("little-endian\n");
    }
    else if (*cp == 4) {
        printf("big-endian\n");
    }
    else {
        printf("who hnowns?\n");
    }
    exit(0);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值