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