|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.