From f3f66b77d5e2c564dd5ee8ded6cae62bc5b62ddb Mon Sep 17 00:00:00 2001 From: rswindell <> Date: Sat, 6 Apr 2002 00:40:31 +0000 Subject: [PATCH] New directory for cross-platform development files (wrappers, etc). --- src/xpdev/conwrap.c | 120 +++++++++++ src/xpdev/conwrap.h | 52 +++++ src/xpdev/dirwrap.c | 469 +++++++++++++++++++++++++++++++++++++++++ src/xpdev/dirwrap.h | 212 +++++++++++++++++++ src/xpdev/filewrap.c | 179 ++++++++++++++++ src/xpdev/filewrap.h | 128 +++++++++++ src/xpdev/gen_defs.h | 180 ++++++++++++++++ src/xpdev/genwrap.c | 118 +++++++++++ src/xpdev/genwrap.h | 180 ++++++++++++++++ src/xpdev/sockwrap.h | 127 +++++++++++ src/xpdev/threadwrap.c | 91 ++++++++ src/xpdev/threadwrap.h | 105 +++++++++ src/xpdev/wraptest.c | 65 ++++++ 13 files changed, 2026 insertions(+) create mode 100644 src/xpdev/conwrap.c create mode 100644 src/xpdev/conwrap.h create mode 100644 src/xpdev/dirwrap.c create mode 100644 src/xpdev/dirwrap.h create mode 100644 src/xpdev/filewrap.c create mode 100644 src/xpdev/filewrap.h create mode 100644 src/xpdev/gen_defs.h create mode 100644 src/xpdev/genwrap.c create mode 100644 src/xpdev/genwrap.h create mode 100644 src/xpdev/sockwrap.h create mode 100644 src/xpdev/threadwrap.c create mode 100644 src/xpdev/threadwrap.h create mode 100644 src/xpdev/wraptest.c diff --git a/src/xpdev/conwrap.c b/src/xpdev/conwrap.c new file mode 100644 index 0000000000..bfaeea3121 --- /dev/null +++ b/src/xpdev/conwrap.c @@ -0,0 +1,120 @@ +/* + conwrap.c -- To give DOS's getch() function to Linux for use in Synchronet + Casey Martin 2000 +*/ + +/* $Id$ */ + +/* @format.tab-size 4, @format.use-tabs true */ + +#ifdef __unix__ + +#include <stdlib.h> +#include <unistd.h> +#include <termios.h> + +/* Do the correct thing under BSD */ +#ifndef __FreeBSD__ +#include <sys/kd.h> +#endif +#ifdef __FreeBSD__ +#include <sys/kbio.h> +#endif + +#include <sys/time.h> +#include <sys/types.h> +#include <signal.h> + +#include "conwrap.h" // Verify prototypes + +struct termios current; // our current term settings +struct termios original; // old termios settings +struct timeval timeout = {0, 0}; // passed in select() call +fd_set inp; // ditto +int beensetup = 0; // has _termios_setup() been called? + +/* + I'm using a variable function here simply for the sake of speed. The + termios functions must be called before a kbhit() can be successful, so + on the first call, we just set up the terminal, point to variable function + to kbhit_norm(), and then call the new function. Otherwise, testing would + be required on every call to determine if termios has already been setup. + + Maybe I'm being way too anal, though. +*/ + +/* Resets the termios to its previous state */ +void _termios_reset(void) +{ + tcsetattr(0, TCSANOW, &original); +} + +/************************************************ + This pair of functions handles Ctrl-Z presses +************************************************/ + +void _sighandler_stop(int sig) +{ + // clean up the terminal + _termios_reset(); + + // ... and stop + kill(getpid(), SIGSTOP); +} + +void _sighandler_cont(int sig) +{ + // restore terminal + tcsetattr(0, TCSANOW, ¤t); +} + + +/* Prepares termios for non-blocking action */ +void _termios_setup(void) +{ + beensetup = 1; + + tcgetattr(0, &original); + + memcpy(¤t, &original, sizeof(struct termios)); + current.c_cc[VMIN] = 1; // read() will return with one char + current.c_cc[VTIME] = 0; // read() blocks forever + current.c_lflag &= ~ICANON; // character mode + current.c_lflag &= ~ECHO; // turn off echoing + tcsetattr(0, TCSANOW, ¤t); + + // Let's install an exit function, also. This way, we can reset + // the termios silently + atexit(_termios_reset); + + // install the Ctrl-Z handler + signal(SIGSTOP, _sighandler_stop); + signal(SIGCONT, _sighandler_cont); +} + + +int kbhit(void) +{ + // set up select() args + FD_ZERO(&inp); + FD_SET(0, &inp); + + return select(1, &inp, NULL, NULL, &timeout); +} + +int getch(void) +{ + char c; + + if (!beensetup) + // I hate to test for this every time, but this shouldn't be + // called that often anyway... + _termios_setup(); + + // get a char out of stdin + read(0, &c, 1); + + return c; +} + +#endif // __unix__ diff --git a/src/xpdev/conwrap.h b/src/xpdev/conwrap.h new file mode 100644 index 0000000000..e1153fb7d2 --- /dev/null +++ b/src/xpdev/conwrap.h @@ -0,0 +1,52 @@ +/* conwrap.h */ + +/* Synchronet local console I/O wrapppers */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#ifndef _CONWRAP_H +#define _CONWRAP_H + +#ifdef __unix__ + + int kbhit(void); + int getch(void); + +#else /* DOS-Based */ + + #include <conio.h> + +#endif + +#endif /* _CONWRAP_H */ diff --git a/src/xpdev/dirwrap.c b/src/xpdev/dirwrap.c new file mode 100644 index 0000000000..4d7d0402e3 --- /dev/null +++ b/src/xpdev/dirwrap.c @@ -0,0 +1,469 @@ +/* dirwrap.c */ + +/* Directory-related system-call wrappers */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#ifdef _WIN32 + +#include <windows.h> /* WINAPI, etc */ +#include <io.h> /* _findfirst */ + +#elif defined __unix__ + +#include <unistd.h> /* usleep */ +#include <fcntl.h> /* O_NOCCTY */ +#include <ctype.h> /* toupper */ + +#ifdef __FreeBSD__ +#include <sys/param.h> +#include <sys/mount.h> +#include <sys/kbio.h> +#endif + +#include <sys/ioctl.h> /* ioctl */ + +#ifdef __GLIBC__ /* actually, BSD, but will work for now */ +#include <sys/vfs.h> /* statfs() */ +#endif + +#endif + +#include <sys/types.h> /* _dev_t */ +#include <sys/stat.h> /* struct stat */ + +#include <stdio.h> /* sprintf */ +#include <stdlib.h> /* rand */ +#include <errno.h> /* ENOENT definitions */ + +#include "dirwrap.h" /* DLLCALL */ + +/****************************************************************************/ +/* Return the filename portion of a full pathname */ +/****************************************************************************/ +char* DLLCALL getfname(char* path) +{ + char *fname; + + fname=strrchr(path,'/'); + if(fname==NULL) + fname=strrchr(path,'\\'); + if(fname!=NULL) + fname++; + else + fname=path; + return(fname); +} + +#if !defined(__unix__) +/****************************************************************************/ +/* Win32 (minimal) implementation of POSIX.2 glob() function */ +/* This code _may_ work on other DOS-based platforms (e.g. OS/2) */ +/****************************************************************************/ +static int glob_compare( const void *arg1, const void *arg2 ) +{ + /* Compare all of both strings: */ + return stricmp( * ( char** ) arg1, * ( char** ) arg2 ); +} + +#ifdef __BORLANDC__ + #pragma argsused +#endif + +int DLLCALL glob(const char *pattern, int flags, void* unused, glob_t* glob) +{ + struct _finddata_t ff; + long ff_handle; + size_t found=0; + char path[MAX_PATH+1]; + char* p; + char** new_pathv; + + if(!(flags&GLOB_APPEND)) { + glob->gl_pathc=0; + glob->gl_pathv=NULL; + } + + ff_handle=_findfirst((char*)pattern,&ff); + while(ff_handle!=-1) { + if(!(flags&GLOB_ONLYDIR) || ff.attrib&_A_SUBDIR) { + if((new_pathv=realloc(glob->gl_pathv + ,(glob->gl_pathc+1)*sizeof(char*)))==NULL) { + globfree(glob); + return(GLOB_NOSPACE); + } + glob->gl_pathv=new_pathv; + + /* build the full pathname */ + strcpy(path,pattern); + p=getfname(path); + *p=0; + strcat(path,ff.name); + + if((glob->gl_pathv[glob->gl_pathc]=malloc(strlen(path)+2))==NULL) { + globfree(glob); + return(GLOB_NOSPACE); + } + strcpy(glob->gl_pathv[glob->gl_pathc],path); + if(flags&GLOB_MARK && ff.attrib&_A_SUBDIR) + strcat(glob->gl_pathv[glob->gl_pathc],"/"); + + glob->gl_pathc++; + found++; + } + if(_findnext(ff_handle, &ff)!=0) { + _findclose(ff_handle); + ff_handle=-1; + } + } + + if(found==0) + return(GLOB_NOMATCH); + + if(!(flags&GLOB_NOSORT)) { + qsort(glob->gl_pathv,found,sizeof(char*),glob_compare); + } + + return(0); /* success */ +} + +void DLLCALL globfree(glob_t* glob) +{ + size_t i; + + if(glob==NULL) + return; + + if(glob->gl_pathv!=NULL) { + for(i=0;i<glob->gl_pathc;i++) + if(glob->gl_pathv[i]!=NULL) + free(glob->gl_pathv[i]); + + free(glob->gl_pathv); + glob->gl_pathv=NULL; + } + glob->gl_pathc=0; +} + +#endif /* !defined(__unix__) */ + +/****************************************************************************/ +/* POSIX directory operations using Microsoft _findfirst/next API. */ +/****************************************************************************/ +#if defined(_MSC_VER) +DIR* opendir(const char* dirname) +{ + DIR* dir; + + if((dir=(DIR*)calloc(1,sizeof(DIR)))==NULL) { + errno=ENOMEM; + return(NULL); + } + sprintf(dir->filespec,"%.*s",sizeof(dir->filespec)-5,dirname); + if(*dir->filespec && dir->filespec[strlen(dir->filespec)-1]!='\\') + strcat(dir->filespec,"\\"); + strcat(dir->filespec,"*.*"); + dir->handle=_findfirst(dir->filespec,&dir->finddata); + if(dir->handle==-1) { + errno=ENOENT; + free(dir); + return(NULL); + } + return(dir); +} +struct dirent* readdir(DIR* dir) +{ + if(dir==NULL) + return(NULL); + if(dir->end==TRUE) + return(NULL); + if(dir->handle==-1) + return(NULL); + sprintf(dir->dirent.d_name,"%.*s",sizeof(struct dirent)-1,dir->finddata.name); + if(_findnext(dir->handle,&dir->finddata)!=0) + dir->end=TRUE; + return(&dir->dirent); +} +int closedir (DIR* dir) +{ + if(dir==NULL) + return(-1); + _findclose(dir->handle); + free(dir); + return(0); +} +void rewinddir(DIR* dir) +{ + if(dir==NULL) + return; + _findclose(dir->handle); + dir->end=FALSE; + dir->handle=_findfirst(dir->filespec,&dir->finddata); +} +#endif /* defined(_MSC_VER) */ + +/****************************************************************************/ +/* Returns the time/date of the file in 'filename' in time_t (unix) format */ +/****************************************************************************/ +time_t DLLCALL fdate(char *filename) +{ + struct stat st; + + if(access(filename,0)==-1) + return(-1); + + if(stat(filename, &st)!=0) + return(-1); + + return(st.st_mtime); +} + +/****************************************************************************/ +/* Returns the length of the file in 'filename' */ +/****************************************************************************/ +long DLLCALL flength(char *filename) +{ +#ifdef __BORLANDC__ /* stat() doesn't work right */ + + long handle; + struct _finddata_t f; + + if(access(filename,0)==-1) + return(-1L); + + if((handle=_findfirst(filename,&f))==-1) + return(-1); + + _findclose(handle); + + return(f.size); + +#else + + struct stat st; + + if(access(filename,0)==-1) + return(-1L); + + if(stat(filename, &st)!=0) + return(-1L); + + return(st.st_size); + +#endif +} + +/****************************************************************************/ +/* Checks the file system for the existence of one or more files. */ +/* Returns TRUE if it exists, FALSE if it doesn't. */ +/* 'filespec' may contain wildcards! */ +/****************************************************************************/ +BOOL DLLCALL fexist(char *filespec) +{ +#ifdef _WIN32 + + long handle; + struct _finddata_t f; + + if(access(filespec,0)==-1 && !strchr(filespec,'*') && !strchr(filespec,'?')) + return(FALSE); + + if((handle=_findfirst(filespec,&f))==-1) + return(FALSE); + + _findclose(handle); + + if(f.attrib&_A_SUBDIR) + return(FALSE); + + return(TRUE); + +#elif defined(__unix__) /* portion by cmartin */ + + glob_t g; + int c; + int l; + + if(access(filespec,0)==-1 && !strchr(filespec,'*') && !strchr(filespec,'?')) + return(FALSE); + + // start the search + glob(filespec, GLOB_MARK | GLOB_NOSORT, NULL, &g); + + if (!g.gl_pathc) { + // no results + globfree(&g); + return FALSE; + } + + // make sure it's not a directory + c = g.gl_pathc; + while (c--) { + l = strlen(g.gl_pathv[c]); + if (l && g.gl_pathv[c][l-1] != '/') { + globfree(&g); + return TRUE; + } + } + + globfree(&g); + return FALSE; + +#else + +#warning "fexist() port needs to support wildcards!" + + return(FALSE); + +#endif +} + +/****************************************************************************/ +/* Returns TRUE if the filename specified is a directory */ +/****************************************************************************/ +BOOL DLLCALL isdir(char *filename) +{ + struct stat st; + + if(stat(filename, &st)!=0) + return(FALSE); + + return((st.st_mode&S_IFDIR) ? TRUE : FALSE); +} + +/****************************************************************************/ +/* Returns the attributes (mode) for specified 'filename' */ +/****************************************************************************/ +int DLLCALL getfattr(char* filename) +{ +#ifdef _WIN32 + long handle; + struct _finddata_t finddata; + + if((handle=_findfirst(filename,&finddata))==-1) { + errno=ENOENT; + return(-1); + } + _findclose(handle); + return(finddata.attrib); +#else + struct stat st; + + if(stat(filename, &st)!=0) { + errno=ENOENT; + return(-1L); + } + + return(st.st_mode); +#endif +} + +/****************************************************************************/ +/* Return free disk space in bytes (up to a maximum of 4GB) */ +/****************************************************************************/ +#ifdef _WIN32 + typedef BOOL(WINAPI * GetDiskFreeSpaceEx_t) + (LPCTSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); +#endif + +ulong DLLCALL getfreediskspace(char* path) +{ +#ifdef _WIN32 + char root[16]; + DWORD TotalNumberOfClusters; + DWORD NumberOfFreeClusters; + DWORD BytesPerSector; + DWORD SectorsPerCluster; + ULARGE_INTEGER avail; + ULARGE_INTEGER size; + static HINSTANCE hK32; + GetDiskFreeSpaceEx_t GetDiskFreeSpaceEx; + + if(hK32 == NULL) + hK32 = LoadLibrary("KERNEL32"); + GetDiskFreeSpaceEx + = (GetDiskFreeSpaceEx_t)GetProcAddress(hK32,"GetDiskFreeSpaceExA"); + + if (GetDiskFreeSpaceEx!=NULL) { /* Windows 95-OSR2 or later */ + if(!GetDiskFreeSpaceEx( + path, // pointer to the directory name + &avail, // receives the number of bytes on disk avail to the caller + &size, // receives the number of bytes on disk + NULL)) // receives the free bytes on disk + return(0); +#ifdef _ANONYMOUS_STRUCT + if(avail.HighPart) +#else + if(avail.u.HighPart) +#endif + return(0xffffffff); /* 4GB max */ + +#ifdef _ANONYMOUS_STRUCT + return(avail.LowPart); +#else + return(avail.u.LowPart); +#endif + } + + /* Windows 95 (old way), limited to 2GB */ + sprintf(root,"%.3s",path); + if(!GetDiskFreeSpace( + root, // pointer to root path + &SectorsPerCluster, // pointer to sectors per cluster + &BytesPerSector, // pointer to bytes per sector + &NumberOfFreeClusters, // pointer to number of free clusters + &TotalNumberOfClusters // pointer to total number of clusters + )) + return(0); + + return(NumberOfFreeClusters*SectorsPerCluster*BytesPerSector); + + +/* statfs is also used under FreeBSD */ +#elif defined(__GLIBC__) || defined(__FreeBSD__) + + struct statfs fs; + + if (statfs(path, &fs) < 0) + return 0; + + return fs.f_bsize * fs.f_bavail; + +#else + + #warning OS-specific code needed here + return(0); + +#endif +} diff --git a/src/xpdev/dirwrap.h b/src/xpdev/dirwrap.h new file mode 100644 index 0000000000..5d382e4435 --- /dev/null +++ b/src/xpdev/dirwrap.h @@ -0,0 +1,212 @@ +/* dirwrap.h */ + +/* Directory system-call wrappers */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#ifndef _DIRWRAP_H +#define _DIRWRAP_H + +#include "gen_defs.h" /* ulong */ + +#ifdef DLLEXPORT +#undef DLLEXPORT +#endif +#ifdef DLLCALL +#undef DLLCALL +#endif + +#ifdef _WIN32 + #ifdef WRAPPER_DLL + #define DLLEXPORT __declspec(dllexport) + #else + #define DLLEXPORT __declspec(dllimport) + #endif + #ifdef __BORLANDC__ + #define DLLCALL __stdcall + #else + #define DLLCALL + #endif +#else /* !_WIN32 */ + #define DLLEXPORT + #define DLLCALL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER + #include "msdirent.h" +#else + #include <dirent.h> /* POSIX directory functions */ +#endif + +/****************/ +/* RTL-specific */ +/****************/ + +#ifdef __unix__ + + #define ALLFILES "*" /* matches all files in a directory */ + #define MKDIR(dir) _mkdir(dir) + #define RMDIR(dir) _rmdir(dir) + #define FULLPATH(a,r,l) _fullpath(a,r,l) + #include <glob.h> /* POSIX.2 directory pattern matching function */ + +#else + + #define ALLFILES "*.*" /* matches all files in a directory */ + #define MKDIR(dir) mkdir(dir,0777) + #define RMDIR(dir) rmdir(dir) + #define FULLPATH(a,r,l) realpath(r,a) + + /* glob-compatible findfirst/findnext wrapper */ + + typedef struct + { + size_t gl_pathc; /* Count of paths matched so far */ + char **gl_pathv; /* List of matched pathnames. */ + size_t gl_offs; /* Slots to reserve in 'gl_pathv'. */ + } glob_t; + + /* Bits set in the FLAGS argument to `glob'. */ + #define GLOB_ERR (1 << 0) /* Return on read errors. */ + #define GLOB_MARK (1 << 1) /* Append a slash to each name. */ + #define GLOB_NOSORT (1 << 2) /* Don't sort the names. */ + #define GLOB_DOOFFS (1 << 3) /* Insert PGLOB->gl_offs NULLs. */ + #define GLOB_NOCHECK (1 << 4) /* If nothing matches, return the pattern. */ + #define GLOB_APPEND (1 << 5) /* Append to results of a previous call. */ + #define GLOB_NOESCAPE (1 << 6) /* Backslashes don't quote metacharacters. */ + #define GLOB_PERIOD (1 << 7) /* Leading `.' can be matched by metachars. */ + #define GLOB_MAGCHAR (1 << 8) /* Set in gl_flags if any metachars seen. */ + #define GLOB_ALTDIRFUNC (1 << 9) /* Use gl_opendir et al functions. */ + #define GLOB_BRACE (1 << 10) /* Expand "{a,b}" to "a" "b". */ + #define GLOB_NOMAGIC (1 << 11) /* If no magic chars, return the pattern. */ + #define GLOB_TILDE (1 << 12) /* Expand ~user and ~ to home directories. */ + #define GLOB_ONLYDIR (1 << 13) /* Match only directories. */ + #define GLOB_TILDE_CHECK (1 << 14) /* Like GLOB_TILDE but return an error + if the user name is not available. */ + /* Error returns from `glob'. */ + #define GLOB_NOSPACE 1 /* Ran out of memory. */ + #define GLOB_ABORTED 2 /* Read error. */ + #define GLOB_NOMATCH 3 /* No matches found. */ + #define GLOB_NOSYS 4 /* Not implemented. */ + + DLLEXPORT int DLLCALL glob(const char *pattern, int flags, void* unused, glob_t*); + DLLEXPORT void DLLCALL globfree(glob_t*); + +#endif + +/*****************************/ +/* POSIX Directory Functions */ +/*****************************/ +#if defined(_MSC_VER) + /* dirent structure returned by readdir(). + */ + struct dirent + { + char d_name[260]; /* filename */ + }; + + /* DIR type returned by opendir(). The members of this structure + * must not be accessed by application programs. + */ + typedef struct + { + char filespec[260]; + struct dirent dirent; + long handle; + struct _finddata_t finddata; + BOOL end; /* End of directory flag */ + } DIR; + + + /* Prototypes. + */ + DIR * opendir (const char *__dirname); + struct dirent * readdir (DIR *__dir); + int closedir (DIR *__dir); + void rewinddir(DIR *__dir); +#endif + +/**********/ +/* Macros */ +/**********/ + +/* POSIX readdir convenience macro */ +#ifndef DIRENT +#define DIRENT struct dirent +#endif + +#if defined(__unix__) +#define BACKSLASH '/' +#else /* MS-DOS based OS */ +#define BACKSLASH '\\' +#endif + +#if defined(_MSC_VER) || defined(__MINGW32__) + +#define CHMOD(s,m) _chmod(s,m) +#define PUTENV _putenv +#define GETCWD _getcwd + +#elif defined(__BORLANDC__) + +#define CHMOD(p,a) _rtl_chmod(p,1,a) /* _chmod obsolete in 4.x */ +#define PUTENV putenv +#define GETCWD getcwd + +#else /* ??? */ + +#define CHMOD(s,m) chmod(s,m) +#define PUTENV putenv +#define GETCWD getcwd + +#endif + +/* General file system wrappers for all platforms and compilers */ +DLLEXPORT BOOL DLLCALL fexist(char *filespec); +DLLEXPORT long DLLCALL flength(char *filename); +DLLEXPORT time_t DLLCALL fdate(char *filename); +DLLEXPORT BOOL DLLCALL isdir(char *filename); +DLLEXPORT char* DLLCALL getfname(char* path); +DLLEXPORT int DLLCALL getfattr(char* filename); +DLLEXPORT ulong DLLCALL getfreediskspace(char* path); + +#ifdef __cplusplus +} +#endif + +#endif /* Don't add anything after this line */ diff --git a/src/xpdev/filewrap.c b/src/xpdev/filewrap.c new file mode 100644 index 0000000000..8b0b5ad6aa --- /dev/null +++ b/src/xpdev/filewrap.c @@ -0,0 +1,179 @@ +/* filewrap.c */ + +/* File-related system-call wrappers */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +/* OS-specific */ +#if defined(__unix__) + +#include <glob.h> /* glob() wildcard matching */ +#include <string.h> /* strlen() */ +#include <unistd.h> /* getpid() */ +#include <fcntl.h> /* fcntl() file/record locking */ + +#endif + +/* ANSI */ +#include <sys/types.h> /* _dev_t */ +#include <sys/stat.h> /* struct stat */ + +#include "filewrap.h" /* Verify prototypes */ + +/****************************************************************************/ +/* Returns the modification time of the file in 'fd' */ +/****************************************************************************/ +time_t DLLCALL filetime(int fd) +{ + struct stat st; + + if(fstat(fd, &st)!=0) + return(-1); + + return(st.st_mtime); +} + +#if defined(__unix__) + +/****************************************************************************/ +/* Returns the length of the file in 'fd' */ +/****************************************************************************/ +long DLLCALL filelength(int fd) +{ + struct stat st; + + if(fstat(fd, &st)!=0) + return(-1L); + + return(st.st_size); +} + +/* Sets a lock on a portion of a file */ +int DLLCALL lock(int fd, long pos, int len) +{ + int flags; + struct flock alock; + + if((flags=fcntl(fd,F_GETFL))<0) + return -1; + + if(flags==O_RDONLY) + alock.l_type = F_RDLCK; // set read lock to prevent writes + else + alock.l_type = F_WRLCK; // set write lock to prevent all access + alock.l_whence = L_SET; // SEEK_SET + alock.l_start = pos; + alock.l_len = len; + + return fcntl(fd, F_SETLK, &alock); +} + +/* Removes a lock from a file record */ +int DLLCALL unlock(int fd, long pos, int len) +{ + struct flock alock; + + alock.l_type = F_UNLCK; // remove the lock + alock.l_whence = L_SET; + alock.l_start = pos; + alock.l_len = len; + return fcntl(fd, F_SETLK, &alock); +} + +/* Opens a file in specified sharing (file-locking) mode */ +int DLLCALL sopen(char *fn, int access, int share) +{ + int fd; + struct flock alock; + + if ((fd = open(fn, access, S_IREAD|S_IWRITE)) < 0) + return -1; + + if (share == SH_DENYNO) + // no lock needed + return fd; + + alock.l_type = share; + alock.l_whence = L_SET; + alock.l_start = 0; + alock.l_len = 0; // lock to EOF + + if (fcntl(fd, F_SETLK, &alock) < 0) { + close(fd); + return -1; + } + + return fd; +} + +#elif defined _MSC_VER || defined __MINGW32__ + +#include <io.h> /* tell */ +#include <stdio.h> /* SEEK_SET */ +#include <sys/locking.h> /* _locking */ + +/* Fix MinGW locking.h typo */ +#if defined LK_UNLOCK && !defined LK_UNLCK + #define LK_UNLCK LK_UNLOCK +#endif + +int DLLCALL lock(int file, long offset, int size) +{ + int i; + long pos; + + pos=tell(file); + if(offset!=pos) + lseek(file, offset, SEEK_SET); + i=_locking(file,LK_NBLCK,size); + if(offset!=pos) + lseek(file, pos, SEEK_SET); + return(i); +} + +int DLLCALL unlock(int file, long offset, int size) +{ + int i; + long pos; + + pos=tell(file); + if(offset!=pos) + lseek(file, offset, SEEK_SET); + i=_locking(file,LK_UNLCK,size); + if(offset!=pos) + lseek(file, pos, SEEK_SET); + return(i); +} + +#endif /* !Unix && (MSVC || MinGW) */ diff --git a/src/xpdev/filewrap.h b/src/xpdev/filewrap.h new file mode 100644 index 0000000000..4e8088f561 --- /dev/null +++ b/src/xpdev/filewrap.h @@ -0,0 +1,128 @@ +/* filewrap.h */ + +/* File system-call wrappers */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#ifndef _FILEWRAP_H +#define _FILEWRAP_H + +/**********/ +/* Macros */ +/**********/ + +#if defined(_WIN32) + + #include <io.h> /* _sopen */ + #include <sys/stat.h> /* S_IREAD */ + #include <fcntl.h> /* O_BINARY */ + #include <windows.h> /* OF_SHARE_ */ + + #define sopen(f,o,s) _sopen(f,o,s,S_IREAD|S_IWRITE) + #define close(f) _close(f) + + #ifndef SH_DENYNO + #define SH_DENYNO OF_SHARE_DENY_NONE + #define SH_DENYWR OF_SHARE_DENY_WRITE + #define SH_DENYRW OF_SHARE_EXCLUSIVE + #endif + #ifndef O_DENYNONE + #define O_DENYNONE SH_DENYNO + #endif + +#elif defined(__unix__) + + #include <fcntl.h> + + #define O_TEXT 0 /* all files in binary mode on Unix */ + #define O_BINARY 0 /* all files in binary mode on Unix */ + #define O_DENYNONE (1<<31) /* req'd for Baja/nopen compatibility */ + + #define SH_DENYNO 2 // no locks + #define SH_DENYRW F_WRLCK // exclusive lock + #define SH_DENYWR F_RDLCK // shareable lock + + #define chsize(fd,size) ftruncate(fd,size) + #define tell(fd) lseek(fd,0,SEEK_CUR) + +#endif + +/**************/ +/* Prototypes */ +/**************/ + +#ifdef DLLEXPORT +#undef DLLEXPORT +#endif +#ifdef DLLCALL +#undef DLLCALL +#endif + +#ifdef _WIN32 + #ifdef WRAPPER_DLL + #define DLLEXPORT __declspec(dllexport) + #else + #define DLLEXPORT __declspec(dllimport) + #endif + #ifdef __BORLANDC__ + #define DLLCALL __stdcall + #else + #define DLLCALL + #endif +#else /* !_WIN32 */ + #define DLLEXPORT + #define DLLCALL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(__BORLANDC__) + DLLEXPORT int DLLCALL lock(int fd, long pos, int len); + DLLEXPORT int DLLCALL unlock(int fd, long pos, int len); +#endif + +#if defined(__unix__) + DLLEXPORT int DLLCALL sopen(char *fn, int access, int share); + DLLEXPORT long DLLCALL filelength(int fd); +#endif + +DLLEXPORT time_t DLLCALL filetime(int fd); + +#ifdef __cplusplus +} +#endif + +#endif /* Don't add anything after this line */ diff --git a/src/xpdev/gen_defs.h b/src/xpdev/gen_defs.h new file mode 100644 index 0000000000..2d110968e4 --- /dev/null +++ b/src/xpdev/gen_defs.h @@ -0,0 +1,180 @@ +/* gen_defs.h */ + +/* General(ly useful) constant, macro, and type definitions */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#ifndef _GEN_DEFS_H +#define _GEN_DEFS_H + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN /* Don't bring in excess baggage */ +#include <windows.h> +#endif + +#include <sys/types.h> + + /* Control characters */ +#define STX 0x02 /* Start of text ^B */ +#define ETX 0x03 /* End of text ^C */ +#define BEL 0x07 /* Bell/beep ^G */ +#define FF 0x0c /* Form feed ^L */ +#define ESC 0x1b /* Escape ^[ */ +#define DEL 0x7f /* Delete ^BS */ +#define BS '\b' /* Back space ^H */ +#define TAB '\t' /* Horizontal tabulation ^I */ +#define LF '\n' /* Line feed ^J */ +#define CR '\r' /* Carriage return ^M */ +#define SP ' ' /* Space */ + +enum { + CTRL_A=1 + ,CTRL_B + ,CTRL_C + ,CTRL_D + ,CTRL_E + ,CTRL_F + ,CTRL_G + ,CTRL_H + ,CTRL_I + ,CTRL_J + ,CTRL_K + ,CTRL_L + ,CTRL_M + ,CTRL_N + ,CTRL_O + ,CTRL_P + ,CTRL_Q + ,CTRL_R + ,CTRL_S + ,CTRL_T + ,CTRL_U + ,CTRL_V + ,CTRL_W + ,CTRL_X + ,CTRL_Y + ,CTRL_Z +}; + +#ifndef MAX_PATH + #ifdef MAXPATHLEN + #define MAX_PATH MAXPATHLEN /* clib.h */ + #elif defined PATH_MAX + #define MAX_PATH PATH_MAX + #elif defined _MAX_PATH + #define MAX_PATH _MAX_PATH + #else + #define MAX_PATH 260 + #endif +#endif + +/* Unsigned type short-hands */ +#ifndef uchar + #define uchar unsigned char +#endif +#ifndef __GLIBC__ + #ifndef ushort + #define ushort unsigned short + #define uint unsigned int + #define ulong unsigned long + #endif +#endif + +/* Windows Types */ +#ifndef BYTE +#define BYTE uchar +#endif +#ifndef WORD +#define WORD ushort +#endif +#ifndef DWORD +#define DWORD ulong +#endif +#ifndef BOOL +#define BOOL int +#endif +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif +#ifndef HANDLE +#define HANDLE void* +#endif + +#define SAFECOPY(dst,src) sprintf(dst,"%.*s",sizeof(dst)-1,src) + +/****************************************************************************/ +/* MALLOC/FREE Macros for various compilers and environments */ +/* MALLOC is used for allocations of 64k or less */ +/* FREE is used to free buffers allocated with MALLOC */ +/* LMALLOC is used for allocations of possibly larger than 64k */ +/* LFREE is used to free buffers allocated with LMALLOC */ +/* REALLOC is used to re-size a previously MALLOCed or LMALLOCed buffer */ +/* FAR16 is used to create a far (32-bit) pointer in 16-bit compilers */ +/* HUGE16 is used to create a huge (32-bit) pointer in 16-bit compilers */ +/****************************************************************************/ +#if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) + #define HUGE16 huge + #define FAR16 far + #if defined(__TURBOC__) + #define REALLOC(x,y) farrealloc(x,y) + #define LMALLOC(x) farmalloc(x) + #define MALLOC(x) farmalloc(x) + #define LFREE(x) farfree(x) + #define FREE(x) farfree(x) + #elif defined(__WATCOMC__) + #define REALLOC realloc + #define LMALLOC(x) halloc(x,1) /* far heap, but slow */ + #define MALLOC malloc /* far heap, but 64k max */ + #define LFREE hfree + #define FREE free + #else /* Other 16-bit Compiler */ + #define REALLOC realloc + #define LMALLOC malloc + #define MALLOC malloc + #define LFREE free + #define FREE free + #endif +#else /* 32-bit Compiler or Small Memory Model */ + #define HUGE16 + #define FAR16 + #define REALLOC realloc + #define LMALLOC malloc + #define MALLOC malloc + #define LFREE free + #define FREE free +#endif + + +#endif /* Don't add anything after this #endif statement */ diff --git a/src/xpdev/genwrap.c b/src/xpdev/genwrap.c new file mode 100644 index 0000000000..3679ae6f49 --- /dev/null +++ b/src/xpdev/genwrap.c @@ -0,0 +1,118 @@ +/* genwrap.c */ + +/* General cross-platform development wrappers */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#include <string.h> /* strlen() */ + +#include "genwrap.h" /* Verify prototypes */ + +/****************************************************************************/ +/* Convert ASCIIZ string to upper case */ +/****************************************************************************/ +#ifdef __unix__ +char* SMBCALL strupr(char* str) +{ + char* p=str; + + while(*p) { + *p=toupper(*p); + p++; + } + return(str); +} +/****************************************************************************/ +/* Convert ASCIIZ string to lower case */ +/****************************************************************************/ +char* SMBCALL strlwr(char* str) +{ + char* p=str; + + while(*p) { + *p=tolower(*p); + p++; + } + return(str); +} +/****************************************************************************/ +/* Reverse characters of a string (provided by amcleod) */ +/****************************************************************************/ +char* strrev(char* str) +{ + char t, *i=str, *j=str+strlen(str); + + while (i<j) { + t=*i; *(i++)=*(--j); *j=t; + } + return str; +} +#endif + +/****************************************************************************/ +/* Generate a tone at specified frequency for specified milliseconds */ +/* Thanks to Casey Martin for this code */ +/****************************************************************************/ +#ifdef __unix__ +void DLLCALL xp_beep(int freq, int dur) +{ + static int console_fd=-1; + + if(console_fd == -1) + console_fd = open("/dev/console", O_NOCTTY); + + if(console_fd != -1) { + ioctl(console_fd, KIOCSOUND, (int) (1193180 / freq)); + mswait(dur); + ioctl(console_fd, KIOCSOUND, 0); /* turn off tone */ + } +} +#endif + +/****************************************************************************/ +/* Return random number between 0 and n-1 */ +/****************************************************************************/ +#ifndef __BORLANDC__ +int DLLCALL xp_random(int n) +{ + float f; + + if(n<2) + return(0); + f=(float)rand()/(float)RAND_MAX; + + return((int)(n*f)); +} +#endif + diff --git a/src/xpdev/genwrap.h b/src/xpdev/genwrap.h new file mode 100644 index 0000000000..759b526c5d --- /dev/null +++ b/src/xpdev/genwrap.h @@ -0,0 +1,180 @@ +/* genwrap.h */ + +/* General cross-platform development wrappers */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#ifndef _GENWRAP_H +#define _GENWRAP_H + +#include <stdio.h> /* sprintf */ +#include "gen_defs.h" /* ulong */ + +#ifdef DLLEXPORT +#undef DLLEXPORT +#endif +#ifdef DLLCALL +#undef DLLCALL +#endif + +#ifdef _WIN32 + #ifdef WRAPPER_DLL + #define DLLEXPORT __declspec(dllexport) + #else + #define DLLEXPORT __declspec(dllimport) + #endif + #ifdef __BORLANDC__ + #define DLLCALL __stdcall + #else + #define DLLCALL + #endif +#else /* !_WIN32 */ + #define DLLEXPORT + #define DLLCALL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*********************/ +/* Compiler-specific */ +/*********************/ + +/* Compiler Description */ +#if defined(__BORLANDC__) + + #define COMPILER_DESC(str) sprintf(str,"BCC %X.%02X" \ + ,__BORLANDC__>>8,__BORLANDC__&0xff); + +#elif defined(_MSC_VER) + + #define COMPILER_DESC(str) sprintf(str,"MSC %u", _MSC_VER); + +/*** +#elif defined(__GNUC__) && defined(__GLIBC__) + + #define COMPILER_DESC(str) sprintf(str,"GCC %u.%02u (GLIBC %u.%u)" \ + ,__GNUC__,__GNUC_MINOR__,__GLIBC__,__GLIBC_MINOR__); +***/ + +#elif defined(__GNUC__) + + #define COMPILER_DESC(str) sprintf(str,"GCC %u.%02u" \ + ,__GNUC__,__GNUC_MINOR__); + +#else /* Unknown compiler */ + + #define COMPILER_DESC(str) strcpy(str,"UNKNOWN COMPILER"); + +#endif + +/**********/ +/* Macros */ +/**********/ + +/* Target Platform Description */ +#if defined(_WIN64) + #define PLATFORM_DESC "Win64" +#elif defined(_WIN32) + #define PLATFORM_DESC "Win32" +#elif defined(__OS2__) + #define PLATFORM_DESC "OS/2" +#elif defined(__MSDOS__) + #define PLATFORM_DESC "DOS" +#elif defined(__linux__) + #define PLATFORM_DESC "Linux" +#elif defined(__FreeBSD__) + #define PLATFORM_DESC "FreeBSD" +#elif defined(BSD) + #define PLATFORM_DESC "BSD" +#elif defined(__unix__) + #define PLATFORM_DESC "Unix" +#else + #warning "Need to describe target platform" + #define PLATFORM_DESC "UNKNOWN" +#endif + +/*********************/ +/* String Functionss */ +/*********************/ + +#if defined(_MSC_VER) || defined(__MINGW32__) + #define snprintf _snprintf +#endif + +#if !defined(_MSC_VER) && !defined(__BORLANDC__) + DLLEXPORT char* DLLCALL ultoa(ulong, char*, int radix); +#endif + +#if defined(__unix__) + DLLEXPORT char* DLLCALL strupr(char* str); + DLLEXPORT char* DLLCALL strlwr(char* str); + DLLEXPORT char* DLLCALL strrev(char* str); + #if !defined(stricmp) + #define stricmp(x,y) strcasecmp(x,y) + #define strnicmp(x,y,z) strncasecmp(x,y,z) + #endif +#endif + +/****************************/ +/* Common Utility Functions */ +/****************************/ + +#if defined(_WIN32) + + #define xp_beep(freq,dur) Beep(freq,dur) + #define mswait(x) Sleep(x) + +#elif defined(__OS2__) + + #define xp_beep(freq,dur) DosBeep(freq,dur) + #define mswait(x) DosSleep(x) + +#elif defined(__unix__) + + #define mswait(x) usleep(x*1000) + DLLEXPORT void DLLCALL xp_beep(int freq, int dur); + +#else /* Unsupported OS */ + + #warning "Unsupported Target: Need some macros or function prototypes here." + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* Don't add anything after this line */ diff --git a/src/xpdev/sockwrap.h b/src/xpdev/sockwrap.h new file mode 100644 index 0000000000..84e0132a53 --- /dev/null +++ b/src/xpdev/sockwrap.h @@ -0,0 +1,127 @@ +/* sockwrap.h */ + +/* Berkley/WinSock socket API wrappers */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#ifndef _SOCKWRAP_H +#define _SOCKWRAP_H + +/***************/ +/* OS-specific */ +/***************/ +#if defined _WIN32 || defined __OS2__ /* Use WinSock */ + +#include <winsock.h> /* socket/bind/etc. */ + +/* Let's agree on a standard WinSock symbol here, people */ +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ +#endif + +#elif defined __unix__ /* Unix-variant */ + +#include <netdb.h> /* gethostbyname */ +#include <sys/types.h> /* For u_int32_t on FreeBSD */ +#include <netinet/in.h> /* IPPROTO_IP */ +#include <sys/socket.h> /* socket/bind/etc. */ +#include <sys/ioctl.h> /* FIONBIO */ +#include <sys/time.h> /* struct timeval */ +#include <arpa/inet.h> /* inet_ntoa */ +#include <unistd.h> /* close */ + +#endif + +#include <errno.h> /* errno */ + +/**********************************/ +/* Socket Implementation-specific */ +/**********************************/ +#ifdef _WINSOCKAPI_ + +#undef EINTR +#define EINTR (WSAEINTR-WSABASEERR) +#undef ENOTSOCK +#define ENOTSOCK (WSAENOTSOCK-WSABASEERR) +#undef EWOULDBLOCK +#define EWOULDBLOCK (WSAEWOULDBLOCK-WSABASEERR) +#undef ECONNRESET +#define ECONNRESET (WSAECONNRESET-WSABASEERR) +#undef ESHUTDOWN +#define ESHUTDOWN (WSAESHUTDOWN-WSABASEERR) +#undef ECONNABORTED +#define ECONNABORTED (WSAECONNABORTED-WSABASEERR) + +#define s_addr S_un.S_addr + +#define socklen_t int + +static wsa_error; +#define ERROR_VALUE ((wsa_error=WSAGetLastError())>0 ? wsa_error-WSABASEERR : wsa_error) +#define sendsocket(s,b,l) send(s,b,l,0) + +#else /* BSD sockets */ + +/* WinSock-isms */ +#define HOSTENT struct hostent +#define SOCKADDR_IN struct sockaddr_in +#define LINGER struct linger +#define SOCKET int +#define SOCKET_ERROR -1 +#define INVALID_SOCKET (SOCKET)(~0) +#define closesocket close +#define ioctlsocket ioctl +#define ERROR_VALUE errno +#define sendsocket write // FreeBSD send() is broken + +#endif /* __unix__ */ + +#ifndef SHUT_RDWR +#define SHUT_RDWR 2 /* for shutdown() */ +#endif + +#ifndef IPPORT_FTP +#define IPPORT_FTP 21 +#endif +#ifndef IPPORT_TELNET +#define IPPORT_TELNET 23 +#endif +#ifndef IPPORT_SMTP +#define IPPORT_SMTP 25 +#endif +#ifndef IPPORT_POP3 +#define IPPORT_POP3 110 +#endif + +#endif /* Don't add anything after this line */ diff --git a/src/xpdev/threadwrap.c b/src/xpdev/threadwrap.c new file mode 100644 index 0000000000..097f947d95 --- /dev/null +++ b/src/xpdev/threadwrap.c @@ -0,0 +1,91 @@ +/* threadwrap.c */ + +/* Thread-related cross-platform development wrappers */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#include "threadwrap.h" /* DLLCALL */ + +/****************************************************************************/ +/* Wrapper for Win32 create/begin thread function */ +/* Uses POSIX threads */ +/****************************************************************************/ +#if defined(__unix__) && defined(SBBS) +#if defined(_POSIX_THREADS) +ulong _beginthread(void( *start_address )( void * ) + ,unsigned stack_size, void *arglist) +{ + pthread_t thread; + pthread_attr_t attr; + + pthread_attr_init(&attr); /* initialize attribute structure */ + + /* set thread attributes to PTHREAD_CREATE_DETACHED which will ensure + that thread resources are freed on exit() */ + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + if(pthread_create(&thread + ,&attr /* default attributes */ + /* POSIX defines this arg as "void *(*start_address)" */ + ,(void *) start_address + ,arglist)==0) + return((int) thread /* thread handle */); + + return(-1); /* error */ +} +#else + +#error "Need _beginthread implementation for non-POSIX thread library." + +#endif + +#endif /* __unix__ */ + +/****************************************************************************/ +/* Win32 implementation of POSIX sem_getvalue() function */ +/****************************************************************************/ +#ifdef _WIN32 +int DLLCALL sem_getvalue(sem_t* psem, int* val) +{ + if(psem==NULL || val==NULL) + return(-1); + + if(WaitForSingleObject(*(psem),0)==WAIT_OBJECT_0) + *val=1; + else + *val=0; + + return(0); +} +#endif diff --git a/src/xpdev/threadwrap.h b/src/xpdev/threadwrap.h new file mode 100644 index 0000000000..24c9fbe18d --- /dev/null +++ b/src/xpdev/threadwrap.h @@ -0,0 +1,105 @@ +/* threadwrap.h */ + +/* Thread-related cross-platform development wrappers */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#ifndef _THREADWRAP_H +#define _THREADWRAP_H + +#include "gen_defs.h" /* HANDLE */ + +#ifdef DLLEXPORT +#undef DLLEXPORT +#endif +#ifdef DLLCALL +#undef DLLCALL +#endif + +#ifdef _WIN32 + #ifdef WRAPPER_DLL + #define DLLEXPORT __declspec(dllexport) + #else + #define DLLEXPORT __declspec(dllimport) + #endif + #ifdef __BORLANDC__ + #define DLLCALL __stdcall + #else + #define DLLCALL + #endif +#else /* !_WIN32 */ + #define DLLEXPORT + #define DLLCALL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __unix__ + + #include <pthread.h> /* POSIX threads and mutexes */ + #include <semaphore.h> /* POSIX semaphores */ + ulong _beginthread(void( *start_address )( void * ) + ,unsigned stack_size, void *arglist); + +#elif defined(_WIN32) + + /* POSIX semaphores */ + typedef HANDLE sem_t; + #define sem_init(psem,ps,v) ResetEvent(*(psem)) + #define sem_wait(psem) WaitForSingleObject(*(psem),INFINITE) + #define sem_post(psem) SetEvent(*(psem)) + #define sem_destroy(psem) CloseHandle(*(psem)) + DLLEXPORT int DLLCALL sem_getvalue(sem_t*, int* val); + + /* POSIX mutexes */ + typedef HANDLE pthread_mutex_t; + #define PTHREAD_MUTEX_INITIALIZER CreateMutex(NULL,FALSE,NULL) + #define pthread_mutex_init(pmtx,v) *(pmtx)=CreateMutex(NULL,FALSE,NULL) + #define pthread_mutex_lock(pmtx) WaitForSingleObject(*(pmtx),INFINITE) + #define pthread_mutex_unlock(pmtx) ReleaseMutex(*(pmtx)) + #define pthread_mutex_destroy(pmtx) CloseHandle(*(pmtx)) + +#else + + #warning "Need semaphore wrappers." + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* Don't add anything after this line */ diff --git a/src/xpdev/wraptest.c b/src/xpdev/wraptest.c new file mode 100644 index 0000000000..290ef6dd97 --- /dev/null +++ b/src/xpdev/wraptest.c @@ -0,0 +1,65 @@ +/* wraptest.c */ + +#include <time.h> /* ctime */ + +#include "genwrap.h" +#include "conwrap.h" +#include "dirwrap.h" +#include "filewrap.h" +#include "sockwrap.h" +#include "threadwrap.h" + +int main() +{ + char compiler[128]; + char fname[MAX_PATH+1]; + char* glob_pattern = "*wrap*"; + int i; + uint u; + time_t t; + glob_t g; + DIR* dir; + DIRENT* dirent; + + COMPILER_DESC(compiler); + printf("Platform: %s\n",PLATFORM_DESC); + printf("Compiler: %s\n",compiler); + + xp_beep(500,500); + + /* GLOB TEST */ + printf("glob() test\n"); + i=glob(glob_pattern,GLOB_MARK,NULL,&g); + if(i==0) { + for(u=0;u<g.gl_pathc;u++) + printf("%s\n",g.gl_pathv[u]); + globfree(&g); + } else + printf("glob(%s) returned %d\n",glob_pattern,i); + + printf("Hit any key..."); + printf("\ngetch() returned %d\n",getch()); + + /* OPENDIR TEST */ + printf("opendir() test\n"); + dir=opendir("."); + while(dir!=NULL && (dirent=readdir(dir))!=NULL) { + t=fdate(dirent->d_name); + sprintf(fname,"%.*s%c" + ,sizeof(fname)-2 + ,dirent->d_name + ,isdir(dirent->d_name) ? '/':0); + printf("%-25s %10lu %.24s\n" + ,fname + ,flength(dirent->d_name) + ,ctime(&t) + ); + } + if(dir!=NULL) + closedir(dir); + + printf("Hit any key..."); + printf("\ngetch() returned %d\n",getch()); + + return 0; +} \ No newline at end of file -- GitLab