Annotation of sbbs/sbbs3/misc.c, revision 1.1.1.1

1.1       root        1: /* misc.cpp */
                      2: 
                      3: /* Synchronet miscellaneous utility-type routines (exported) */
                      4: 
                      5: /* $Id: misc.c,v 1.9 2000/11/14 01:58:37 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 2000 Rob Swindell - http://www.synchro.net/copyright.html         *
                     12:  *                                                                                                                                                     *
                     13:  * This program is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU 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 General Public License for more details: gpl.txt or                     *
                     18:  * http://www.fsf.org/copyleft/gpl.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 "sbbs.h"
                     39: #include "crc32.h"
                     40: 
                     41: /****************************************************************************/
                     42: /* Network open function. Opens all files DENYALL and retries LOOP_NOPEN    */
                     43: /* number of times if the attempted file is already open or denying access  */
                     44: /* for some other reason.      All files are opened in BINARY mode.                    */
                     45: /****************************************************************************/
                     46: int nopen(char *str, int access)
                     47: {
                     48:        int file,share,count=0;
                     49: 
                     50:     if(access&O_DENYNONE) {
                     51:         share=SH_DENYNO;
                     52:         access&=~O_DENYNONE; }
                     53:     else if(access==O_RDONLY) share=SH_DENYWR;
                     54:     else share=SH_DENYRW;
                     55:     while(((file=sopen(str,O_BINARY|access,share))==-1)
                     56:         && errno==EACCES && count++<LOOP_NOPEN)
                     57:         if(count>10)
                     58:             mswait(55);
                     59:     return(file);
                     60: }
                     61: /****************************************************************************/
                     62: /* This function performs an nopen, but returns a file stream with a buffer */
                     63: /* allocated.                                                                                                                          */
                     64: /****************************************************************************/
                     65: FILE * fnopen(int *fd, char *str, int access)
                     66: {
                     67:        char    mode[128];
                     68:        int             file;
                     69:        FILE *  stream;
                     70: 
                     71:     if((file=nopen(str,access))==-1)
                     72:         return(NULL);
                     73: 
                     74:     if(fd!=NULL)
                     75:         *fd=file;
                     76: 
                     77:     if(access&O_APPEND) {
                     78:         if(access&O_RDONLY)
                     79:             strcpy(mode,"a+");
                     80:         else
                     81:             strcpy(mode,"a"); 
                     82:        } else if(access&O_CREAT) {
                     83:                if(access&O_TRUNC)
                     84:                        strcpy(mode,"w");
                     85:                else
                     86:                        strcpy(mode,"w+");
                     87:        } else {
                     88:         if(access&O_WRONLY || (access&O_RDWR)==O_RDWR)
                     89:             strcpy(mode,"r+");
                     90:         else
                     91:             strcpy(mode,"r"); 
                     92:        }
                     93:     stream=fdopen(file,mode);
                     94:     if(stream==NULL) {
                     95:         close(file);
                     96:         return(NULL); 
                     97:        }
                     98:     setvbuf(stream,NULL,_IOFBF,FNOPEN_BUF_SIZE);
                     99:     return(stream);
                    100: }
                    101: 
                    102: /****************************************************************************/
                    103: /* Returns the number of characters in 'str' not counting ctrl-ax codes                */
                    104: /* or the null terminator                                                                                                      */
                    105: /****************************************************************************/
                    106: int bstrlen(char *str)
                    107: {
                    108:        int i=0;
                    109: 
                    110:        while(*str) {
                    111:                if(*str==1) /* ctrl-a */
                    112:                        str++;
                    113:                else
                    114:                        i++;
                    115:                if(!(*str)) break;
                    116:                str++; }
                    117:        return(i);
                    118: }
                    119: 
                    120: void strip_ctrl(char *str)
                    121: {
                    122:        char tmp[1024];
                    123:        int i,j,k;
                    124: 
                    125:        k=strlen(str);
                    126:        for(i=j=0;i<k;i++)
                    127:                if(str[i]==1)  /* Ctrl-a */
                    128:                        i++;
                    129:                else if(j && str[i]<=SP && tmp[j-1]==SP)
                    130:                        continue;
                    131:                else if(i && !isalnum(str[i]) && str[i]==str[i-1])
                    132:                        continue;
                    133:                else if((uchar)str[i]>=SP)
                    134:                        tmp[j++]=str[i];
                    135:                else if(str[i]==TAB || (str[i]==CR && str[i+1]==LF))
                    136:                        tmp[j++]=SP;
                    137:        tmp[j]=0;
                    138:        strcpy(str,tmp);
                    139: }
                    140: 
                    141: void strip_exascii(char *str)
                    142: {
                    143:        char tmp[1024];
                    144:        int i,j,k;
                    145: 
                    146:        k=strlen(str);
                    147:        for(i=j=0;i<k;i++)
                    148:                if(!(str[i]&0x80))
                    149:                        tmp[j++]=str[i];
                    150:        tmp[j]=0;
                    151:        strcpy(str,tmp);
                    152: }
                    153: 
                    154: /****************************************************************************/
                    155: /* Returns in 'string' a character representation of the number in l with   */
                    156: /* commas.                                                                                                                                     */
                    157: /****************************************************************************/
                    158: char *ultoac(ulong l, char *string)
                    159: {
                    160:        char str[256];
                    161:        char i,j,k;
                    162: 
                    163:        ultoa(l,str,10);
                    164:        i=strlen(str)-1;
                    165:        j=i/3+1+i;
                    166:        string[j--]=0;
                    167:        for(k=1;i>-1;k++) {
                    168:                string[j--]=str[i--];
                    169:                if(j>0 && !(k%3))
                    170:                        string[j--]=','; }
                    171:        return(string);
                    172: }
                    173: 
                    174: /****************************************************************************/
                    175: /* Truncates white-space chars off end of 'str'                                                                */
                    176: /****************************************************************************/
                    177: void truncsp(char *str)
                    178: {
                    179:        uint c;
                    180: 
                    181: #if 0  /* no longer terminates at first tab OCT-09-2000 rswindell */
                    182:        str[strcspn(str,"\t")]=0;
                    183: #endif
                    184:        c=strlen(str);
                    185:        while(c && (uchar)str[c-1]<=SP) c--;
                    186:        str[c]=0;
                    187: }
                    188: 
                    189: /****************************************************************************/
                    190: /* Puts a backslash on path strings                                                                            */
                    191: /****************************************************************************/
                    192: void backslash(char *str)
                    193: {
                    194:     int i;
                    195: 
                    196:        i=strlen(str);
                    197:        if(i && str[i-1]!='\\' && str[i-1]!='/') {
                    198:                str[i]=BACKSLASH; 
                    199:                str[i+1]=0; 
                    200:        }
                    201: }
                    202: 
                    203: /****************************************************************************/
                    204: /* Puts a backslash on path strings if not just a drive letter and colon       */
                    205: /****************************************************************************/
                    206: void backslashcolon(char *str)
                    207: {
                    208:     int i;
                    209: 
                    210:        i=strlen(str);
                    211:        if(i && str[i-1]!='\\' && str[i-1]!='/' && str[i-1]!=':') {
                    212:                str[i]=BACKSLASH; 
                    213:                str[i+1]=0; 
                    214:        }
                    215: }
                    216: 
                    217: /****************************************************************************/
                    218: /* Updates 16-bit "rcrc" with character 'ch'                                */
                    219: /****************************************************************************/
                    220: void ucrc16(uchar ch, ushort *rcrc) 
                    221: {
                    222:        ushort i, cy;
                    223:     uchar nch=ch;
                    224:  
                    225:        for (i=0; i<8; i++) {
                    226:                cy=*rcrc & 0x8000;
                    227:                *rcrc<<=1;
                    228:                if (nch & 0x80) *rcrc |= 1;
                    229:                nch<<=1;
                    230:                if (cy) *rcrc ^= 0x1021; }
                    231: }
                    232: 
                    233: /****************************************************************************/
                    234: /* Returns CRC-16 of string (not including terminating NULL)                           */
                    235: /****************************************************************************/
                    236: ushort DLLCALL crc16(char *str)
                    237: {
                    238:        int     i=0;
                    239:        ushort  crc=0;
                    240: 
                    241:        ucrc16(0,&crc);
                    242:        while(str[i])
                    243:                ucrc16(str[i++],&crc);
                    244:        ucrc16(0,&crc);
                    245:        ucrc16(0,&crc);
                    246:        return(crc);
                    247: }
                    248: 
                    249: /****************************************************************************/
                    250: /* Returns CRC-32 of string (not including terminating NULL)                           */
                    251: /****************************************************************************/
                    252: ulong crc32(char *buf, ulong len)
                    253: {
                    254:        ulong l,crc=0xffffffff;
                    255: 
                    256:        for(l=0;l<len;l++)
                    257:                crc=ucrc32(buf[l],crc);
                    258:        return(~crc);
                    259: }
                    260: 
                    261: /****************************************************************************/
                    262: /* Compares pointers to pointers to char. Used in conjuction with qsort()   */
                    263: /****************************************************************************/
                    264: int pstrcmp(char **str1, char **str2)
                    265: {
                    266:        return(strcmp(*str1,*str2));
                    267: }
                    268: 
                    269: /****************************************************************************/
                    270: /* Returns the number of characters that are the same between str1 and str2 */
                    271: /****************************************************************************/
                    272: int strsame(char *str1, char *str2)
                    273: {
                    274:        int i,j=0;
                    275: 
                    276:        for(i=0;str1[i];i++)
                    277:                if(str1[i]==str2[i]) j++;
                    278:        return(j);
                    279: }
                    280: 
                    281: #define MV_BUFLEN      4096
                    282: 
                    283: /****************************************************************************/
                    284: /* Converts when_t.zone into ASCII format                                   */
                    285: /****************************************************************************/
                    286: char* DLLCALL zonestr(short zone)
                    287: {
                    288:     static char str[32];
                    289: 
                    290:        switch((ushort)zone) {
                    291:                case 0:     return("UT");
                    292:                case AST:   return("AST");
                    293:                case EST:   return("EST");
                    294:                case CST:   return("CST");
                    295:                case MST:   return("MST");
                    296:                case PST:   return("PST");
                    297:                case YST:   return("YST");
                    298:                case HST:   return("HST");
                    299:                case BST:   return("BST");
                    300:                case ADT:   return("ADT");
                    301:                case EDT:   return("EDT");
                    302:                case CDT:   return("CDT");
                    303:                case MDT:   return("MDT");
                    304:                case PDT:   return("PDT");
                    305:                case YDT:   return("YDT");
                    306:                case HDT:   return("HDT");
                    307:                case BDT:   return("BDT");
                    308:                case MID:   return("MID");
                    309:                case VAN:   return("VAN");
                    310:                case EDM:   return("EDM");
                    311:                case WIN:   return("WIN");
                    312:                case BOG:   return("BOG");
                    313:                case CAR:   return("CAR");
                    314:                case RIO:   return("RIO");
                    315:                case FER:   return("FER");
                    316:                case AZO:   return("AZO");
                    317:                case LON:   return("LON");
                    318:                case BER:   return("BER");
                    319:                case ATH:   return("ATH");
                    320:                case MOS:   return("MOS");
                    321:                case DUB:   return("DUB");
                    322:                case KAB:   return("KAB");
                    323:                case KAR:   return("KAR");
                    324:                case BOM:   return("BOM");
                    325:                case KAT:   return("KAT");
                    326:                case DHA:   return("DHA");
                    327:                case BAN:   return("BAN");
                    328:                case HON:   return("HON");
                    329:                case TOK:   return("TOK");
                    330:                case SYD:   return("SYD");
                    331:                case NOU:   return("NOU");
                    332:                case WEL:   return("WEL");
                    333:                }
                    334: 
                    335:        sprintf(str,"%02d:%02u",zone/60,zone<0 ? (-zone)%60 : zone%60);
                    336:        return(str);
                    337: }
                    338: 
                    339: 
                    340: /****************************************************************************/
                    341: /* Returns an ASCII string for FidoNet address 'addr'                       */
                    342: /****************************************************************************/
                    343: char *faddrtoa(faddr_t addr)
                    344: {
                    345:     static char str[25];
                    346:     char point[25];
                    347: 
                    348:        sprintf(str,"%u:%u/%u",addr.zone,addr.net,addr.node);
                    349:        if(addr.point) {
                    350:                sprintf(point,".%u",addr.point);
                    351:                strcat(str,point); }
                    352:        return(str);
                    353: }
                    354: 
                    355: /****************************************************************************/
                    356: /* Returns string for 2 digit hex+ numbers up to 575                                           */
                    357: /****************************************************************************/
                    358: char *hexplus(uint num, char *str)
                    359: {
                    360:        sprintf(str,"%03x",num);
                    361:        str[0]=num/0x100 ? 'f'+(num/0x10)-0xf : str[1];
                    362:        str[1]=str[2];
                    363:        str[2]=0;
                    364:        return(str);
                    365: }
                    366: 
                    367: uint hptoi(char *str)
                    368: {
                    369:        char tmp[128];
                    370:        uint i;
                    371: 
                    372:        if(!str[1] || toupper(str[0])<='F')
                    373:                return(ahtoul(str));
                    374:        strcpy(tmp,str);
                    375:        tmp[0]='F';
                    376:        i=ahtoul(tmp)+((toupper(str[0])-'F')*0x10);
                    377:        return(i);
                    378: }
                    379: 
                    380: /****************************************************************************/
                    381: /* Converts an ASCII Hex string into an ulong                               */
                    382: /****************************************************************************/
                    383: ulong ahtoul(char *str)
                    384: {
                    385:     ulong l,val=0;
                    386: 
                    387:        while((l=(*str++)|0x20)!=0x20)
                    388:                val=(l&0xf)+(l>>6&1)*9+val*16;
                    389:        return(val);
                    390: }
                    391: 

unix.superglobalmegacorp.com

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