Annotation of coherent/g/usr/lib/uucp/tay104/unix/move.c, revision 1.1

1.1     ! root        1: /* move.c
        !             2:    Move a file.
        !             3: 
        !             4:    Copyright (C) 1991, 1992 Ian Lance Taylor
        !             5: 
        !             6:    This file is part of the Taylor UUCP package.
        !             7: 
        !             8:    This program is free software; you can redistribute it and/or
        !             9:    modify it under the terms of the GNU General Public License as
        !            10:    published by the Free Software Foundation; either version 2 of the
        !            11:    License, or (at your option) any later version.
        !            12: 
        !            13:    This program is distributed in the hope that it will be useful, but
        !            14:    WITHOUT ANY WARRANTY; without even the implied warranty of
        !            15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            16:    General Public License for more details.
        !            17: 
        !            18:    You should have received a copy of the GNU General Public License
        !            19:    along with this program; if not, write to the Free Software
        !            20:    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            21: 
        !            22:    The author of the program may be contacted at [email protected] or
        !            23:    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
        !            24:    */
        !            25: 
        !            26: #include "uucp.h"
        !            27: 
        !            28: #include "uudefs.h"
        !            29: #include "sysdep.h"
        !            30: #include "system.h"
        !            31: 
        !            32: #include <errno.h>
        !            33: 
        !            34: #if HAVE_FCNTL_H
        !            35: #include <fcntl.h>
        !            36: #else
        !            37: #if HAVE_SYS_FILE_H
        !            38: #include <sys/file.h>
        !            39: #endif
        !            40: #endif
        !            41: 
        !            42: /* Move (rename) a file from one name to another.  This routine will
        !            43:    optionally create necessary directories, and fpublic indicates
        !            44:    whether the new directories should be publically accessible or not.
        !            45:    If fcheck is true, it will try to determine whether the named user
        !            46:    has write access to the new file.  */
        !            47: 
        !            48: boolean
        !            49: fsysdep_move_file (zorig, zto, fmkdirs, fpublic, fcheck, zuser)
        !            50:      const char *zorig;
        !            51:      const char *zto;
        !            52:      boolean fmkdirs;
        !            53:      boolean fpublic;
        !            54:      boolean fcheck;
        !            55:      const char *zuser;
        !            56: {
        !            57:   struct stat s;
        !            58:   int o;
        !            59: 
        !            60:   DEBUG_MESSAGE2 (DEBUG_SPOOLDIR,
        !            61:                  "fsysdep_move_file: Moving %s to %s", zorig, zto);
        !            62: 
        !            63:   /* Optionally make sure that zuser has write access on the
        !            64:      directory.  */
        !            65:   if (fcheck)
        !            66:     {
        !            67:       char *zcopy;
        !            68:       char *zslash;
        !            69: 
        !            70:       zcopy = zbufcpy (zto);
        !            71:       zslash = strrchr (zcopy, '/');
        !            72:       if (zslash == zcopy)
        !            73:        zslash[1] = '\0';
        !            74:       else
        !            75:        *zslash = '\0';
        !            76: 
        !            77:       if (stat (zcopy, &s) != 0)
        !            78:        {
        !            79:          ulog (LOG_ERROR, "stat (%s): %s", zcopy, strerror (errno));
        !            80:          (void) remove (zorig);
        !            81:          ubuffree (zcopy);
        !            82:          return FALSE;
        !            83:        }
        !            84:       if (! fsuser_access (&s, W_OK, zuser))
        !            85:        {
        !            86:          ulog (LOG_ERROR, "%s: %s", zcopy, strerror (EACCES));
        !            87:          (void) remove (zorig);
        !            88:          ubuffree (zcopy);
        !            89:          return FALSE;
        !            90:        }
        !            91:       ubuffree (zcopy);
        !            92: 
        !            93:       /* A malicious user now has a few milliseconds to change a
        !            94:         symbolic link to a directory uucp has write permission on but
        !            95:         the user does not (the obvious choice being /usr/lib/uucp).
        !            96:         The only certain method I can come up with to close this race
        !            97:         is to fork an suid process which takes on the users identity
        !            98:         and does the actual copy.  This is sufficiently high overhead
        !            99:         that I'm not going to do it.  */
        !           100:     }
        !           101: 
        !           102:   /* We try to use rename to move the file.  */
        !           103: 
        !           104:   if (rename (zorig, zto) == 0)
        !           105:     return TRUE;
        !           106: 
        !           107:   if (fmkdirs && errno == ENOENT)
        !           108:     {
        !           109:       if (! fsysdep_make_dirs (zto, fpublic))
        !           110:        {
        !           111:          (void) remove (zorig);
        !           112:          return FALSE;
        !           113:        }
        !           114:       if (rename (zorig, zto) == 0)
        !           115:        return TRUE;
        !           116:     }
        !           117: 
        !           118: #if HAVE_RENAME
        !           119:   /* On some systems the system call rename seems to fail for
        !           120:      arbitrary reasons.  To get around this, we always try to copy the
        !           121:      file by hand if the rename failed.  */
        !           122:   errno = EXDEV;
        !           123: #endif
        !           124: 
        !           125:   /* If we can't link across devices, we must copy the file by hand.  */
        !           126:   if (errno != EXDEV)
        !           127:     {
        !           128:       ulog (LOG_ERROR, "rename (%s, %s): %s", zorig, zto,
        !           129:            strerror (errno));
        !           130:       (void) remove (zorig);
        !           131:       return FALSE;
        !           132:     }
        !           133: 
        !           134:   /* Copy the file.  */
        !           135:   if (stat ((char *) zorig, &s) < 0)
        !           136:     {
        !           137:       ulog (LOG_ERROR, "stat (%s): %s", zorig, strerror (errno));
        !           138:       (void) remove (zorig);
        !           139:       return FALSE;
        !           140:     }
        !           141: 
        !           142:   /* Make sure the file gets the right mode by creating it before we
        !           143:      call fcopy_file.  */
        !           144:   (void) remove (zto);
        !           145:   o = creat ((char *) zto, s.st_mode);
        !           146:   if (o < 0)
        !           147:     {
        !           148:       if (fmkdirs && errno == ENOENT)
        !           149:        {
        !           150:          if (! fsysdep_make_dirs (zto, fpublic))
        !           151:            {
        !           152:              (void) remove (zorig);
        !           153:              return FALSE;
        !           154:            }
        !           155:          o = creat ((char *) zto, s.st_mode);
        !           156:        }
        !           157:       if (o < 0)
        !           158:        {
        !           159:          ulog (LOG_ERROR, "creat (%s): %s", zto, strerror (errno));
        !           160:          (void) remove (zorig);
        !           161:          return FALSE;
        !           162:        }
        !           163:     }
        !           164:   (void) close (o);
        !           165: 
        !           166:   if (! fcopy_file (zorig, zto, fpublic, fmkdirs))
        !           167:     {
        !           168:       (void) remove (zorig);
        !           169:       return FALSE;
        !           170:     }
        !           171: 
        !           172:   if (remove (zorig) != 0)
        !           173:     ulog (LOG_ERROR, "remove (%s): %s", zorig, strerror (errno));
        !           174: 
        !           175:   return TRUE;
        !           176: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.