root/src/vfs/smbfs/helpers/lib/util_file.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. gotalarm_sig
  2. do_file_lock
  3. file_lock
  4. file_unlock
  5. startfilepwent
  6. endfilepwent
  7. getfilepwpos
  8. setfilepwpos
  9. getfileline
  10. fgets_slash

   1 /*
   2    Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
   3 
   4    Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
   5 
   6    Copyright (C) 2011-2019
   7    Free Software Foundation, Inc.
   8 
   9    This file is part of the Midnight Commander.
  10 
  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.
  15 
  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.
  20 
  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/>.
  23  */
  24 
  25 #include "includes.h"
  26 
  27 extern int DEBUGLEVEL;
  28 
  29 #if 0
  30 static int gotalarm;
  31 
  32 /***************************************************************
  33  Signal function to tell us we timed out.
  34 ****************************************************************/
  35 
  36 static void
  37 gotalarm_sig (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
  38 {
  39     gotalarm = 1;
  40 }
  41 
  42 /***************************************************************
  43  Lock or unlock a fd for a known lock type. Abandon after waitsecs 
  44  seconds.
  45 ****************************************************************/
  46 
  47 BOOL
  48 do_file_lock (int fd, int waitsecs, int type)
     /* [previous][next][first][last][top][bottom][index][help]  */
  49 {
  50     SMB_STRUCT_FLOCK lock;
  51     int ret;
  52 
  53     gotalarm = 0;
  54     CatchSignal (SIGALRM, SIGNAL_CAST gotalarm_sig);
  55 
  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;
  61 
  62     alarm (waitsecs);
  63     ret = fcntl (fd, SMB_F_SETLKW, &lock);
  64     alarm (0);
  65     CatchSignal (SIGALRM, SIGNAL_CAST SIG_DFL);
  66 
  67     if (gotalarm)
  68     {
  69         DEBUG (0, ("do_file_lock: failed to %s file.\n", type == F_UNLCK ? "unlock" : "lock"));
  70         return False;
  71     }
  72 
  73     return (ret == 0);
  74 }
  75 
  76 /***************************************************************
  77  Lock an fd. Abandon after waitsecs seconds.
  78 ****************************************************************/
  79 
  80 BOOL
  81 file_lock (int fd, int type, int secs, int *plock_depth)
     /* [previous][next][first][last][top][bottom][index][help]  */
  82 {
  83     if (fd < 0)
  84         return False;
  85 
  86     (*plock_depth)++;
  87 
  88     if ((*plock_depth) == 0)
  89     {
  90         if (!do_file_lock (fd, secs, type))
  91         {
  92             DEBUG (10, ("file_lock: locking file failed, error = %s.\n",
  93                         unix_error_string (errno)));
  94             return False;
  95         }
  96     }
  97 
  98     return True;
  99 }
 100 
 101 /***************************************************************
 102  Unlock an fd. Abandon after waitsecs seconds.
 103 ****************************************************************/
 104 
 105 BOOL
 106 file_unlock (int fd, int *plock_depth)
     /* [previous][next][first][last][top][bottom][index][help]  */
 107 {
 108     BOOL ret = True;
 109 
 110     if (*plock_depth == 1)
 111         ret = do_file_lock (fd, 5, F_UNLCK);
 112 
 113     (*plock_depth)--;
 114 
 115     if (!ret)
 116         DEBUG (10, ("file_unlock: unlocking file failed, error = %s.\n",
 117                     unix_error_string (errno)));
 118     return ret;
 119 }
 120 
 121 /***************************************************************
 122  locks a file for enumeration / modification.
 123  update to be set = True if modification is required.
 124 ****************************************************************/
 125 
 126 void *
 127 startfilepwent (char *pfile, char *s_readbuf, int bufsize, int *file_lock_depth, BOOL update)
     /* [previous][next][first][last][top][bottom][index][help]  */
 128 {
 129     FILE *fp = NULL;
 130 
 131     if (!*pfile)
 132     {
 133         DEBUG (0, ("startfilepwent: No file set\n"));
 134         return (NULL);
 135     }
 136     DEBUG (10, ("startfilepwent: opening file %s\n", pfile));
 137 
 138     fp = sys_fopen (pfile, update ? "r+b" : "rb");
 139 
 140     if (fp == NULL)
 141     {
 142         DEBUG (0, ("startfilepwent: unable to open file %s\n", pfile));
 143         return NULL;
 144     }
 145 
 146     /* Set a buffer to do more efficient reads */
 147     setvbuf (fp, s_readbuf, _IOFBF, bufsize);
 148 
 149     if (!file_lock (fileno (fp), (update ? F_WRLCK : F_RDLCK), 5, file_lock_depth))
 150     {
 151         DEBUG (0, ("startfilepwent: unable to lock file %s\n", pfile));
 152         fclose (fp);
 153         return NULL;
 154     }
 155 
 156     /* Make sure it is only rw by the owner */
 157     chmod (pfile, 0600);
 158 
 159     /* We have a lock on the file. */
 160     return (void *) fp;
 161 }
 162 
 163 /***************************************************************
 164  End enumeration of the file.
 165 ****************************************************************/
 166 void
 167 endfilepwent (void *vp, int *file_lock_depth)
     /* [previous][next][first][last][top][bottom][index][help]  */
 168 {
 169     FILE *fp = (FILE *) vp;
 170 
 171     file_unlock (fileno (fp), file_lock_depth);
 172     fclose (fp);
 173     DEBUG (7, ("endfilepwent: closed file.\n"));
 174 }
 175 
 176 
 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)
     /* [previous][next][first][last][top][bottom][index][help]  */
 183 {
 184     return (SMB_BIG_UINT) sys_ftell ((FILE *) vp);
 185 }
 186 
 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)
     /* [previous][next][first][last][top][bottom][index][help]  */
 193 {
 194     return !sys_fseek ((FILE *) vp, (SMB_OFF_T) tok, SEEK_SET);
 195 }
 196 
 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 *************************************************************************/
 202 int
 203 getfileline (void *vp, char *linebuf, int linebuf_size)
     /* [previous][next][first][last][top][bottom][index][help]  */
 204 {
 205     /* Static buffers we will return. */
 206     FILE *fp = (FILE *) vp;
 207     unsigned char c;
 208     unsigned char *p;
 209     size_t linebuf_len;
 210 
 211     if (fp == NULL)
 212     {
 213         DEBUG (0, ("getfileline: Bad file pointer.\n"));
 214         return -1;
 215     }
 216 
 217     /*
 218      * Scan the file, a line at a time.
 219      */
 220     while (!feof (fp))
 221     {
 222         linebuf[0] = '\0';
 223 
 224         fgets (linebuf, linebuf_size, fp);
 225         if (ferror (fp))
 226         {
 227             return -1;
 228         }
 229 
 230         /*
 231          * Check if the string is terminated with a newline - if not
 232          * then we must keep reading and discard until we get one.
 233          */
 234 
 235         linebuf_len = strlen (linebuf);
 236         if (linebuf[linebuf_len - 1] != '\n')
 237         {
 238             c = '\0';
 239             while (!ferror (fp) && !feof (fp))
 240             {
 241                 c = fgetc (fp);
 242                 if (c == '\n')
 243                 {
 244                     break;
 245                 }
 246             }
 247         }
 248         else
 249         {
 250             linebuf[linebuf_len - 1] = '\0';
 251         }
 252 
 253 #ifdef DEBUG_PASSWORD
 254         DEBUG (100, ("getfileline: got line |%s|\n", linebuf));
 255 #endif
 256         if ((linebuf[0] == 0) && feof (fp))
 257         {
 258             DEBUG (4, ("getfileline: end of file reached\n"));
 259             return 0;
 260         }
 261 
 262         if (linebuf[0] == '#' || linebuf[0] == '\0')
 263         {
 264             DEBUG (6, ("getfileline: skipping comment or blank line\n"));
 265             continue;
 266         }
 267 
 268         p = (unsigned char *) strchr (linebuf, ':');
 269         if (p == NULL)
 270         {
 271             DEBUG (0, ("getfileline: malformed line entry (no :)\n"));
 272             continue;
 273         }
 274         return linebuf_len;
 275     }
 276     return -1;
 277 }
 278 #endif /* 0 */
 279 
 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)
     /* [previous][next][first][last][top][bottom][index][help]  */
 287 {
 288     char *s = s2;
 289     int len = 0;
 290     int c;
 291     BOOL start_of_line = True;
 292 
 293     if (feof (f))
 294         return (NULL);
 295 
 296     if (!s2)
 297     {
 298         maxlen = MIN (maxlen, 8);
 299         s = (char *) Realloc (s, maxlen);
 300     }
 301 
 302     if (!s || maxlen < 2)
 303         return (NULL);
 304 
 305     *s = 0;
 306 
 307     while (len < maxlen - 1)
 308     {
 309         c = getc (f);
 310         switch (c)
 311         {
 312         case '\r':
 313             break;
 314         case '\n':
 315             while (len > 0 && s[len - 1] == ' ')
 316             {
 317                 s[--len] = 0;
 318             }
 319             if (len > 0 && s[len - 1] == '\\')
 320             {
 321                 s[--len] = 0;
 322                 start_of_line = True;
 323                 break;
 324             }
 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;
 337         }
 338         if (!s2 && len > maxlen - 3)
 339         {
 340             maxlen *= 2;
 341             s = (char *) Realloc (s, maxlen);
 342             if (!s)
 343                 return (NULL);
 344         }
 345     }
 346     return (s);
 347 }

/* [previous][next][first][last][top][bottom][index][help]  */