|
|
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.