psptcpux.c

来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 1,005 行 · 第 1/2 页

C
1,005
字号
        return PSP_DUPLICATE;    if (sock == -1)        return PSP_FAILED;    if ((lmcdata = psp_getMemory(sizeof(LMC_SERVER_DATA), 0)) == NULL) {        close(sock);        unlink(tokfile);        return PSP_NOMEMORY;    }    lmcdata->clients = psp_getMemory(maxclients * sizeof(LMC_CLIENT_DATA), 0);    if (lmcdata->clients == NULL) {        psp_freeMemory(lmcdata, 0);        close(sock);        unlink(tokfile);        return PSP_NOMEMORY;    }    lmcdata->count = 0;    FD_ZERO(&lmcdata->holdFDS);    FD_SET(sock, &lmcdata->holdFDS);    lmcdata->sock1 = sock;    lmcdata->sock2 = -1;    if (tokfile[0])        lmcdata->tokfile = psp_strdup(tokfile, 0);    else        lmcdata->tokfile = NULL;    lmcdata->numclients = 0;    lmcdata->maxclients = maxclients;    *data = lmcdata;    return PSP_OKAY;}#endif/* ==========================================================================   Handle a new connection*/static void new_connection(    int               listensock,    LMC_SERVER_DATA  *lmcdata){    int              ii;    int              len;    int              sock;    LMC_CLIENT_DATA *client;    FD_CLR(listensock, &lmcdata->FDS);    for (ii = 0; ii < lmcdata->maxclients; ii++) {        if (!lmcdata->clients[ii])            break;    }    if (ii == lmcdata->maxclients)        return;    if  ((client = psp_getMemory(sizeof(LMC_CLIENT_DATA), 0)) == NULL)        return;    lmcdata->count--;    do {        len = sizeof(saddr);        sock = accept(listensock, (struct sockaddr *) &client->addrinfo, &len);        if (sock == -1 && errno != EINTR) {            psp_freeMemory(client, 0);            return;        }    } while (sock == -1);    client->sock = sock;    FD_SET(sock, &lmcdata->holdFDS);    if (++lmcdata->numclients == lmcdata->maxclients) {        listen(lmcdata->sock1, 0);        if (lmcdata->sock2 >= 0)            listen(lmcdata->sock2, 0);    }    lmcdata->clients[ii] = client;}/* ==========================================================================   Check for a message or new connection*/static void *handle_data(    LMC_SERVER_DATA *lmcdata){    int               ii;    LMC_CLIENT_DATA **clients;    if (lmcdata->sock1 != -1 && FD_ISSET(lmcdata->sock1, &lmcdata->FDS))        new_connection(lmcdata->sock1, lmcdata);    if (lmcdata->sock2 >= 0 && FD_ISSET(lmcdata->sock2, &lmcdata->FDS))        new_connection(lmcdata->sock2, lmcdata);    if (lmcdata->count) {        clients = lmcdata->clients;        for (ii = 0; ii  < lmcdata->maxclients; ii++) {            if (clients[ii] && FD_ISSET(clients[ii]->sock, &lmcdata->FDS)) {                FD_CLR(lmcdata->clients[ii]->sock, &lmcdata->FDS);                lmcdata->count--;                return clients[ii];            }        }    }    lmcdata->count = 0;  /* just to be sure */    return NULL; /* timeout */}/* ==========================================================================   Wait for a message*/static void *psp_socket_waitmsg(    void   *data,    long    timeout){    struct timeval   tmout;    LMC_SERVER_DATA *lmcdata = (LMC_SERVER_DATA *) data;    if (!data)        return NULL;    if (lmcdata->count)        return handle_data(lmcdata);    tmout.tv_sec = timeout / 1000;    tmout.tv_usec = (timeout % 1000) * 1000;    memcpy(&lmcdata->FDS, &lmcdata->holdFDS, sizeof(fd_set));    lmcdata->count = select(FD_SETSIZE, &lmcdata->FDS, NULL, NULL, &tmout);    if (lmcdata->count == -1)        return NULL;    if (lmcdata->count)        return handle_data(lmcdata);    return NULL; /* timeout */}/* ==========================================================================   Shut down the listen*/static void psp_socket_stoplisten(    void *data){    int               ii;    LMC_SERVER_DATA  *lmcdata;    LMC_CLIENT_DATA **clients;    if (!data)        return;    lmcdata = (LMC_SERVER_DATA *) data;    if (lmcdata->numclients > 0) {        clients = lmcdata->clients;        for (ii = 0; ii < lmcdata->maxclients; ii++) {            if (clients[ii]) {               close(clients[ii]->sock);               psp_freeMemory(clients[ii], 0);            }        }    }    close(lmcdata->sock1);    if (lmcdata->sock2 >= 0)        close(lmcdata->sock2);    if (lmcdata->tokfile) {        unlink(lmcdata->tokfile);        psp_freeMemory(lmcdata->tokfile, 0);    }    psp_freeMemory(lmcdata->clients, 0);    psp_freeMemory(lmcdata, 0);}/* ==========================================================================   Close the client connection*/static void psp_socket_disconclient(    void  *data,    void  *cdata){    int ii;    LMC_SERVER_DATA *lmcdata;    LMC_CLIENT_DATA *client;    if (!data || !cdata)        return;    lmcdata = (LMC_SERVER_DATA *) data;    client = (LMC_CLIENT_DATA *) cdata;    close(client->sock);    FD_CLR(client->sock, &lmcdata->holdFDS);    if (lmcdata->numclients-- == lmcdata->maxclients) {        listen(lmcdata->sock1, 5);        if (lmcdata->sock2 >= 0)            listen(lmcdata->sock2, 5);    }    if (FD_ISSET(client->sock, &lmcdata->FDS)) {        FD_CLR(client->sock, &lmcdata->FDS);        lmcdata->count--;    }    for (ii = 0; ii < lmcdata->maxclients; ii++) {        if (client == lmcdata->clients[ii]) {            psp_freeMemory(client, 0);            lmcdata->clients[ii] = NULL;        }    }}/* ==========================================================================   Close the connection*/static void psp_socket_disconnect(    void *data){    LMC_CLIENT_DATA *lmcdata;    if (!data)        return;    lmcdata = (LMC_CLIENT_DATA *) data;    shutdown(lmcdata->sock, 2);    close(lmcdata->sock);/*    signal(SIGPIPE, lmcdata->pipefcn); */    if (lmcdata->tokfile)        psp_freeMemory(lmcdata->tokfile, 0);    psp_freeMemory(lmcdata, 0);}/* ==========================================================================   Send a message on a socket*/static int socket_send(    const MSG_HDR  *hdr,    const void     *msg,    int             len,    int             sock){    int         bytes;    const char *cp;    while (send(sock, (const char *) hdr, sizeof(MSG_HDR), 0) == -1) {        if (errno != EINTR)            return PSP_DISCONNECTED;    }    cp = msg;    while (len) {        if ((bytes = send(sock, cp, len, 0)) == -1) {            if (errno == EINTR)                continue;            return PSP_DISCONNECTED;        }        len -= bytes;        cp += bytes;    }    return PSP_OKAY;}/* ==========================================================================   TCP/IP specific send function*/static int psp_tcp_send(    const void *msg,    size_t      len,    const void *data){    MSG_HDR hdr;    hdr.db_star_id = htonl(DB_STAR_ID);    hdr.msglen     = htonl(len);       return socket_send(&hdr, msg, (int) len, ((LMC_CLIENT_DATA *) data)->sock);}/* ==========================================================================   Receive data from a socket*/static int socket_receive(    void *msg,    int   len,    int   sock){    char *cp = msg;    int   bytes;    do    {        if ((bytes = recv(sock, cp, len, 0)) <= 0) {            if (errno == EINTR)                continue;            return PSP_DISCONNECTED;        }        len -= bytes;        cp += bytes;    } while (len);    return PSP_OKAY;}/* ==========================================================================   TCP/IP specific receive function*/static int psp_tcp_receive(    void      **msg,    size_t     *len,    const void *data){    int     stat;    int     sock = ((LMC_CLIENT_DATA *) data)->sock;    MSG_HDR hdr;    if ((stat = socket_receive(&hdr, sizeof(hdr), sock)) != PSP_OKAY)        return stat;    if (ntohl(hdr.db_star_id) != DB_STAR_ID)        return PSP_INVMSG;    *len = ntohl(hdr.msglen);    if ((*msg = psp_getMemory(*len, 0)) == NULL)        return PSP_NOMEMORY;    return socket_receive(*msg, (int) *len, sock);}static void psp_socket_info(    const void *data,    char       *line1,    char       *line2,    char       *line3){    saddr *sa = &((LMC_CLIENT_DATA *) data)->addrinfo;    if (sa->in.sin_family == AF_INET) {        strcpy(line1, "TCP/IP socket connection");        sprintf(line2, "Address: %s", inet_ntoa(sa->in.sin_addr));    }    else {        strcpy(line1, "Unix domain socket connection");        line2[0] = '\0';    }    line3[0] = '\0';} #if !defined(NO_UNIX_DOMAIN) /* ==========================================================================   Check to see if IP (Unix Domain sockets) is available*/int psp_ip_avail(    int            *flags,    LOCKCOMM_FCNS **fcns){    *fcns = &ip_lockcomm;    return PSP_OKAY;}/* ==========================================================================   IP (Unix Domain sockets) specific connect*/static int ip_connect(    const char *name,    const char *tmp,    char       *tokfile,    int         timeout){    int                ii;    int                sock;    int                addr_len;    struct protoent   *protocol;    struct sockaddr   *sockaddr = NULL;    struct sockaddr_un sockaddr_un;    /* Set up the token file for local IP attempt */    strcpy(tokfile, tmp);    strcat(tokfile, name);    protocol = getprotobyname("ip");    sockaddr = (struct sockaddr *) &sockaddr_un;    addr_len = sizeof(sockaddr_un.sun_family) + strlen(tokfile) + 1;    sockaddr_un.sun_family = AF_UNIX;    strncpy(sockaddr_un.sun_path, tokfile, sizeof(sockaddr_un.sun_path));    sockaddr_un.sun_path[sizeof(sockaddr_un.sun_path) - 1] = '\0';    /* The first connect may fail if there is a lot of activity on       the lockmgr. */    sock = socket(sockaddr_un.sun_family, SOCK_STREAM, protocol->p_proto);    if (sock != -1) {        for (ii = 0; ii < timeout; ii++) {            if (connect(sock, sockaddr, addr_len) != -1)                break;            /* TBD: Log out error *//*            printf("ip connect fail: %s (%d)\n", strerror(errno),                    errno); */            psp_sleep(1);        }                    if (ii == timeout) {            close(sock);            return -1;        }    }    return sock;}/* ==========================================================================   Open a connection using IP (Unix Domain sockets)*/static int psp_ip_connect(    const char *lockmgr,    const char *tmp,    const char *id,    void      **data){    int              ii;    int              sock = -1;    char             tokfile[80];    LMC_CLIENT_DATA *lmcdata;    /* TBD: Need to get timeout value (net_timeout) from db.star.ini. */    int              timeout = 5;    if ((sock = ip_connect(lockmgr, tmp, tokfile, timeout)) == -1)        return PSP_FAILED;    /* Allocate control data buffer */    lmcdata = (LMC_CLIENT_DATA *) psp_cGetMemory(sizeof(LMC_CLIENT_DATA), 0);    if (lmcdata == NULL)        return PSP_NOMEMORY;    lmcdata->sock = sock;/*    lmcdata->pipefcn = signal(SIGPIPE, SIG_IGN); */    lmcdata->tokfile = psp_strdup(tokfile, 0);    *data = lmcdata;    return PSP_OKAY;}/* ==========================================================================   IP (Unix Domain sockets) specific send*/static int psp_ip_send(    const void *msg,    size_t      len,    const void *data){    MSG_HDR hdr;    hdr.db_star_id = DB_STAR_ID;    hdr.msglen     = len;       return socket_send(&hdr, msg, (int) len, ((LMC_CLIENT_DATA *) data)->sock);}/* ==========================================================================   IP (Unix Domain sockets) specific send*/static int psp_ip_receive(    void      **msg,    size_t     *len,    const void *data){    int     stat;    int     sock = ((LMC_CLIENT_DATA *) data)->sock;    MSG_HDR hdr;      if ((stat = socket_receive(&hdr, sizeof(hdr), sock)) != PSP_OKAY)        return stat;    if (hdr.db_star_id != DB_STAR_ID)        return PSP_INVMSG;    *len = hdr.msglen;    if ((*msg = psp_getMemory(*len, 0)) == NULL)        return PSP_NOMEMORY;    return socket_receive(*msg, (int) *len, sock);}#endif

⌨️ 快捷键说明

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