|
|
1.1 root 1: /* smbwrap.c */
2:
3: /* Synchronet SMBLIB system-call wrappers */
4:
5: /* $Id: smbwrap.c,v 1.14 2000/11/07 21:42:48 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: /* OS-specific */
39: #if defined(__unix__)
40:
41: #include <glob.h> /* glob() wildcard matching */
42: #include <string.h> /* strlen() */
43: #include <unistd.h> /* getpid() */
44: #include <fcntl.h> /* fcntl() file/record locking */
45:
46: #endif
47:
48: /* ANSI */
49: #include <sys/types.h> /* _dev_t */
50: #include <sys/stat.h> /* struct stat */
51:
52: /* SMB-specific */
53: #include "smblib.h" /* SMBCALL */
54: #include "smbwrap.h" /* Verify prototypes */
55:
56: #ifdef _WIN32
57: #define stat(f,s) _stat(f,s)
58: #define STAT struct _stat
59: #else
60: #define STAT struct stat
61: #endif
62:
63: /****************************************************************************/
64: /* Convert ASCIIZ string to upper case */
65: /****************************************************************************/
66: #ifdef __unix__
67: char* SMBCALL strupr(char* str)
68: {
69: char* p=str;
70:
71: while(*p) {
72: *p=toupper(*p);
73: p++;
74: }
75: return(str);
76: }
77: /****************************************************************************/
78: /* Convert ASCIIZ string to lower case */
79: /****************************************************************************/
80: char* SMBCALL strlwr(char* str)
81: {
82: char* p=str;
83:
84: while(*p) {
85: *p=tolower(*p);
86: p++;
87: }
88: return(str);
89: }
90: #endif
91:
92: /****************************************************************************/
93: /* Returns the length of the file in 'filename' */
94: /****************************************************************************/
95: long SMBCALL flength(char *filename)
96: {
97: STAT st;
98:
99: if(stat(filename, &st)!=0)
100: return(-1L);
101:
102: return(st.st_size);
103: }
104:
105: /****************************************************************************/
106: /* Checks the file system for the existence of one or more files. */
107: /* Returns TRUE if it exists, FALSE if it doesn't. */
108: /* 'filespec' may contain wildcards! */
109: /****************************************************************************/
110: BOOL SMBCALL fexist(char *filespec)
111: {
112: #ifdef _WIN32
113:
114: long handle;
115: struct _finddata_t f;
116:
117: if((handle=_findfirst(filespec,&f))==-1)
118: return(FALSE);
119:
120: _findclose(handle);
121:
122: if(f.attrib&_A_SUBDIR)
123: return(FALSE);
124:
125: return(TRUE);
126:
127: #elif defined(__unix__) /* portion by cmartin */
128:
129: glob_t g;
130: int c;
131: int l;
132:
133: // start the search
134: glob(filespec, GLOB_MARK | GLOB_NOSORT, NULL, &g);
135:
136: if (!g.gl_pathc) {
137: // no results
138: globfree(&g);
139: return FALSE;
140: }
141:
142: // make sure it's not a directory
143: c = g.gl_pathc;
144: while (c--) {
145: l = strlen(g.gl_pathv[c]);
146: if (l && g.gl_pathv[c][l-1] != '/') {
147: globfree(&g);
148: return TRUE;
149: }
150: }
151:
152: globfree(&g);
153: return FALSE;
154:
155: #else
156:
157: #warning "fexist() port needs to support wildcards!"
158:
159: return(FALSE);
160:
161: #endif
162: }
163:
164: #if defined(__unix__)
165:
166: /****************************************************************************/
167: /* Returns the length of the file in 'fd' */
168: /****************************************************************************/
169: long SMBCALL filelength(int fd)
170: {
171: STAT st;
172:
173: if(fstat(fd, &st)!=0)
174: return(-1L);
175:
176: return(st.st_size);
177: }
178:
179: /* Sets a lock on a portion of a file */
180: int SMBCALL lock(int fd, long pos, int len)
181: {
182: int flags;
183: struct flock alock;
184:
185: if((flags=fcntl(fd,F_GETFL))<0)
186: return -1;
187:
188: if(flags==O_RDONLY)
189: alock.l_type = F_RDLCK; // set read lock to prevent writes
190: else
191: alock.l_type = F_WRLCK; // set write lock to prevent all access
192: alock.l_whence = L_SET; // SEEK_SET
193: alock.l_start = pos;
194: alock.l_len = len;
195:
196: return fcntl(fd, F_SETLK, &alock);
197: }
198:
199: /* Removes a lock from a file record */
200: int SMBCALL unlock(int fd, long pos, int len)
201: {
202: struct flock alock;
203:
204: alock.l_type = F_UNLCK; // remove the lock
205: alock.l_whence = L_SET;
206: alock.l_start = pos;
207: alock.l_len = len;
208: return fcntl(fd, F_SETLK, &alock);
209: }
210:
211: /* Opens a file in specified sharing (file-locking) mode */
212: int SMBCALL sopen(char *fn, int access, int share)
213: {
214: int fd;
215: struct flock alock;
216:
217: if ((fd = open(fn, access, S_IREAD|S_IWRITE)) < 0)
218: return -1;
219:
220: if (share == SH_DENYNO)
221: // no lock needed
222: return fd;
223:
224: alock.l_type = share;
225: alock.l_whence = L_SET;
226: alock.l_start = 0;
227: alock.l_len = 0; // lock to EOF
228:
229: #if 0
230: /* The l_pid field is only used with F_GETLK to return the process
231: ID of the process holding a blocking lock. */
232: alock.l_pid = getpid();
233: #endif
234:
235: if (fcntl(fd, F_SETLK, &alock) < 0) {
236: close(fd);
237: return -1;
238: }
239:
240: return fd;
241: }
242:
243: #elif defined _MSC_VER || defined __MINGW32__
244:
245: #include <io.h> /* tell */
246: #include <stdio.h> /* SEEK_SET */
247: #include <sys/locking.h> /* _locking */
248:
249: /* Fix MinGW locking.h typo */
250: #if defined LK_UNLOCK && !defined LK_UNLCK
251: #define LK_UNLCK LK_UNLOCK
252: #endif
253:
254: int SMBCALL lock(int file, long offset, int size)
255: {
256: int i;
257: long pos;
258:
259: pos=tell(file);
260: if(offset!=pos)
261: lseek(file, offset, SEEK_SET);
262: i=_locking(file,LK_NBLCK,size);
263: if(offset!=pos)
264: lseek(file, pos, SEEK_SET);
265: return(i);
266: }
267:
268: int SMBCALL unlock(int file, long offset, int size)
269: {
270: int i;
271: long pos;
272:
273: pos=tell(file);
274: if(offset!=pos)
275: lseek(file, offset, SEEK_SET);
276: i=_locking(file,LK_UNLCK,size);
277: if(offset!=pos)
278: lseek(file, pos, SEEK_SET);
279: return(i);
280: }
281:
282: #endif /* !Unix && (MSVC || MinGW) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.