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 *startfilepwent(char *pfile, char *s_readbuf, int bufsize,
117 int *file_lock_depth, BOOL update)
123 DEBUG(0, ("startfilepwent: No file set\n"));
126 DEBUG(10, ("startfilepwent: opening file %s\n", pfile));
128 fp = sys_fopen(pfile, update ? "r+b" : "rb");
131 DEBUG(0, ("startfilepwent: 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, ("startfilepwent: 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 endfilepwent(void *vp, int *file_lock_depth)
157 FILE *fp = (FILE *)vp;
159 file_unlock(fileno(fp), file_lock_depth);
161 DEBUG(7, ("endfilepwent: 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 line is of format "xxxx:xxxxxx:xxxxx:".
185 lines with "#" at the front are ignored.
186 *************************************************************************/
187 int getfileline(void *vp, char *linebuf, int linebuf_size)
189 /* Static buffers we will return. */
190 FILE *fp = (FILE *)vp;
197 DEBUG(0,("getfileline: Bad file pointer.\n"));
202 * Scan the file, a line at a time.
208 fgets(linebuf, linebuf_size, fp);
215 * Check if the string is terminated with a newline - if not
216 * then we must keep reading and discard until we get one.
219 linebuf_len = strlen(linebuf);
220 if (linebuf[linebuf_len - 1] != '\n')
223 while (!ferror(fp) && !feof(fp))
234 linebuf[linebuf_len - 1] = '\0';
237 #ifdef DEBUG_PASSWORD
238 DEBUG(100, ("getfileline: got line |%s|\n", linebuf));
240 if ((linebuf[0] == 0) && feof(fp))
242 DEBUG(4, ("getfileline: end of file reached\n"));
246 if (linebuf[0] == '#' || linebuf[0] == '\0')
248 DEBUG(6, ("getfileline: skipping comment or blank line\n"));
252 p = (unsigned char *) strchr(linebuf, ':');
255 DEBUG(0, ("getfileline: malformed line entry (no :)\n"));
264 /****************************************************************************
265 read a line from a file with possible \ continuation chars.
266 Blanks at the start or end of a line are stripped.
267 The string will be allocated if s2 is NULL
268 ****************************************************************************/
269 char *fgets_slash(char *s2,int maxlen,FILE *f)
274 BOOL start_of_line = True;
281 maxlen = MIN(maxlen,8);
282 s = (char *)Realloc(s,maxlen);
285 if (!s || maxlen < 2) return(NULL);
289 while (len < maxlen-1)
297 while (len > 0 && s[len-1] == ' ')
301 if (len > 0 && s[len-1] == '\\')
304 start_of_line = True;
311 return(len>0?s:NULL);
316 start_of_line = False;
320 if (!s2 && len > maxlen-3)
323 s = (char *)Realloc(s,maxlen);
324 if (!s) return(NULL);
331 /****************************************************************************
332 load from a pipe into memory
333 ****************************************************************************/
334 char *file_pload(char *syscmd, size_t *size)
341 fd = sys_popen(syscmd);
342 if (fd == -1) return NULL;
347 while ((n = read(fd, buf, sizeof(buf))) > 0) {
348 p = Realloc(p, total + n + 1);
353 memcpy(p+total, buf, n);
360 if (size) *size = total;
366 /****************************************************************************
367 load a file into memory
368 ****************************************************************************/
369 char *file_load(char *fname, size_t *size)
372 SMB_STRUCT_STAT sbuf;
375 fd = open(fname,O_RDONLY);
376 if (fd == -1) return NULL;
378 if (sys_fstat(fd, &sbuf) != 0) return NULL;
380 if (sbuf.st_size == 0) return NULL;
382 p = (char *)malloc(sbuf.st_size+1);
385 if (read(fd, p, sbuf.st_size) != sbuf.st_size) {
393 if (size) *size = sbuf.st_size;
399 /****************************************************************************
400 parse a buffer into lines
401 ****************************************************************************/
402 static char **file_lines_parse(char *p, size_t size, int *numlines)
409 for (s = p, i=0; s < p+size; s++) {
410 if (s[0] == '\n') i++;
413 ret = (char **)malloc(sizeof(ret[0])*(i+2));
418 memset(ret, 0, sizeof(ret[0])*(i+2));
419 if (numlines) *numlines = i;
422 for (s = p, i=0; s < p+size; s++) {
428 if (s[0] == '\r') s[0] = 0;
435 /****************************************************************************
436 load a file into memory and return an array of pointers to lines in the file
437 must be freed with file_lines_free()
438 ****************************************************************************/
439 char **file_lines_load(char *fname, int *numlines)
444 p = file_load(fname, &size);
447 return file_lines_parse(p, size, numlines);
451 /****************************************************************************
452 load a pipe into memory and return an array of pointers to lines in the data
453 must be freed with file_lines_free()
454 ****************************************************************************/
455 char **file_lines_pload(char *syscmd, int *numlines)
460 p = file_pload(syscmd, &size);
463 return file_lines_parse(p, size, numlines);
466 /****************************************************************************
467 free lines loaded with file_lines_load
468 ****************************************************************************/
469 void file_lines_free(char **lines)