Code indentation.
[midnight-commander.git] / src / vfs / smbfs / helpers / lib / util_file.c
blob9155ac78c603ed2e0cd4e63947009124bf67f543
1 /*
2 Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
4 Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
6 Copyright (C) 2011
7 The Free Software Foundation, Inc.
9 This file is part of the Midnight Commander.
11 The Midnight Commander is free software: you can redistribute it
12 and/or modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation, either version 3 of the License,
14 or (at your option) any later version.
16 The Midnight Commander is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "includes.h"
27 extern int DEBUGLEVEL;
29 #if 0
30 static int gotalarm;
32 /***************************************************************
33 Signal function to tell us we timed out.
34 ****************************************************************/
36 static void
37 gotalarm_sig (void)
39 gotalarm = 1;
42 /***************************************************************
43 Lock or unlock a fd for a known lock type. Abandon after waitsecs
44 seconds.
45 ****************************************************************/
47 BOOL
48 do_file_lock (int fd, int waitsecs, int type)
50 SMB_STRUCT_FLOCK lock;
51 int ret;
53 gotalarm = 0;
54 CatchSignal (SIGALRM, SIGNAL_CAST gotalarm_sig);
56 lock.l_type = type;
57 lock.l_whence = SEEK_SET;
58 lock.l_start = 0;
59 lock.l_len = 1;
60 lock.l_pid = 0;
62 alarm (waitsecs);
63 ret = fcntl (fd, SMB_F_SETLKW, &lock);
64 alarm (0);
65 CatchSignal (SIGALRM, SIGNAL_CAST SIG_DFL);
67 if (gotalarm)
69 DEBUG (0, ("do_file_lock: failed to %s file.\n", type == F_UNLCK ? "unlock" : "lock"));
70 return False;
73 return (ret == 0);
76 /***************************************************************
77 Lock an fd. Abandon after waitsecs seconds.
78 ****************************************************************/
80 BOOL
81 file_lock (int fd, int type, int secs, int *plock_depth)
83 if (fd < 0)
84 return False;
86 (*plock_depth)++;
88 if ((*plock_depth) == 0)
90 if (!do_file_lock (fd, secs, type))
92 DEBUG (10, ("file_lock: locking file failed, error = %s.\n",
93 unix_error_string (errno)));
94 return False;
98 return True;
101 /***************************************************************
102 Unlock an fd. Abandon after waitsecs seconds.
103 ****************************************************************/
105 BOOL
106 file_unlock (int fd, int *plock_depth)
108 BOOL ret = True;
110 if (*plock_depth == 1)
111 ret = do_file_lock (fd, 5, F_UNLCK);
113 (*plock_depth)--;
115 if (!ret)
116 DEBUG (10, ("file_unlock: unlocking file failed, error = %s.\n",
117 unix_error_string (errno)));
118 return ret;
121 /***************************************************************
122 locks a file for enumeration / modification.
123 update to be set = True if modification is required.
124 ****************************************************************/
126 void *
127 startfilepwent (char *pfile, char *s_readbuf, int bufsize, int *file_lock_depth, BOOL update)
129 FILE *fp = NULL;
131 if (!*pfile)
133 DEBUG (0, ("startfilepwent: No file set\n"));
134 return (NULL);
136 DEBUG (10, ("startfilepwent: opening file %s\n", pfile));
138 fp = sys_fopen (pfile, update ? "r+b" : "rb");
140 if (fp == NULL)
142 DEBUG (0, ("startfilepwent: unable to open file %s\n", pfile));
143 return NULL;
146 /* Set a buffer to do more efficient reads */
147 setvbuf (fp, s_readbuf, _IOFBF, bufsize);
149 if (!file_lock (fileno (fp), (update ? F_WRLCK : F_RDLCK), 5, file_lock_depth))
151 DEBUG (0, ("startfilepwent: unable to lock file %s\n", pfile));
152 fclose (fp);
153 return NULL;
156 /* Make sure it is only rw by the owner */
157 chmod (pfile, 0600);
159 /* We have a lock on the file. */
160 return (void *) fp;
163 /***************************************************************
164 End enumeration of the file.
165 ****************************************************************/
166 void
167 endfilepwent (void *vp, int *file_lock_depth)
169 FILE *fp = (FILE *) vp;
171 file_unlock (fileno (fp), file_lock_depth);
172 fclose (fp);
173 DEBUG (7, ("endfilepwent: closed file.\n"));
177 /*************************************************************************
178 Return the current position in the file list as an SMB_BIG_UINT.
179 This must be treated as an opaque token.
180 *************************************************************************/
181 SMB_BIG_UINT
182 getfilepwpos (void *vp)
184 return (SMB_BIG_UINT) sys_ftell ((FILE *) vp);
187 /*************************************************************************
188 Set the current position in the file list from an SMB_BIG_UINT.
189 This must be treated as an opaque token.
190 *************************************************************************/
191 BOOL
192 setfilepwpos (void *vp, SMB_BIG_UINT tok)
194 return !sys_fseek ((FILE *) vp, (SMB_OFF_T) tok, SEEK_SET);
197 /*************************************************************************
198 gets a line out of a file.
199 line is of format "xxxx:xxxxxx:xxxxx:".
200 lines with "#" at the front are ignored.
201 *************************************************************************/
203 getfileline (void *vp, char *linebuf, int linebuf_size)
205 /* Static buffers we will return. */
206 FILE *fp = (FILE *) vp;
207 unsigned char c;
208 unsigned char *p;
209 size_t linebuf_len;
211 if (fp == NULL)
213 DEBUG (0, ("getfileline: Bad file pointer.\n"));
214 return -1;
218 * Scan the file, a line at a time.
220 while (!feof (fp))
222 linebuf[0] = '\0';
224 fgets (linebuf, linebuf_size, fp);
225 if (ferror (fp))
227 return -1;
231 * Check if the string is terminated with a newline - if not
232 * then we must keep reading and discard until we get one.
235 linebuf_len = strlen (linebuf);
236 if (linebuf[linebuf_len - 1] != '\n')
238 c = '\0';
239 while (!ferror (fp) && !feof (fp))
241 c = fgetc (fp);
242 if (c == '\n')
244 break;
248 else
250 linebuf[linebuf_len - 1] = '\0';
253 #ifdef DEBUG_PASSWORD
254 DEBUG (100, ("getfileline: got line |%s|\n", linebuf));
255 #endif
256 if ((linebuf[0] == 0) && feof (fp))
258 DEBUG (4, ("getfileline: end of file reached\n"));
259 return 0;
262 if (linebuf[0] == '#' || linebuf[0] == '\0')
264 DEBUG (6, ("getfileline: skipping comment or blank line\n"));
265 continue;
268 p = (unsigned char *) strchr (linebuf, ':');
269 if (p == NULL)
271 DEBUG (0, ("getfileline: malformed line entry (no :)\n"));
272 continue;
274 return linebuf_len;
276 return -1;
278 #endif /* 0 */
280 /****************************************************************************
281 read a line from a file with possible \ continuation chars.
282 Blanks at the start or end of a line are stripped.
283 The string will be allocated if s2 is NULL
284 ****************************************************************************/
285 char *
286 fgets_slash (char *s2, int maxlen, FILE * f)
288 char *s = s2;
289 int len = 0;
290 int c;
291 BOOL start_of_line = True;
293 if (feof (f))
294 return (NULL);
296 if (!s2)
298 maxlen = MIN (maxlen, 8);
299 s = (char *) Realloc (s, maxlen);
302 if (!s || maxlen < 2)
303 return (NULL);
305 *s = 0;
307 while (len < maxlen - 1)
309 c = getc (f);
310 switch (c)
312 case '\r':
313 break;
314 case '\n':
315 while (len > 0 && s[len - 1] == ' ')
317 s[--len] = 0;
319 if (len > 0 && s[len - 1] == '\\')
321 s[--len] = 0;
322 start_of_line = True;
323 break;
325 return (s);
326 case EOF:
327 if (len <= 0 && !s2)
328 free (s);
329 return (len > 0 ? s : NULL);
330 case ' ':
331 if (start_of_line)
332 break;
333 default:
334 start_of_line = False;
335 s[len++] = c;
336 s[len] = 0;
338 if (!s2 && len > maxlen - 3)
340 maxlen *= 2;
341 s = (char *) Realloc (s, maxlen);
342 if (!s)
343 return (NULL);
346 return (s);