|
|
1.1 ! root 1: #line 1 "MISC.C" ! 2: ! 3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ ! 4: ! 5: /***************************************************************************/ ! 6: /* Miscellaneous functions that are useful many places throughout the code */ ! 7: /***************************************************************************/ ! 8: ! 9: #include "sbbs.h" ! 10: #include "crc32.h" ! 11: ! 12: #ifdef __WIN32__ ! 13: #include <windows.h> // Required for kbd_state(), beep(), and mswait() ! 14: #endif ! 15: ! 16: /****************************************************************************/ ! 17: /* Returns the number of characters in 'str' not counting ctrl-ax codes */ ! 18: /* or the null terminator */ ! 19: /****************************************************************************/ ! 20: int bstrlen(char *str) ! 21: { ! 22: int i=0; ! 23: ! 24: while(*str) { ! 25: if(*str==1) /* ctrl-a */ ! 26: str++; ! 27: else ! 28: i++; ! 29: if(!(*str)) break; ! 30: str++; } ! 31: return(i); ! 32: } ! 33: ! 34: void strip_ctrl(char *str) ! 35: { ! 36: char tmp[1024]; ! 37: int i,j,k; ! 38: ! 39: k=strlen(str); ! 40: for(i=j=0;i<k;i++) ! 41: if(str[i]==1) /* Ctrl-a */ ! 42: i++; ! 43: else if(j && str[i]<=SP && tmp[j-1]==SP) ! 44: continue; ! 45: else if(i && !isalnum(str[i]) && str[i]==str[i-1]) ! 46: continue; ! 47: else if((uchar)str[i]>=SP) ! 48: tmp[j++]=str[i]; ! 49: else if(str[i]==TAB || (str[i]==CR && str[i+1]==LF)) ! 50: tmp[j++]=SP; ! 51: tmp[j]=0; ! 52: strcpy(str,tmp); ! 53: } ! 54: ! 55: void strip_exascii(char *str) ! 56: { ! 57: char tmp[1024]; ! 58: int i,j,k; ! 59: ! 60: k=strlen(str); ! 61: for(i=j=0;i<k;i++) ! 62: if(!(str[i]&0x80)) ! 63: tmp[j++]=str[i]; ! 64: tmp[j]=0; ! 65: strcpy(str,tmp); ! 66: } ! 67: ! 68: /****************************************************************************/ ! 69: /* Returns in 'string' a character representation of the number in l with */ ! 70: /* commas. */ ! 71: /****************************************************************************/ ! 72: char *ultoac(ulong l, char *string) ! 73: { ! 74: char str[256]; ! 75: char i,j,k; ! 76: ! 77: ultoa(l,str,10); ! 78: i=strlen(str)-1; ! 79: j=i/3+1+i; ! 80: string[j--]=0; ! 81: for(k=1;i>-1;k++) { ! 82: string[j--]=str[i--]; ! 83: if(j>0 && !(k%3)) ! 84: string[j--]=','; } ! 85: return(string); ! 86: } ! 87: ! 88: /****************************************************************************/ ! 89: /* Network open function. Opens all files DENYALL and retries LOOP_NOPEN */ ! 90: /* number of times if the attempted file is already open or denying access */ ! 91: /* for some other reason. All files are opened in BINARY mode. */ ! 92: /****************************************************************************/ ! 93: int nopen(char *str, int access) ! 94: { ! 95: char logstr[256]; ! 96: int file,share,count=0; ! 97: ! 98: if(access&O_DENYNONE) { ! 99: share=SH_DENYNO; ! 100: access&=~O_DENYNONE; } ! 101: else if(access==O_RDONLY) share=SH_DENYWR; ! 102: else share=SH_DENYRW; ! 103: while(((file=sopen(str,O_BINARY|access,share,S_IWRITE))==-1) ! 104: && errno==EACCES && count++<LOOP_NOPEN) ! 105: if(count>10) ! 106: mswait(55); ! 107: if(count>(LOOP_NOPEN/2) && count<=LOOP_NOPEN) { ! 108: sprintf(logstr,"NOPEN COLLISION - File: %s Count: %d" ! 109: ,str,count); ! 110: logline("!!",logstr); } ! 111: if(file==-1 && errno==EACCES) ! 112: bputs("\7\r\nNOPEN: ACCESS DENIED\r\n\7"); ! 113: return(file); ! 114: } ! 115: ! 116: /****************************************************************************/ ! 117: /* This function performs an nopen, but returns a file stream with a buffer */ ! 118: /* allocated. */ ! 119: /****************************************************************************/ ! 120: FILE *fnopen(int *file, char *str, int access) ! 121: { ! 122: char mode[128]; ! 123: FILE *stream; ! 124: ! 125: if(((*file)=nopen(str,access))==-1) ! 126: return(NULL); ! 127: ! 128: if(access&O_APPEND) { ! 129: if(access&O_RDONLY) ! 130: strcpy(mode,"a+"); ! 131: else ! 132: strcpy(mode,"a"); } ! 133: else { ! 134: if(access&O_WRONLY) ! 135: strcpy(mode,"r+"); ! 136: else ! 137: strcpy(mode,"r"); } ! 138: stream=fdopen((*file),mode); ! 139: if(stream==NULL) { ! 140: close(*file); ! 141: errormsg(WHERE,ERR_FDOPEN,str,access); ! 142: return(NULL); } ! 143: setvbuf(stream,NULL,_IOFBF,2*1024); ! 144: return(stream); ! 145: } ! 146: ! 147: #ifndef __FLAT__ ! 148: /****************************************************************************/ ! 149: /* This function reads files that are potentially larger than 32k. */ ! 150: /* Up to one megabyte of data can be read with each call. */ ! 151: /****************************************************************************/ ! 152: long lread(int file, char huge *buf,long bytes) ! 153: { ! 154: long count; ! 155: ! 156: for(count=bytes;count>32767;count-=32767,buf+=32767) ! 157: if(read(file,(char *)buf,32767)!=32767) ! 158: return(-1L); ! 159: if(read(file,(char *)buf,(int)count)!=count) ! 160: return(-1L); ! 161: return(bytes); ! 162: } ! 163: ! 164: long lfread(char huge *buf, long bytes, FILE *fp) ! 165: { ! 166: long count; ! 167: ! 168: for(count=bytes;count>0x7fff;count-=0x7fff,buf+=0x7fff) ! 169: if(fread((char *)buf,1,0x7fff,fp)!=0x7fff) ! 170: return(0); ! 171: if(fread((char *)buf,1,(int)count,fp)!=count) ! 172: return(0); ! 173: return(bytes); ! 174: } ! 175: ! 176: /****************************************************************************/ ! 177: /* This function writes files that are potentially larger than 32767 bytes */ ! 178: /* Up to one megabytes of data can be written with each call. */ ! 179: /****************************************************************************/ ! 180: long lwrite(int file, char huge *buf, long bytes) ! 181: { ! 182: ! 183: long count; ! 184: ! 185: for(count=bytes;count>32767;count-=32767,buf+=32767) ! 186: if(write(file,(char *)buf,32767)!=32767) ! 187: return(-1L); ! 188: if(write(file,(char *)buf,(int)count)!=count) ! 189: return(-1L); ! 190: return(bytes); ! 191: } ! 192: #endif ! 193: ! 194: /****************************************************************************/ ! 195: /* Truncates white-space chars off end of 'str' and terminates at first tab */ ! 196: /****************************************************************************/ ! 197: void truncsp(char *str) ! 198: { ! 199: uint c; ! 200: ! 201: str[strcspn(str,"\t")]=0; ! 202: c=strlen(str); ! 203: while(c && (uchar)str[c-1]<=SP) c--; ! 204: str[c]=0; ! 205: } ! 206: ! 207: /****************************************************************************/ ! 208: /* Puts a backslash on path strings */ ! 209: /****************************************************************************/ ! 210: void backslash(char *str) ! 211: { ! 212: int i; ! 213: ! 214: i=strlen(str); ! 215: if(i && str[i-1]!='\\') { ! 216: str[i]='\\'; str[i+1]=0; } ! 217: } ! 218: ! 219: /****************************************************************************/ ! 220: /* Puts a backslash on path strings if not just a drive letter and colon */ ! 221: /****************************************************************************/ ! 222: void backslashcolon(char *str) ! 223: { ! 224: int i; ! 225: ! 226: i=strlen(str); ! 227: if(i && str[i-1]!='\\' && str[i-1]!=':') { ! 228: str[i]='\\'; str[i+1]=0; } ! 229: } ! 230: ! 231: /****************************************************************************/ ! 232: /* Updates 16-bit "rcrc" with character 'ch' */ ! 233: /****************************************************************************/ ! 234: void ucrc16(uchar ch, ushort *rcrc) { ! 235: ushort i, cy; ! 236: uchar nch=ch; ! 237: ! 238: for (i=0; i<8; i++) { ! 239: cy=*rcrc & 0x8000; ! 240: *rcrc<<=1; ! 241: if (nch & 0x80) *rcrc |= 1; ! 242: nch<<=1; ! 243: if (cy) *rcrc ^= 0x1021; } ! 244: } ! 245: ! 246: /****************************************************************************/ ! 247: /* Returns CRC-16 of string (not including terminating NULL) */ ! 248: /****************************************************************************/ ! 249: ushort crc16(char *str) ! 250: { ! 251: int i=0; ! 252: ushort crc=0; ! 253: ! 254: ucrc16(0,&crc); ! 255: while(str[i]) ! 256: ucrc16(str[i++],&crc); ! 257: ucrc16(0,&crc); ! 258: ucrc16(0,&crc); ! 259: return(crc); ! 260: } ! 261: ! 262: /****************************************************************************/ ! 263: /* Returns CRC-32 of string (not including terminating NULL) */ ! 264: /****************************************************************************/ ! 265: ulong crc32(char *buf, ulong len) ! 266: { ! 267: ulong l,crc=0xffffffff; ! 268: ! 269: for(l=0;l<len;l++) ! 270: crc=ucrc32(buf[l],crc); ! 271: return(~crc); ! 272: } ! 273: ! 274: /****************************************************************************/ ! 275: /* Compares pointers to pointers to char. Used in conjuction with qsort() */ ! 276: /****************************************************************************/ ! 277: int pstrcmp(char **str1, char **str2) ! 278: { ! 279: return(strcmp(*str1,*str2)); ! 280: } ! 281: ! 282: /****************************************************************************/ ! 283: /* Returns the number of characters that are the same between str1 and str2 */ ! 284: /****************************************************************************/ ! 285: int strsame(char *str1, char *str2) ! 286: { ! 287: int i,j=0; ! 288: ! 289: for(i=0;i<strlen(str1);i++) ! 290: if(str1[i]==str2[i]) j++; ! 291: return(j); ! 292: } ! 293: ! 294: #define MV_BUFLEN 4096 ! 295: ! 296: /****************************************************************************/ ! 297: /* Moves or copies a file from one dir to another */ ! 298: /* both 'src' and 'dest' must contain full path and filename */ ! 299: /* returns 0 if successful, -1 if error */ ! 300: /****************************************************************************/ ! 301: int mv(char *src, char *dest, char copy) ! 302: { ! 303: char str[256],*buf,atr=curatr; ! 304: int ind,outd; ! 305: long length,chunk=MV_BUFLEN,l; ! 306: struct ftime ftime; ! 307: FILE *inp,*outp; ! 308: ! 309: if(!stricmp(src,dest)) /* source and destination are the same! */ ! 310: return(0); ! 311: if(!fexist(src)) { ! 312: bprintf("\r\n\7MV ERROR: Source doesn't exist\r\n'%s'\r\n" ! 313: ,src); ! 314: return(-1); } ! 315: if(!copy && fexist(dest)) { ! 316: bprintf("\r\n\7MV ERROR: Destination already exists\r\n'%s'\r\n" ! 317: ,dest); ! 318: return(-1); } ! 319: if(!copy && ((src[1]!=':' && dest[1]!=':') ! 320: || (src[1]==':' && dest[1]==':' && toupper(src[0])==toupper(dest[0])))) { ! 321: if(rename(src,dest)) { /* same drive, so move */ ! 322: bprintf("\r\nMV ERROR: Error renaming '%s'" ! 323: "\r\n to '%s'\r\n\7",src,dest); ! 324: return(-1); } ! 325: return(0); } ! 326: attr(WHITE); ! 327: if((ind=nopen(src,O_RDONLY))==-1) { ! 328: errormsg(WHERE,ERR_OPEN,src,O_RDONLY); ! 329: return(-1); } ! 330: if((inp=fdopen(ind,"rb"))==NULL) { ! 331: close(ind); ! 332: errormsg(WHERE,ERR_FDOPEN,str,O_RDONLY); ! 333: return(-1); } ! 334: setvbuf(inp,NULL,_IOFBF,32*1024); ! 335: if((outd=nopen(dest,O_WRONLY|O_CREAT|O_TRUNC))==-1) { ! 336: fclose(inp); ! 337: errormsg(WHERE,ERR_OPEN,dest,O_WRONLY|O_CREAT|O_TRUNC); ! 338: return(-1); } ! 339: if((outp=fdopen(outd,"wb"))==NULL) { ! 340: close(outd); ! 341: fclose(inp); ! 342: errormsg(WHERE,ERR_FDOPEN,dest,O_WRONLY|O_CREAT|O_TRUNC); ! 343: return(-1); } ! 344: setvbuf(outp,NULL,_IOFBF,8*1024); ! 345: length=filelength(ind); ! 346: if(!length) { ! 347: fclose(inp); ! 348: fclose(outp); ! 349: errormsg(WHERE,ERR_LEN,src,0); ! 350: return(-1); } ! 351: if((buf=(char *)MALLOC(MV_BUFLEN))==NULL) { ! 352: fclose(inp); ! 353: fclose(outp); ! 354: errormsg(WHERE,ERR_ALLOC,nulstr,MV_BUFLEN); ! 355: return(-1); } ! 356: l=0L; ! 357: while(l<length) { ! 358: bprintf("%2lu%%",l ? (long)(100.0/((float)length/l)) : 0L); ! 359: if(l+chunk>length) ! 360: chunk=length-l; ! 361: if(fread(buf,1,chunk,inp)!=chunk) { ! 362: FREE(buf); ! 363: fclose(inp); ! 364: fclose(outp); ! 365: errormsg(WHERE,ERR_READ,src,chunk); ! 366: return(-1); } ! 367: if(fwrite(buf,1,chunk,outp)!=chunk) { ! 368: FREE(buf); ! 369: fclose(inp); ! 370: fclose(outp); ! 371: errormsg(WHERE,ERR_WRITE,dest,chunk); ! 372: return(-1); } ! 373: l+=chunk; ! 374: bputs("\b\b\b"); } ! 375: bputs(" \b\b\b"); /* erase it */ ! 376: attr(atr); ! 377: getftime(ind,&ftime); ! 378: setftime(outd,&ftime); ! 379: FREE(buf); ! 380: fclose(inp); ! 381: fclose(outp); ! 382: if(!copy && remove(src)) { ! 383: errormsg(WHERE,ERR_REMOVE,src,0); ! 384: return(-1); } ! 385: return(0); ! 386: } ! 387: ! 388: /****************************************************************************/ ! 389: /* Prompts user for System Password. Returns 1 if user entered correct PW */ ! 390: /****************************************************************************/ ! 391: char chksyspass(int local) ! 392: { ! 393: static int inside; ! 394: char str[256],str2[256],x,y,atr; ! 395: int orgcon=console; ! 396: ! 397: if(inside) return(0); ! 398: if(online==ON_REMOTE && !(sys_misc&SM_R_SYSOP)) ! 399: return(0); ! 400: if(online==ON_LOCAL) { ! 401: if(!(sys_misc&SM_L_SYSOP)) ! 402: return(0); ! 403: if(!(node_misc&NM_SYSPW) && !(sys_misc&SM_REQ_PW)) ! 404: return(1); } ! 405: if(local) { ! 406: x=lclwx(); ! 407: y=lclwy(); ! 408: atr=lclatr(LIGHTGRAY<<4); ! 409: STATUSLINE; ! 410: lclxy(1,node_scrnlen); ! 411: lputc(CLREOL); ! 412: lputs(" System Password: "); } ! 413: else ! 414: bputs("SY: "); ! 415: console&=~(CON_R_ECHO|CON_L_ECHO); ! 416: inside=1; ! 417: getstr(str,40,K_UPPER); ! 418: if(local) { ! 419: TEXTWINDOW; ! 420: lclatr(atr); ! 421: lclxy(x,y); ! 422: statusline(); } ! 423: inside=0; ! 424: console=orgcon; ! 425: if(!local) ! 426: CRLF; ! 427: if(strcmp(sys_pass,str)) { ! 428: sprintf(str2,"%s #%u System password attempt: '%s'" ! 429: ,useron.alias,useron.number,str); ! 430: logline("S!",str2); ! 431: return(0); } ! 432: return(1); ! 433: } ! 434: ! 435: /****************************************************************************/ ! 436: /* Converts when_t.zone into ASCII format */ ! 437: /****************************************************************************/ ! 438: char *zonestr(short zone) ! 439: { ! 440: static char str[32]; ! 441: ! 442: switch((ushort)zone) { ! 443: case 0: return("UT"); ! 444: case AST: return("AST"); ! 445: case EST: return("EST"); ! 446: case CST: return("CST"); ! 447: case MST: return("MST"); ! 448: case PST: return("PST"); ! 449: case YST: return("YST"); ! 450: case HST: return("HST"); ! 451: case BST: return("BST"); ! 452: case ADT: return("ADT"); ! 453: case EDT: return("EDT"); ! 454: case CDT: return("CDT"); ! 455: case MDT: return("MDT"); ! 456: case PDT: return("PDT"); ! 457: case YDT: return("YDT"); ! 458: case HDT: return("HDT"); ! 459: case BDT: return("BDT"); ! 460: case MID: return("MID"); ! 461: case VAN: return("VAN"); ! 462: case EDM: return("EDM"); ! 463: case WIN: return("WIN"); ! 464: case BOG: return("BOG"); ! 465: case CAR: return("CAR"); ! 466: case RIO: return("RIO"); ! 467: case FER: return("FER"); ! 468: case AZO: return("AZO"); ! 469: case LON: return("LON"); ! 470: case BER: return("BER"); ! 471: case ATH: return("ATH"); ! 472: case MOS: return("MOS"); ! 473: case DUB: return("DUB"); ! 474: case KAB: return("KAB"); ! 475: case KAR: return("KAR"); ! 476: case BOM: return("BOM"); ! 477: case KAT: return("KAT"); ! 478: case DHA: return("DHA"); ! 479: case BAN: return("BAN"); ! 480: case HON: return("HON"); ! 481: case TOK: return("TOK"); ! 482: case SYD: return("SYD"); ! 483: case NOU: return("NOU"); ! 484: case WEL: return("WEL"); ! 485: } ! 486: ! 487: sprintf(str,"%02d:%02u",zone/60,zone<0 ? (-zone)%60 : zone%60); ! 488: return(str); ! 489: } ! 490: ! 491: /****************************************************************************/ ! 492: /* Waits so many seconds. Call with 2 or greater. */ ! 493: /****************************************************************************/ ! 494: void secwait(int sec) ! 495: { ! 496: time_t start; ! 497: ! 498: start=time(NULL); ! 499: while(time(NULL)-start<sec) ! 500: mswait(1); ! 501: } ! 502: ! 503: /****************************************************************************/ ! 504: /* Converts a date string in format MM/DD/YY into unix time format */ ! 505: /****************************************************************************/ ! 506: time_t dstrtounix(char *str) ! 507: { ! 508: ! 509: if(!strncmp(str,"00/00/00",8)) ! 510: return(0); ! 511: curtime.ti_hour=curtime.ti_min=curtime.ti_sec=0; ! 512: if(str[6]<'7') ! 513: date.da_year=2000+((str[6]&0xf)*10)+(str[7]&0xf); ! 514: else ! 515: date.da_year=1900+((str[6]&0xf)*10)+(str[7]&0xf); ! 516: if(sys_misc&SM_EURODATE) { ! 517: date.da_mon=((str[3]&0xf)*10)+(str[4]&0xf); ! 518: date.da_day=((str[0]&0xf)*10)+(str[1]&0xf); } ! 519: else { ! 520: date.da_mon=((str[0]&0xf)*10)+(str[1]&0xf); ! 521: date.da_day=((str[3]&0xf)*10)+(str[4]&0xf); } ! 522: return(dostounix(&date,&curtime)); ! 523: } ! 524: ! 525: /****************************************************************************/ ! 526: /* Converts unix time format (long - time_t) into a char str MM/DD/YY */ ! 527: /****************************************************************************/ ! 528: char *unixtodstr(time_t unix, char *str) ! 529: { ! 530: ! 531: if(!unix) ! 532: strcpy(str,"00/00/00"); ! 533: else { ! 534: unixtodos(unix,&date,&curtime); ! 535: if((unsigned)date.da_mon>12) { /* DOS leap year bug */ ! 536: date.da_mon=1; ! 537: date.da_year++; } ! 538: if((unsigned)date.da_day>31) ! 539: date.da_day=1; ! 540: if(sys_misc&SM_EURODATE) ! 541: sprintf(str,"%02u/%02u/%02u",date.da_day,date.da_mon ! 542: ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900); ! 543: else ! 544: sprintf(str,"%02u/%02u/%02u",date.da_mon,date.da_day ! 545: ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900); } ! 546: return(str); ! 547: } ! 548: ! 549: /****************************************************************************/ ! 550: /* Checks the disk drive for the existence of a file. Returns 1 if it */ ! 551: /* exists, 0 if it doesn't. */ ! 552: /****************************************************************************/ ! 553: char fexist(char *filespec) ! 554: { ! 555: struct ffblk f; ! 556: ! 557: if(findfirst(filespec,&f,0 /*FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_DIREC */)==0) ! 558: return(1); ! 559: return(0); ! 560: } ! 561: ! 562: /****************************************************************************/ ! 563: /* Returns the length of the file in 'filespec' */ ! 564: /****************************************************************************/ ! 565: long flength(char *filespec) ! 566: { ! 567: struct ffblk f; ! 568: ! 569: if(findfirst(filespec,&f,0)==0) ! 570: return(f.ff_fsize); ! 571: return(-1L); ! 572: } ! 573: ! 574: time_t ftimetounix(struct ftime ft) ! 575: { ! 576: struct date da; ! 577: struct time ti; ! 578: ! 579: ti.ti_min=ft.ft_min; ! 580: ti.ti_hour=ft.ft_hour; ! 581: ti.ti_hund=0; ! 582: ti.ti_sec=ft.ft_tsec*2; ! 583: da.da_year=1980+ft.ft_year; ! 584: da.da_day=ft.ft_day; ! 585: da.da_mon=ft.ft_month; ! 586: return(dostounix(&da,&ti)); ! 587: } ! 588: ! 589: struct ftime unixtoftime(time_t unix) ! 590: { ! 591: struct date da; ! 592: struct time ti; ! 593: struct ftime ft; ! 594: ! 595: unixtodos(unix,&da,&ti); ! 596: ft.ft_min=ti.ti_min; ! 597: ft.ft_hour=ti.ti_hour; ! 598: ft.ft_tsec=ti.ti_sec/2; ! 599: ft.ft_year=da.da_year-1980; ! 600: ft.ft_day=da.da_day; ! 601: ft.ft_month=da.da_mon; ! 602: return(ft); ! 603: } ! 604: ! 605: /****************************************************************************/ ! 606: /* Returns the time/date of the file in 'filespec' in time_t (unix) format */ ! 607: /****************************************************************************/ ! 608: long fdate(char *filespec) ! 609: { ! 610: int file; ! 611: struct ftime f; ! 612: time_t t; ! 613: ! 614: if((file=nopen(filespec,O_RDONLY))==-1) ! 615: return(0); ! 616: getftime(file,&f); ! 617: t=ftimetounix(f); ! 618: close(file); ! 619: return(t); ! 620: } ! 621: ! 622: long fdate_dir(char *filespec) ! 623: { ! 624: struct ffblk f; ! 625: struct date fd; ! 626: struct time ft; ! 627: ! 628: if(findfirst(filespec,&f,0/* FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_DIREC */)==0) { ! 629: fd.da_day=f.ff_fdate&0x1f; ! 630: fd.da_mon=(f.ff_fdate>>5)&0xf; ! 631: fd.da_year=1980+((f.ff_fdate>>9)&0x7f); ! 632: ft.ti_hour=(f.ff_ftime>>11)&0x1f; ! 633: ft.ti_min=(f.ff_ftime>>5)&0x3f; ! 634: ft.ti_sec=(f.ff_ftime&0xf)*2; ! 635: return(dostounix(&fd,&ft)); } ! 636: else return(0); ! 637: } ! 638: ! 639: ! 640: ! 641: /****************************************************************************/ ! 642: /* Returns the FidoNet address kept in str as ASCII. */ ! 643: /****************************************************************************/ ! 644: faddr_t atofaddr(char *str) ! 645: { ! 646: char *p; ! 647: faddr_t addr; ! 648: ! 649: addr.zone=addr.net=addr.node=addr.point=0; ! 650: if((p=strchr(str,':'))!=NULL) { ! 651: addr.zone=atoi(str); ! 652: addr.net=atoi(p+1); } ! 653: else { ! 654: if(total_faddrs) ! 655: addr.zone=faddr[0].zone; ! 656: else ! 657: addr.zone=1; ! 658: addr.net=atoi(str); } ! 659: if(!addr.zone) /* no such thing as zone 0 */ ! 660: addr.zone=1; ! 661: if((p=strchr(str,'/'))!=NULL) ! 662: addr.node=atoi(p+1); ! 663: else { ! 664: if(total_faddrs) ! 665: addr.net=faddr[0].net; ! 666: else ! 667: addr.net=1; ! 668: addr.node=atoi(str); } ! 669: if((p=strchr(str,'.'))!=NULL) ! 670: addr.point=atoi(p+1); ! 671: return(addr); ! 672: } ! 673: ! 674: /****************************************************************************/ ! 675: /* Returns an ASCII string for FidoNet address 'addr' */ ! 676: /****************************************************************************/ ! 677: char *faddrtoa(faddr_t addr) ! 678: { ! 679: static char str[25]; ! 680: char point[25]; ! 681: ! 682: sprintf(str,"%u:%u/%u",addr.zone,addr.net,addr.node); ! 683: if(addr.point) { ! 684: sprintf(point,".%u",addr.point); ! 685: strcat(str,point); } ! 686: return(str); ! 687: } ! 688: ! 689: /****************************************************************************/ ! 690: /* Returns string for 2 digit hex+ numbers up to 575 */ ! 691: /****************************************************************************/ ! 692: char *hexplus(uint num, char *str) ! 693: { ! 694: sprintf(str,"%03x",num); ! 695: str[0]=num/0x100 ? 'f'+(num/0x10)-0xf : str[1]; ! 696: str[1]=str[2]; ! 697: str[2]=0; ! 698: return(str); ! 699: } ! 700: ! 701: uint hptoi(char *str) ! 702: { ! 703: char tmp[128]; ! 704: uint i; ! 705: ! 706: if(!str[1] || toupper(str[0])<='F') ! 707: return(ahtoul(str)); ! 708: strcpy(tmp,str); ! 709: tmp[0]='F'; ! 710: i=ahtoul(tmp)+((toupper(str[0])-'F')*0x10); ! 711: return(i); ! 712: } ! 713: ! 714: #ifndef __FLAT__ ! 715: ! 716: void beep(int freq, int dur) ! 717: { ! 718: sound(freq); ! 719: mswait(dur); ! 720: nosound(); ! 721: } ! 722: ! 723: int kbd_state(void) ! 724: { ! 725: return(peekb(0,0x417)); /* Check scroll lock */ ! 726: } ! 727: ! 728: #elif defined(__WIN32__) ! 729: ! 730: void beep(int freq, int dur) ! 731: { ! 732: Beep(freq,dur); // Requires WINDOWS.H ! 733: } ! 734: ! 735: void mswait(int ms) ! 736: { ! 737: Sleep(ms); // Requires WINDOWS.H ! 738: } ! 739: ! 740: #endif ! 741: ! 742: #ifdef __OS2__ ! 743: ! 744: int kbd_state(void) ! 745: { ! 746: KBDINFO info; ! 747: ! 748: KbdGetStatus(&info,0); ! 749: return(info.fsState); ! 750: } ! 751: ! 752: void mswait(int msec) ! 753: { ! 754: DosSleep(msec ? msec : 1); ! 755: } ! 756: ! 757: #elif defined(__WIN32__) ! 758: ! 759: #define KBDSTF_RIGHTSHIFT 0x0001 ! 760: #define KBDSTF_LEFTSHIFT 0x0002 ! 761: #define KBDSTF_CONTROL 0x0004 ! 762: #define KBDSTF_ALT 0x0008 ! 763: #define KBDSTF_SCROLLLOCK_ON 0x0010 ! 764: #define KBDSTF_NUMLOCK_ON 0x0020 ! 765: #define KBDSTF_CAPSLOCK_ON 0x0040 ! 766: #define KBDSTF_INSERT_ON 0x0080 ! 767: #define KBDSTF_LEFTCONTROL 0x0100 ! 768: #define KBDSTF_LEFTALT 0x0200 ! 769: #define KBDSTF_RIGHTCONTROL 0x0400 ! 770: #define KBDSTF_RIGHTALT 0x0800 ! 771: #define KBDSTF_SCROLLLOCK 0x1000 ! 772: #define KBDSTF_NUMLOCK 0x2000 ! 773: #define KBDSTF_CAPSLOCK 0x4000 ! 774: #define KBDSTF_SYSREQ 0x8000 ! 775: ! 776: int kbd_state(void) ! 777: { ! 778: int i=0; ! 779: ulong l; ! 780: INPUT_RECORD rec; ! 781: ! 782: PeekConsoleInput(stdin,&rec,1,&l); ! 783: if(rec.EventType==KEY_EVENT) ! 784: l=rec.Event.KeyEvent.dwControlKeyState; ! 785: else if(rec.EventType==MOUSE_EVENT) ! 786: l=rec.Event.MouseEvent.dwControlKeyState; ! 787: else ! 788: return(0); ! 789: ! 790: /* Translate Win32 key state to IBM key state */ ! 791: ! 792: if(l&RIGHT_ALT_PRESSED) ! 793: i|=KBDSTF_RIGHTALT; ! 794: if(l&LEFT_ALT_PRESSED) ! 795: i|=KBDSTF_LEFTALT; ! 796: if(l&RIGHT_CTRL_PRESSED) ! 797: i|=KBDSTF_RIGHTCONTROL; ! 798: if(l&LEFT_CTRL_PRESSED) ! 799: i|=KBDSTF_LEFTCONTROL; ! 800: if(l&CAPSLOCK_ON) ! 801: i|=KBDSTF_CAPSLOCK; ! 802: if(l&NUMLOCK_ON) ! 803: i|=KBDSTF_NUMLOCK; ! 804: if(l&SCROLLLOCK_ON) ! 805: i|=KBDSTF_SCROLLLOCK; ! 806: if(l&SHIFT_PRESSED) ! 807: i|=KBDSTF_LEFTSHIFT; ! 808: ! 809: return(i); ! 810: } ! 811: ! 812: ! 813: ! 814: #endif ! 815:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.