2 * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
3 * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 675
17 * Mass Ave, Cambridge, MA 02139, USA.
22 extern int DEBUGLEVEL;
26 /***************************************************************
27 Signal function to tell us we timed out.
28 ****************************************************************/
30 static void gotalarm_sig(void)
35 /***************************************************************
36 Lock or unlock a fd for a known lock type. Abandon after waitsecs
38 ****************************************************************/
40 BOOL do_file_lock(int fd, int waitsecs, int type)
42 SMB_STRUCT_FLOCK lock;
46 CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
49 lock.l_whence = SEEK_SET;
55 ret = fcntl(fd, SMB_F_SETLKW, &lock);
57 CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
60 DEBUG(0, ("do_file_lock: failed to %s file.\n",
61 type == F_UNLCK ? "unlock" : "lock"));
69 /***************************************************************
70 Lock an fd. Abandon after waitsecs seconds.
71 ****************************************************************/
73 BOOL file_lock(int fd, int type, int secs, int *plock_depth)
80 if ((*plock_depth) == 0)
82 if (!do_file_lock(fd, secs, type)) {
83 DEBUG(10,("file_lock: locking file failed, error = %s.\n",
92 /***************************************************************
93 Unlock an fd. Abandon after waitsecs seconds.
94 ****************************************************************/
96 BOOL file_unlock(int fd, int *plock_depth)
100 if(*plock_depth == 1)
101 ret = do_file_lock(fd, 5, F_UNLCK);
106 DEBUG(10,("file_unlock: unlocking file failed, error = %s.\n",
111 /***************************************************************
112 locks a file for enumeration / modification.
113 update to be set = True if modification is required.
114 ****************************************************************/
116 void *startfileent(char *pfile, char *s_readbuf, int bufsize,
117 int *file_lock_depth, BOOL update)
123 DEBUG(0, ("startfileent: No file set\n"));
126 DEBUG(10, ("startfileent: opening file %s\n", pfile));
128 fp = sys_fopen(pfile, update ? "r+b" : "rb");
131 DEBUG(0, ("startfileent: unable to open file %s\n", pfile));
135 /* Set a buffer to do more efficient reads */
136 setvbuf(fp, s_readbuf, _IOFBF, bufsize);
138 if (!file_lock(fileno(fp), (update ? F_WRLCK : F_RDLCK), 5, file_lock_depth))
140 DEBUG(0, ("startfileent: unable to lock file %s\n", pfile));
145 /* Make sure it is only rw by the owner */
148 /* We have a lock on the file. */
152 /***************************************************************
153 End enumeration of the file.
154 ****************************************************************/
155 void endfileent(void *vp, int *file_lock_depth)
157 FILE *fp = (FILE *)vp;
159 file_unlock(fileno(fp), file_lock_depth);
161 DEBUG(7, ("endfileent: closed file.\n"));
164 /*************************************************************************
165 Return the current position in the file list as an SMB_BIG_UINT.
166 This must be treated as an opaque token.
167 *************************************************************************/
168 SMB_BIG_UINT getfilepwpos(void *vp)
170 return (SMB_BIG_UINT)sys_ftell((FILE *)vp);
173 /*************************************************************************
174 Set the current position in the file list from an SMB_BIG_UINT.
175 This must be treated as an opaque token.
176 *************************************************************************/
177 BOOL setfilepwpos(void *vp, SMB_BIG_UINT tok)
179 return !sys_fseek((FILE *)vp, (SMB_OFF_T)tok, SEEK_SET);
182 /*************************************************************************
183 gets a line out of a file.
184 lines with "#" at the front are ignored.
185 *************************************************************************/
186 int getfileline(void *vp, char *linebuf, int linebuf_size)
188 /* Static buffers we will return. */
189 FILE *fp = (FILE *)vp;
195 DEBUG(0,("getfileline: Bad file pointer.\n"));
200 * Scan the file, a line at a time.
206 fgets(linebuf, linebuf_size, fp);
213 * Check if the string is terminated with a newline - if not
214 * then we must keep reading and discard until we get one.
217 linebuf_len = strlen(linebuf);
218 if (linebuf[linebuf_len - 1] != '\n')
221 while (!ferror(fp) && !feof(fp))
232 linebuf[linebuf_len - 1] = '\0';
235 #ifdef DEBUG_PASSWORD
236 DEBUG(100, ("getfileline: got line |%s|\n", linebuf));
238 if ((linebuf[0] == 0) && feof(fp))
240 DEBUG(4, ("getfileline: end of file reached\n"));
244 if (linebuf[0] == '#' || linebuf[0] == '\0')
246 DEBUG(6, ("getfileline: skipping comment or blank line\n"));
256 /****************************************************************************
257 read a line from a file with possible \ continuation chars.
258 Blanks at the start or end of a line are stripped.
259 The string will be allocated if s2 is NULL
260 ****************************************************************************/
261 char *fgets_slash(char *s2,int maxlen,FILE *f)
266 BOOL start_of_line = True;
273 maxlen = MIN(maxlen,8);
274 s = (char *)Realloc(s,maxlen);
277 if (!s || maxlen < 2) return(NULL);
281 while (len < maxlen-1)
289 while (len > 0 && s[len-1] == ' ')
293 if (len > 0 && s[len-1] == '\\')
296 start_of_line = True;
303 return(len>0?s:NULL);
308 start_of_line = False;
312 if (!s2 && len > maxlen-3)
315 s = (char *)Realloc(s,maxlen);
316 if (!s) return(NULL);
322 /****************************************************************************
323 checks if a file has changed since last read
324 ****************************************************************************/
325 BOOL file_modified(const char *filename, time_t *lastmodified)
329 if (sys_stat(filename, &st) != 0)
331 DEBUG(0, ("file_changed: Unable to stat file %s. Error was %s\n",
332 filename, strerror(errno) ));
336 if(st.st_mtime <= *lastmodified)
338 DEBUG(20, ("file_modified: %s not modified\n", filename));
342 DEBUG(20, ("file_modified: %s modified\n", filename));
343 *lastmodified = st.st_mtime;
347 /***************************************************************************
348 opens a file if modified otherwise returns NULL
349 ***************************************************************************/
350 void *open_file_if_modified(const char *filename, char *mode, time_t *lastmodified)
354 if (!file_modified(filename, lastmodified))
359 if( (f = fopen(filename, mode)) == NULL)
361 DEBUG(0, ("open_file_if_modified: can't open file %s. Error was %s\n",
362 filename, strerror(errno)));