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

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: 

unix.superglobalmegacorp.com

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