Annotation of coherent/d/usr/bin/pax/shipping/fileio.c, revision 1.1.1.1

1.1       root        1: /* $Source: /newbits/usr/bin/pax/shipping/RCS/fileio.c,v $
                      2:  *
                      3:  * $Revision: 1.2 $
                      4:  *
                      5:  * fileio.c - file I/O functions for all archive interfaces
                      6:  *
                      7:  * DESCRIPTION
                      8:  *
                      9:  *     These function all do I/O of some form or another.  They are
                     10:  *     grouped here mainly for convienence.
                     11:  *
                     12:  * AUTHOR
                     13:  *
                     14:  *     Mark H. Colburn, NAPS International ([email protected])
                     15:  *
                     16:  * Sponsored by The USENIX Association for public distribution. 
                     17:  *
                     18:  * Copyright (c) 1989 Mark H. Colburn.
                     19:  * All rights reserved.
                     20:  *
                     21:  * Redistribution and use in source and binary forms are permitted
                     22:  * provided that the above copyright notice is duplicated in all such 
                     23:  * forms and that any documentation, advertising materials, and other 
                     24:  * materials related to such distribution and use acknowledge that the 
                     25:  * software was developed * by Mark H. Colburn and sponsored by The 
                     26:  * USENIX Association. 
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     29:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     30:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     31:  *
                     32:  * $Log:       fileio.c,v $
                     33:  * Revision 1.2  91/06/19  09:55:59  bin
                     34:  * udated by vlad for restoring ownership/permissions 
                     35:  * 
                     36:  * Revision 1.1        91/02/05  11:56:02      bin
                     37:  * Initial revision
                     38:  * 
                     39:  * Revision 1.2  89/02/12  10:04:31  mark
                     40:  * 1.2 release fixes
                     41:  * 
                     42:  * Revision 1.1  88/12/23  18:02:09  mark
                     43:  * Initial revision
                     44:  * 
                     45:  */
                     46: 
                     47: #ifndef lint
                     48: static char *ident = "$Id: fileio.c,v 1.2 91/06/19 09:55:59 bin Exp Locker: bin $";
                     49: static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
                     50: #endif /* ! lint */
                     51: 
                     52: 
                     53: /* Headers */
                     54: 
                     55: #include "pax.h"
                     56: 
                     57: #define TAPE_DEV 12    /* Tape's major number */
                     58: 
                     59: /* open_archive -  open an archive file.  
                     60:  *
                     61:  * DESCRIPTION
                     62:  *
                     63:  *     Open_archive will open an archive file for reading or writing,
                     64:  *     setting the proper file mode, depending on the "mode" passed to
                     65:  *     it.  All buffer pointers are reset according to the mode
                     66:  *     specified.
                     67:  *
                     68:  * PARAMETERS
                     69:  *
                     70:  *     int     mode    - specifies whether we are reading or writing.   
                     71:  *
                     72:  * RETURNS
                     73:  *
                     74:  *     Returns a zero if successfull, or -1 if an error occured during 
                     75:  *     the open.
                     76:  */
                     77: 
                     78: #if __STDC__
                     79:     
                     80: int open_archive(int mode)
                     81: 
                     82: #else
                     83:     
                     84: int open_archive(mode)
                     85: int             mode;
                     86: 
                     87: #endif
                     88: {      
                     89:     struct stat        ap_stat;
                     90: 
                     91:    if (ar_file[0] == '-' && ar_file[1] == '\0') {
                     92:        if (mode == AR_READ) {
                     93:            archivefd = STDIN;
                     94:            bufend = bufidx = bufstart;
                     95:        } else {
                     96:            archivefd = STDOUT;
                     97:        }
                     98:     } else if (mode == AR_READ) {
                     99:        archivefd = open(ar_file, 0);
                    100:        bufend = bufidx = bufstart;     /* set up for initial read */
                    101:     } else if (mode == AR_WRITE) {
                    102:        archivefd = creat(ar_file, 0666);
                    103:     } else if (mode == AR_APPEND) {
                    104:        if (stat(ar_file, &ap_stat) == -1)
                    105:                fatal("cannot define the attributes of a file\n");
                    106:        if (major(ap_stat.st_rdev) == TAPE_DEV)
                    107:                fatal("option 'r' does not work with tape\n");
                    108:        archivefd = open(ar_file, 2);
                    109:         bufend = bufidx = bufstart;    /* set up for initial read */
                    110:     }
                    111:     if (archivefd < 0) {
                    112:        warnarch(strerror(), (OFFSET) 0);
                    113:        return (-1);
                    114:     }
                    115:     ++arvolume;
                    116:     return (0);
                    117: }
                    118: 
                    119: 
                    120: /* close_archive - close the archive file
                    121:  *
                    122:  * DESCRIPTION
                    123:  *
                    124:  *     Closes the current archive and resets the archive end of file
                    125:  *     marker.
                    126:  */
                    127: 
                    128: #if __STDC__
                    129: 
                    130: void close_archive(void)
                    131: 
                    132: #else
                    133:     
                    134: void close_archive()
                    135: 
                    136: #endif
                    137: {
                    138:     if (archivefd != STDIN && archivefd != STDOUT) {
                    139:        close(archivefd);
                    140:     }
                    141:     areof = 0;
                    142: }
                    143: 
                    144: 
                    145: /* openout - open an output file
                    146:  *
                    147:  * DESCRIPTION
                    148:  *
                    149:  *     Openo opens the named file for output.  The file mode and type are
                    150:  *     set based on the values stored in the stat structure for the file.
                    151:  *     If the file is a special file, then no data will be written, the
                    152:  *     file/directory/Fifo, etc., will just be created.  Appropriate
                    153:  *     permission may be required to create special files.
                    154:  *
                    155:  * PARAMETERS
                    156:  *
                    157:  *     char    *name           - The name of the file to create
                    158:  *     Stat    *asb            - Stat structure for the file
                    159:  *     Link    *linkp;         - pointer to link chain for this file
                    160:  *     int      ispass         - true if we are operating in "pass" mode
                    161:  *
                    162:  * RETURNS
                    163:  *
                    164:  *     Returns the output file descriptor, 0 if no data is required or -1 
                    165:  *     if unsuccessful. Note that UNIX open() will never return 0 because 
                    166:  *     the standard input is in use. 
                    167:  */
                    168: 
                    169: #if __STDC__
                    170: 
                    171: int openout(char *name, Stat *asb, Link *linkp, int ispass)
                    172: 
                    173: #else
                    174:     
                    175: int openout(name, asb, linkp, ispass)
                    176: char           *name;
                    177: Stat           *asb;
                    178: Link           *linkp;
                    179: int             ispass;
                    180: 
                    181: #endif
                    182: {
                    183:     int             exists;
                    184:     int             fd;
                    185:     ushort          perm;
                    186:     ushort          operm = 0;
                    187:     Stat            osb;
                    188: #ifdef S_IFLNK
                    189:     int             ssize;
                    190:     char            sname[PATH_MAX + 1];
                    191: #endif /* S_IFLNK */
                    192: 
                    193:    if (exists = (LSTAT(name, &osb) == 0)) {
                    194:        if (ispass && osb.sb_ino == asb->sb_ino && osb.sb_dev == asb->sb_dev) {
                    195:            warn(name, "Same file");
                    196:            return (-1);
                    197:        } else if ((osb.sb_mode & S_IFMT) == (asb->sb_mode & S_IFMT)) {
                    198:            operm = osb.sb_mode & S_IPERM;
                    199:        } else if (REMOVE(name, &osb) < 0) {
                    200:            warn(name, strerror());
                    201:            return (-1);
                    202:        } else {
                    203:            exists = 0;
                    204:        }
                    205:     }
                    206:     if (linkp) {
                    207:        if (exists) {
                    208:            if (asb->sb_ino == osb.sb_ino && asb->sb_dev == osb.sb_dev) {
                    209:                return (0);
                    210:            } else if (unlink(name) < 0) {
                    211:                warn(name, strerror());
                    212:                return (-1);
                    213:            } else {
                    214:                exists = 0;
                    215:            }
                    216:        }
                    217:        if (link(linkp->l_name, name) != 0) {
                    218:            if (errno == ENOENT) {
                    219:                if (f_dir_create) {
                    220:                    if (dirneed(name) != 0 ||
                    221:                            link(linkp->l_name, name) != 0) {
                    222:                            warn(name, strerror());
                    223:                        return (-1);
                    224:                    }
                    225:                } else {
                    226:                    warn(name, 
                    227:                             "Directories are not being created (-d option)");
                    228:                }
                    229:                return(0);
                    230:            } else if (errno != EXDEV) {
                    231:                warn(name, strerror());
                    232:                return (-1);
                    233:            }
                    234:        } else {
                    235:            return(0);
                    236:        } 
                    237:     }
                    238:     perm = asb->sb_mode & S_IPERM;
                    239:     switch (asb->sb_mode & S_IFMT) {
                    240:     case S_IFBLK: /* block/character special file */
                    241:     case S_IFCHR:
                    242:        fd = 0;
                    243:        if (exists) {
                    244:            if (asb->sb_rdev == osb.sb_rdev) {
                    245:                if (perm != operm && chmod(name, (int) perm) < 0) {
                    246:                    warn(name, strerror());
                    247:                    return (-1);
                    248:                } else {
                    249:                    break;
                    250:                }
                    251:            } else if (REMOVE(name, &osb) < 0) {
                    252:                warn(name, strerror());
                    253:                return (-1);
                    254:            } else {
                    255:                exists = 0;
                    256:            }
                    257:        }
                    258:        if (mknod(name, (int) asb->sb_mode, (int) asb->sb_rdev) < 0) {
                    259:            if (errno == ENOENT) {
                    260:                if (f_dir_create) {
                    261:                    if (dirneed(name) < 0 || mknod(name, (int) asb->sb_mode, 
                    262:                           (int) asb->sb_rdev) < 0) {
                    263:                        warn(name, strerror());
                    264:                        return (-1);
                    265:                    }
                    266:                } else {
                    267:                    warn(name, "Directories are not being created (-d option)");
                    268:                }
                    269:            } else {
                    270:                warn(name, strerror());
                    271:                return (-1);
                    272:            }
                    273:        }
                    274:        break;
                    275:     case S_IFDIR:
                    276:        if (exists) {
                    277:            if (perm != operm && chmod(name, (int) perm) < 0) {
                    278:                warn(name, strerror());
                    279:                return (-1);
                    280:            }
                    281:        } else if (f_dir_create) {
                    282:            if (dirmake(name, asb) < 0 || dirneed(name) < 0) {
                    283:                warn(name, strerror());
                    284:                return (-1);
                    285:            }
                    286:        } else {
                    287:            warn(name, "Directories are not being created (-d option)");
                    288:        }
                    289:        break;
                    290: #ifdef S_IFIFO
                    291:     case S_IFIFO:
                    292:        fd = 0;
                    293:        if (exists) {
                    294:            if (perm != operm && chmod(name, (int) perm) < 0) {
                    295:                warn(name, strerror());
                    296:                return (-1);
                    297:            }
                    298:        } else if (mknod(name, (int) asb->sb_mode, 0) < 0) {
                    299:            if (errno == ENOENT) {
                    300:                if (f_dir_create) {
                    301:                    if (dirneed(name) < 0
                    302:                       || mknod(name, (int) asb->sb_mode, 0) < 0) {
                    303:                        warn(name, strerror());
                    304:                        return (-1);
                    305:                    }
                    306:                } else {
                    307:                    warn(name, "Directories are not being created (-d option)");
                    308:                }
                    309:            } else {
                    310:                warn(name, strerror());
                    311:                return (-1);
                    312:            }
                    313:        }
                    314:        break;
                    315: #endif                         /* S_IFIFO */
                    316: #ifdef S_IFLNK
                    317:     case S_IFLNK:
                    318:        if (exists) {
                    319:            if ((ssize = readlink(name, sname, sizeof(sname))) < 0) {
                    320:                warn(name, strerror());
                    321:                return (-1);
                    322:            } else if (strncmp(sname, asb->sb_link, ssize) == 0) {
                    323:                return (0);
                    324:            } else if (REMOVE(name, &osb) < 0) {
                    325:                warn(name, strerror());
                    326:                return (-1);
                    327:            } else {
                    328:                exists = 0;
                    329:            }
                    330:        }
                    331:        if (symlink(asb->sb_link, name) < 0) {
                    332:            if (errno == ENOENT) {
                    333:                if (f_dir_create) {
                    334:                    if (dirneed(name) < 0 || symlink(asb->sb_link, name) < 0) {
                    335:                        warn(name, strerror());
                    336:                        return (-1);
                    337:                    }
                    338:                } else {
                    339:                    warn(name, "Directories are not being created (-d option)");
                    340:                }
                    341:            } else {
                    342:                warn(name, strerror());
                    343:                return (-1);
                    344:            }
                    345:        }
                    346:        return (0);             /* Can't chown()/chmod() a symbolic link */
                    347: #endif                         /* S_IFLNK */
                    348:     case S_IFREG:
                    349:        if (exists) {
                    350:            if (!f_unconditional && osb.sb_mtime > asb->sb_mtime) {
                    351:                warn(name, "Newer file exists");
                    352:                return (-1);
                    353:            } else if (unlink(name) < 0) {
                    354:                warn(name, strerror());
                    355:                return (-1);
                    356:            } else {
                    357:                exists = 0;
                    358:            }
                    359:        }
                    360:        if ((fd = creat(name, (int) perm)) < 0) {
                    361:            if (errno == ENOENT) {
                    362:                if (f_dir_create) {
                    363:                    if (dirneed(name) < 0 || 
                    364:                            (fd = creat(name, (int) perm)) < 0) {
                    365:                        warn(name, strerror());
                    366:                        return (-1);
                    367:                    }
                    368:                } else {
                    369:                    /* 
                    370:                     * the file requires a directory which does not exist
                    371:                     * and which the user does not want created, so skip
                    372:                     * the file...
                    373:                     */
                    374:                    warn(name, "Directories are not being created (-d option)");
                    375:                    return(0);
                    376:                }
                    377:            } else {
                    378:                warn(name, strerror());
                    379:                return (-1);
                    380:            }
                    381:        }
                    382:        break;
                    383:     default:
                    384:        warn(name, "Unknown filetype");
                    385:        return (-1);
                    386:     }
                    387:     if (f_owner) {
                    388:        if (!exists || (asb->sb_uid != osb.sb_uid) || 
                    389:                                        (asb->sb_gid != osb.sb_gid)) {
                    390:            chown(name, (int) asb->sb_uid, (int) asb->sb_gid);
                    391:            chmod(name, perm);
                    392:        }
                    393:     }
                    394:     return (fd);
                    395: }
                    396: 
                    397: 
                    398: /* openin - open the next input file
                    399:  *
                    400:  * DESCRIPTION
                    401:  *
                    402:  *     Openin will attempt to open the next file for input.  If the file is
                    403:  *     a special file, such as a directory, FIFO, link, character- or
                    404:  *     block-special file, then the file size field of the stat structure
                    405:  *     is zeroed to make sure that no data is written out for the file.
                    406:  *     If the file is a special file, then a file descriptor of 0 is
                    407:  *     returned to the caller, which is handled specially.  If the file
                    408:  *     is a regular file, then the file is opened and a file descriptor
                    409:  *     to the open file is returned to the caller.
                    410:  *
                    411:  * PARAMETERS
                    412:  *
                    413:  *     char   *name    - pointer to the name of the file to open
                    414:  *     Stat   *asb     - pointer to the stat block for the file to open
                    415:  *
                    416:  * RETURNS
                    417:  *
                    418:  *     Returns a file descriptor, 0 if no data exists, or -1 at EOF. This 
                    419:  *     kludge works because standard input is in use, preventing open() from 
                    420:  *     returning zero. 
                    421:  */
                    422: 
                    423: #if __STDC__
                    424: 
                    425: int openin(char *name, Stat *asb)
                    426: 
                    427: #else
                    428:     
                    429: int openin(name, asb)
                    430: char           *name;          /* name of file to open */
                    431: Stat           *asb;           /* pointer to stat structure for file */
                    432: 
                    433: #endif
                    434: {
                    435:     int             fd;
                    436: 
                    437:     switch (asb->sb_mode & S_IFMT) {
                    438:     case S_IFDIR:
                    439:        asb->sb_nlink = 1;
                    440:        asb->sb_size = 0;
                    441:        return (0);
                    442: #ifdef S_IFLNK
                    443:     case S_IFLNK:
                    444:        if ((asb->sb_size = readlink(name,
                    445:                             asb->sb_link, sizeof(asb->sb_link) - 1)) < 0) {
                    446:            warn(name, strerror());
                    447:            return(0);
                    448:        }
                    449:        asb->sb_link[asb->sb_size] = '\0';
                    450:        return (0);
                    451: #endif                         /* S_IFLNK */
                    452:     case S_IFREG:
                    453:        if (asb->sb_size == 0) {
                    454:            return (0);
                    455:        }
                    456:        if ((fd = open(name, 0)) < 0) {
                    457:            warn(name, strerror());
                    458:        }
                    459:        return (fd);
                    460:     default:
                    461:        asb->sb_size = 0;
                    462:        return (0);
                    463:     }
                    464: }

unix.superglobalmegacorp.com

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