Annotation of sbbs/xpdev/sockwrap.c, revision 1.1

1.1     ! root        1: /* sockwrap.c */
        !             2: 
        !             3: /* Berkley/WinSock socket API wrappers */
        !             4: 
        !             5: /* $Id: sockwrap.c,v 1.24 2005/01/01 00:52:43 rswindell Exp $ */
        !             6: 
        !             7: /****************************************************************************
        !             8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
        !             9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
        !            10:  *                                                                                                                                                     *
        !            11:  * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html         *
        !            12:  *                                                                                                                                                     *
        !            13:  * This library is free software; you can redistribute it and/or                       *
        !            14:  * modify it under the terms of the GNU Lesser General Public License          *
        !            15:  * as published by the Free Software Foundation; either version 2                      *
        !            16:  * of the License, or (at your option) any later version.                                      *
        !            17:  * See the GNU Lesser General Public License for more details: lgpl.txt or     *
        !            18:  * http://www.fsf.org/copyleft/lesser.html                                                                     *
        !            19:  *                                                                                                                                                     *
        !            20:  * Anonymous FTP access to the most recent released source is available at     *
        !            21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
        !            22:  *                                                                                                                                                     *
        !            23:  * Anonymous CVS access to the development source and modification history     *
        !            24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
        !            25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
        !            26:  *     (just hit return, no password is necessary)                                                     *
        !            27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
        !            28:  *                                                                                                                                                     *
        !            29:  * For Synchronet coding style and modification guidelines, see                                *
        !            30:  * http://www.synchro.net/source.html                                                                          *
        !            31:  *                                                                                                                                                     *
        !            32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
        !            33:  * format) via e-mail to [email protected]                                                                      *
        !            34:  *                                                                                                                                                     *
        !            35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
        !            36:  ****************************************************************************/
        !            37: 
        !            38: #include <stdlib.h>            /* malloc/free on FreeBSD */
        !            39: #include <string.h>            /* bzero (for FD_ZERO) on FreeBSD */
        !            40: #include <errno.h>             /* ENOMEM */
        !            41: #include <stdio.h>             /* SEEK_SET */
        !            42: #include <string.h>
        !            43: 
        !            44: #include "genwrap.h"   /* SLEEP */
        !            45: #include "gen_defs.h"  /* BOOL/LOG_WARNING */
        !            46: #include "sockwrap.h"  /* sendsocket */
        !            47: #include "filewrap.h"  /* filelength */
        !            48: 
        !            49: int sendfilesocket(int sock, int file, long *offset, long count)
        !            50: {
        !            51: /* sendfile() on Linux may or may not work with non-blocking sockets ToDo */
        !            52: #if defined(__FreeBSD__) && 0
        !            53: #warning FreeBSD sendfile may cause problems!
        !            54:        off_t   total=0;
        !            55:        off_t   wr=0;
        !            56:        int             i;
        !            57:        long    len;
        !            58: 
        !            59:        len=filelength(file);
        !            60:        if(count<1 || count>len) {
        !            61:                count=len;
        !            62:                count-=offset==NULL?0:*offset;
        !            63:        }
        !            64:        while((i=sendfile(file,sock,(offset==NULL?0:*offset)+total,count-total,NULL,&wr,0))==-1 && errno==EAGAIN)  {
        !            65:                total+=wr;
        !            66:                SLEEP(1);
        !            67:        }
        !            68:        if(i==0)
        !            69:                return((int)count);
        !            70:        return(i);
        !            71: #else
        !            72:        char*   buf;
        !            73:        long    len;
        !            74:        int             rd;
        !            75:        int             wr;
        !            76:        int             total;
        !            77: 
        !            78:        if(offset!=NULL)
        !            79:                if(lseek(file,*offset,SEEK_SET)<0)
        !            80:                        return(-1);
        !            81: 
        !            82:        len=filelength(file);
        !            83: 
        !            84:        if(count<1 || count>len) {
        !            85:                count=len;
        !            86:                count-=tell(file);              /* don't try to read beyond EOF */
        !            87:        }
        !            88: 
        !            89:        if((buf=(char*)malloc(count))==NULL) {
        !            90:                errno=ENOMEM;
        !            91:                return(-1);
        !            92:        }
        !            93: 
        !            94:        rd=read(file,buf,count);
        !            95:        if(rd!=count) {
        !            96:                free(buf);
        !            97:                return(-1);
        !            98:        }
        !            99: 
        !           100:        for(total=wr=0;total<count;total+=wr) {
        !           101:                wr=sendsocket(sock,buf+total,count-total);
        !           102:                if(wr>0)
        !           103:                        continue;
        !           104:                if(wr==SOCKET_ERROR && ERROR_VALUE==EWOULDBLOCK) {
        !           105:                        wr=0;
        !           106:                        SLEEP(1);
        !           107:                        continue;
        !           108:                }
        !           109:                break;
        !           110:        }
        !           111: 
        !           112:        free(buf);
        !           113: 
        !           114:        if(offset!=NULL)
        !           115:                (*offset)+=total;
        !           116: 
        !           117:        if(wr<1)
        !           118:                return(wr);
        !           119: 
        !           120:        return(total);
        !           121: #endif
        !           122: }
        !           123: 
        !           124: int recvfilesocket(int sock, int file, long *offset, long count)
        !           125: {
        !           126:        /* Writes a file from a socket -
        !           127:         *
        !           128:         * sock         - Socket to read from
        !           129:         * file         - File descriptior to write to
        !           130:         *                              MUST be open and writeable
        !           131:         * offset       - pointer to file offset to start writing at
        !           132:         *                              is set to offset writing STOPPED
        !           133:         *                              on return
        !           134:         * count        - number of bytes to read/write
        !           135:         *
        !           136:         * returns -1 if an error occurse, otherwise
        !           137:         * returns number ob bytes written and sets offset
        !           138:         * to the new offset
        !           139:         */
        !           140:         
        !           141:        char*   buf;
        !           142:        int             rd;
        !           143:        int             wr;
        !           144: 
        !           145:        if(count<1) {
        !           146:                errno=ERANGE;
        !           147:                return(-1);
        !           148:        }
        !           149:                
        !           150:        if((buf=(char*)malloc(count))==NULL) {
        !           151:                errno=ENOMEM;
        !           152:                return(-1);
        !           153:        }
        !           154: 
        !           155:        if(offset!=NULL)
        !           156:                if(lseek(file,*offset,SEEK_SET)<0)
        !           157:                        return(-1);
        !           158: 
        !           159:        rd=read(sock,buf,count);
        !           160:        if(rd!=count) {
        !           161:                free(buf);
        !           162:                return(-1);
        !           163:        }
        !           164: 
        !           165:        wr=write(file,buf,rd);
        !           166:        free(buf);
        !           167: 
        !           168:        if(offset!=NULL)
        !           169:                (*offset)+=wr;
        !           170: 
        !           171:        return(wr);
        !           172: }
        !           173: 
        !           174: 
        !           175: /* Return true if connected, optionally sets *rd_p to true if read data available */
        !           176: BOOL socket_check(SOCKET sock, BOOL* rd_p, BOOL* wr_p, DWORD timeout)
        !           177: {
        !           178:        char    ch;
        !           179:        int             i,rd;
        !           180:        fd_set  rd_set;
        !           181:        fd_set* rd_set_p=&rd_set;
        !           182:        fd_set  wr_set;
        !           183:        fd_set* wr_set_p=NULL;
        !           184:        struct  timeval tv;
        !           185: 
        !           186:        if(rd_p!=NULL)
        !           187:                *rd_p=FALSE;
        !           188: 
        !           189:        if(wr_p!=NULL)
        !           190:                *wr_p=FALSE;
        !           191: 
        !           192:        if(sock==INVALID_SOCKET)
        !           193:                return(FALSE);
        !           194: 
        !           195:        FD_ZERO(&rd_set);
        !           196:        FD_SET(sock,&rd_set);
        !           197:        if(wr_p!=NULL) {
        !           198:                wr_set_p=&wr_set;
        !           199:                FD_ZERO(wr_set_p);
        !           200:                FD_SET(sock,wr_set_p);
        !           201:                if(rd_p==NULL)
        !           202:                        rd_set_p=NULL;
        !           203:        }
        !           204: 
        !           205:        /* Convert timeout from ms to sec/usec */
        !           206:        tv.tv_sec=timeout/1000;
        !           207:        tv.tv_usec=(timeout%1000)*1000;
        !           208: 
        !           209:        i=select(sock+1,rd_set_p,wr_set_p,NULL,&tv);
        !           210:        if(i==SOCKET_ERROR)
        !           211:                return(FALSE);
        !           212: 
        !           213:        if(i==0) 
        !           214:                return(TRUE);
        !           215: 
        !           216:        if(wr_p!=NULL && FD_ISSET(sock,wr_set_p)) {
        !           217:                *wr_p=TRUE;
        !           218:                if(i==1)
        !           219:                        return(TRUE);
        !           220:        }
        !           221: 
        !           222:        if(rd_p !=NULL || wr_p==NULL)  {
        !           223:                rd=recv(sock,&ch,1,MSG_PEEK);
        !           224:                if(rd==1 
        !           225:                        || (rd==SOCKET_ERROR && ERROR_VALUE==EMSGSIZE)) {
        !           226:                        if(rd_p!=NULL)
        !           227:                                *rd_p=TRUE;
        !           228:                        return(TRUE);
        !           229:                }
        !           230:        }
        !           231: 
        !           232:        return(FALSE);
        !           233: }
        !           234: 
        !           235: int retry_bind(SOCKET s, const struct sockaddr *addr, socklen_t addrlen
        !           236:                           ,uint retries, uint wait_secs
        !           237:                           ,const char* prot
        !           238:                           ,int (*lprintf)(int level, char *fmt, ...))
        !           239: {
        !           240:        char    port_str[128];
        !           241:        int             result=-1;
        !           242:        uint    i;
        !           243: 
        !           244:        if(addr->sa_family==AF_INET)
        !           245:                SAFEPRINTF(port_str," to port %u",ntohs(((SOCKADDR_IN *)(addr))->sin_port)); 
        !           246:        else
        !           247:                port_str[0]=0;
        !           248:        for(i=0;i<=retries;i++) {
        !           249:                if((result=bind(s,addr,addrlen))==0)
        !           250:                        break;
        !           251:                if(lprintf!=NULL)
        !           252:                        lprintf(i<retries ? LOG_WARNING:LOG_ERR
        !           253:                                ,"%04d !ERROR %d binding %s socket%s", s, ERROR_VALUE, prot, port_str);
        !           254:                if(i<retries) {
        !           255:                        if(lprintf!=NULL)
        !           256:                                lprintf(LOG_WARNING,"%04d Will retry in %u seconds (%u of %u)"
        !           257:                                        ,s, wait_secs, i+1, retries);
        !           258:                        SLEEP(wait_secs*1000);
        !           259:                }
        !           260:        }
        !           261:        return(result);
        !           262: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.