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

1.1       root        1: /* wrappers.c */
                      2: 
                      3: /* Synchronet system-call wrappers */
                      4: 
                      5: /* $Id: wrappers.c,v 1.30 2000/12/05 03:26:34 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: #ifdef _WIN32
                     39: 
                     40: #include <windows.h>   /* WINAPI, etc */
                     41: #include <io.h>                        /* _findfirst */
                     42: 
                     43: #elif defined __unix__
                     44: 
                     45: #include <unistd.h>            /* usleep */
                     46: #include <fcntl.h>             /* O_NOCCTY */
                     47: #include <ctype.h>             /* toupper */
                     48: #include <sys/kd.h>            /* KIOCSOUND */
                     49: #include <sys/ioctl.h> /* ioctl */
                     50: 
                     51: #ifdef __GLIBC__               /* actually, BSD, but will work for now */
                     52: #include <sys/vfs.h>    /* statfs() */
                     53: #endif
                     54: 
                     55: #endif
                     56: 
                     57: #include <sys/types.h> /* _dev_t */
                     58: #include <sys/stat.h>  /* struct stat */
                     59: 
                     60: #include <stdio.h>             /* sprintf */
                     61: #include <stdlib.h>            /* rand */
                     62: #include <errno.h>             /* ENOENT definitions */
                     63: 
                     64: #include "sbbs.h"              /* getfname */
                     65: 
                     66: #ifdef _WIN32
                     67: #define stat(f,s)      _stat(f,s)
                     68: #define STAT           struct _stat
                     69: #else
                     70: #define STAT           struct stat
                     71: #endif
                     72: 
                     73: /****************************************************************************/
                     74: /* POSIX.2 directory pattern matching function                                                         */
                     75: /****************************************************************************/
                     76: #ifndef __unix__
                     77: #ifdef __BORLANDC__
                     78:        #pragma argsused
                     79: #endif
                     80: int    DLLCALL glob(const char *pattern, int flags, void* unused, glob_t* glob)
                     81: {
                     82:     struct     _finddata_t ff;
                     83:        long    ff_handle;
                     84:        size_t  found=0;
                     85:        char    path[MAX_PATH];
                     86:        char*   p;
                     87:        char**  new_pathv;
                     88: 
                     89:        if(!(flags&GLOB_APPEND)) {
                     90:                glob->gl_pathc=0;
                     91:                glob->gl_pathv=NULL;
                     92:        }
                     93: 
                     94:        ff_handle=_findfirst((char*)pattern,&ff);
                     95:        while(ff_handle!=-1) {
                     96:                if(!(flags&GLOB_ONLYDIR) || ff.attrib&_A_SUBDIR) {
                     97:                        if((new_pathv=realloc(glob->gl_pathv
                     98:                                ,(glob->gl_pathc+1)*sizeof(char*)))==NULL) {
                     99:                                globfree(glob);
                    100:                                return(GLOB_NOSPACE);
                    101:                        }
                    102:                        glob->gl_pathv=new_pathv;
                    103: 
                    104:                        /* build the full pathname */
                    105:                        strcpy(path,pattern);
                    106:                        p=getfname(path);
                    107:                        *p=0;
                    108:                        strcat(path,ff.name);
                    109: 
                    110:                        if((glob->gl_pathv[glob->gl_pathc]=malloc(strlen(path)+2))==NULL) {
                    111:                                globfree(glob);
                    112:                                return(GLOB_NOSPACE);
                    113:                        }
                    114:                        strcpy(glob->gl_pathv[glob->gl_pathc],path);
                    115:                        if(flags&GLOB_MARK && ff.attrib&_A_SUBDIR)
                    116:                                strcat(glob->gl_pathv[glob->gl_pathc],"/");
                    117: 
                    118:                        glob->gl_pathc++;
                    119:                        found++;
                    120:                }
                    121:                if(_findnext(ff_handle, &ff)!=0) {
                    122:                        _findclose(ff_handle);
                    123:                        ff_handle=-1; 
                    124:                } 
                    125:        }
                    126: 
                    127:        if(found==0)
                    128:                return(GLOB_NOMATCH);
                    129: 
                    130:        return(0);      /* success */
                    131: }
                    132: 
                    133: void DLLCALL globfree(glob_t* glob)
                    134: {
                    135:        size_t i;
                    136: 
                    137:        if(glob==NULL)
                    138:                return;
                    139: 
                    140:        if(glob->gl_pathv!=NULL) {
                    141:                for(i=0;i<glob->gl_pathc;i++)
                    142:                        if(glob->gl_pathv[i]!=NULL)
                    143:                                free(glob->gl_pathv[i]);
                    144: 
                    145:                free(glob->gl_pathv);
                    146:                glob->gl_pathv=NULL;
                    147:        }
                    148:        glob->gl_pathc=0;
                    149: }
                    150: #endif
                    151: 
                    152: /****************************************************************************/
                    153: /* Returns the time/date of the file in 'filename' in time_t (unix) format  */
                    154: /****************************************************************************/
                    155: long DLLCALL fdate(char *filename)
                    156: {
                    157:        STAT st;
                    158: 
                    159:        if(stat(filename, &st)!=0)
                    160:                return(-1L);
                    161: 
                    162:        return(st.st_mtime);
                    163: }
                    164: 
                    165: /****************************************************************************/
                    166: /* Returns TRUE if the filename specified is a directory                                       */
                    167: /****************************************************************************/
                    168: BOOL DLLCALL isdir(char *filename)
                    169: {
                    170:        STAT st;
                    171: 
                    172:        if(stat(filename, &st)!=0)
                    173:                return(FALSE);
                    174: 
                    175:        return((st.st_mode&S_IFDIR) ? TRUE : FALSE);
                    176: }
                    177: 
                    178: 
                    179: /****************************************************************************/
                    180: /* Returns the attributes (mode) for specified 'filename'                                      */
                    181: /****************************************************************************/
                    182: int DLLCALL getfattr(char* filename)
                    183: {
                    184: #ifdef _WIN32
                    185:        long handle;
                    186:        struct _finddata_t      finddata;
                    187: 
                    188:        if((handle=_findfirst(filename,&finddata))==-1) {
                    189:                errno=ENOENT;
                    190:                return(-1);
                    191:        }
                    192:        _findclose(handle);
                    193:        return(finddata.attrib);
                    194: #else
                    195:        STAT st;
                    196: 
                    197:        if(stat(filename, &st)!=0) {
                    198:                errno=ENOENT;
                    199:                return(-1L);
                    200:        }
                    201: 
                    202:        return(st.st_mode);
                    203: #endif
                    204: }
                    205: 
                    206: /****************************************************************************/
                    207: /* Generate a tone at specified frequency for specified milliseconds           */
                    208: /* Thanks to Casey Martin for this code                                                                                */
                    209: /****************************************************************************/
                    210: #ifdef __unix__
                    211: void DLLCALL sbbs_beep(int freq, int dur)
                    212: {
                    213:        static int console_fd=-1;
                    214: 
                    215:        if(console_fd == -1) 
                    216:                console_fd = open("/dev/console", O_NOCTTY);
                    217:        
                    218:        if(console_fd != -1) {
                    219:                ioctl(console_fd, KIOCSOUND, (int) (1193180 / freq));
                    220:                mswait(dur);
                    221:                ioctl(console_fd, KIOCSOUND, 0);        /* turn off tone */
                    222:        }
                    223: }
                    224: #endif
                    225: 
                    226: /****************************************************************************/
                    227: /* Return random number between 0 and n-1                                                                      */
                    228: /****************************************************************************/
                    229: #ifndef __BORLANDC__
                    230: int DLLCALL sbbs_random(int n)
                    231: {
                    232:        float f;
                    233: 
                    234:        if(n<2)
                    235:                return(0);
                    236:        f=(float)rand()/(float)RAND_MAX;
                    237: 
                    238:        return((int)(n*f));
                    239: }
                    240: #endif
                    241: 
                    242: /****************************************************************************/
                    243: /* Return ASCII string representation of ulong                                                         */
                    244: /* There may be a native GNU C Library function to this...                                     */
                    245: /****************************************************************************/
                    246: #if !defined _MSC_VER && !defined __BORLANDC__
                    247: char* DLLCALL ultoa(ulong val, char* str, int radix)
                    248: {
                    249:        switch(radix) {
                    250:                case 8:
                    251:                        sprintf(str,"%lo",val);
                    252:                        break;
                    253:                case 10:
                    254:                        sprintf(str,"%lu",val);
                    255:                        break;
                    256:                case 16:
                    257:                        sprintf(str,"%lx",val);
                    258:                        break;
                    259:                default:
                    260:                        sprintf(str,"bad radix: %d",radix);
                    261:                        break;
                    262:        }
                    263:        return(str);
                    264: }
                    265: #endif
                    266: 
                    267: /****************************************************************************/
                    268: /* Reverse characters of a string (provided by amcleod)                                                */
                    269: /****************************************************************************/
                    270: #ifdef __unix__
                    271: char* strrev(char* str)
                    272: {
                    273:     char t, *i=str, *j=str+strlen(str);
                    274: 
                    275:     while (i<j) {
                    276:         t=*i; *(i++)=*(--j); *j=t;
                    277:     }
                    278:     return str;
                    279: }
                    280: #endif
                    281: 
                    282: /****************************************************************************/
                    283: /* Wrapper for Win32 create/begin thread function                                                      */
                    284: /* Uses POSIX threads                                                                                                          */
                    285: /****************************************************************************/
                    286: #ifdef __unix__
                    287: #ifdef _POSIX_THREADS
                    288: ulong _beginthread(void( *start_address )( void * )
                    289:                ,unsigned stack_size, void *arglist)
                    290: {
                    291:        pthread_t       thread;
                    292:        pthread_attr_t attr;
                    293: 
                    294:        pthread_attr_init(&attr);     /* initialize attribute structure */
                    295: 
                    296:        /* set thread attributes to PTHREAD_CREATE_DETACHED which will ensure
                    297:           that thread resources are freed on exit() */
                    298:        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
                    299: 
                    300:        if(pthread_create(&thread
                    301:                ,&attr  /* default attributes */
                    302:                /* POSIX defines this arg as "void *(*start_address)" */
                    303:                ,(void *) start_address
                    304:                ,arglist)==0)
                    305:                return((int) thread /* thread handle */);
                    306: 
                    307:        return(-1);     /* error */
                    308: }
                    309: #else
                    310: 
                    311: #error "Need _beginthread implementation for non-POSIX thread library."
                    312: 
                    313: #endif
                    314: 
                    315: #endif /* __unix__ */
                    316: 
                    317: /****************************************************************************/
                    318: /* Win32 implementation of POSIX sem_getvalue() function                                       */
                    319: /****************************************************************************/
                    320: #ifdef _WIN32
                    321: int sem_getvalue(sem_t* psem, int* val)
                    322: {
                    323:        if(psem==NULL || val==NULL)
                    324:                return(-1);
                    325: 
                    326:        if(WaitForSingleObject(*(psem),0)==WAIT_OBJECT_0)
                    327:                *val=1;
                    328:        else
                    329:                *val=0;
                    330: 
                    331:        return(0);
                    332: }
                    333: #endif
                    334: 
                    335: /****************************************************************************/
                    336: /* Return free disk space in bytes (up to a maximum of 4GB)                                    */
                    337: /****************************************************************************/
                    338: #ifdef _WIN32
                    339:        typedef BOOL(WINAPI * GetDiskFreeSpaceEx_t)
                    340:                (LPCTSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); 
                    341: #endif
                    342: 
                    343: ulong DLLCALL getfreediskspace(char* path)
                    344: {
                    345: #ifdef _WIN32
                    346:        HINSTANCE               hK32;
                    347:        char                    root[16];
                    348:        DWORD                   TotalNumberOfClusters;
                    349:        DWORD                   NumberOfFreeClusters;
                    350:        DWORD                   BytesPerSector;
                    351:        DWORD                   SectorsPerCluster;
                    352:        ULARGE_INTEGER  avail;
                    353:        ULARGE_INTEGER  size;
                    354:        GetDiskFreeSpaceEx_t GetDiskFreeSpaceEx;
                    355: 
                    356:        if ((hK32 = LoadLibrary("KERNEL32")) == NULL)
                    357:                return(0);
                    358: 
                    359:        GetDiskFreeSpaceEx 
                    360:                = (GetDiskFreeSpaceEx_t)GetProcAddress(hK32,"GetDiskFreeSpaceExA");
                    361:  
                    362:        if (GetDiskFreeSpaceEx!=NULL) { /* Windows 95-OSR2 or later */
                    363:                if(!GetDiskFreeSpaceEx(
                    364:                        path,           // pointer to the directory name
                    365:                        &avail,         // receives the number of bytes on disk avail to the caller
                    366:                        &size,          // receives the number of bytes on disk
                    367:                        NULL))          // receives the free bytes on disk
                    368:                        return(0);
                    369: #ifdef _ANONYMOUS_STRUCT
                    370:                if(avail.HighPart)
                    371: #else
                    372:                if(avail.u.HighPart)
                    373: #endif
                    374:                        return(~0);     /* 4GB max */
                    375: 
                    376: #ifdef _ANONYMOUS_STRUCT
                    377:                return(avail.LowPart);
                    378: #else
                    379:                return(avail.u.LowPart);
                    380: #endif
                    381:        }
                    382: 
                    383:        /* Windows 95 (old way), limited to 2GB */
                    384:        sprintf(root,"%.3s",path);
                    385:        if(!GetDiskFreeSpace(
                    386:                root,                                   // pointer to root path
                    387:                &SectorsPerCluster,             // pointer to sectors per cluster
                    388:                &BytesPerSector,                // pointer to bytes per sector
                    389:                &NumberOfFreeClusters,  // pointer to number of free clusters
                    390:                &TotalNumberOfClusters  // pointer to total number of clusters
                    391:                ))
                    392:                return(0);
                    393: 
                    394:        return(NumberOfFreeClusters*SectorsPerCluster*BytesPerSector);
                    395: 
                    396: #elif defined(__GLIBC__)
                    397: 
                    398:        struct statfs fs;
                    399: 
                    400:     if (statfs(path, &fs) < 0)
                    401:        return 0;
                    402: 
                    403:     return fs.f_bsize * fs.f_bavail;
                    404:     
                    405: #else
                    406: 
                    407:        #warning OS-specific code needed here
                    408:        return(0);
                    409: 
                    410: #endif
                    411: }

unix.superglobalmegacorp.com

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