Annotation of coherent/e/bin/pax/fileio.c, revision 1.1.1.1

1.1       root        1: /* $Source: /src386/usr/bin/pax/fileio.c,v $
                      2:  *
                      3:  * $Revision: 1.1 $
                      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.1  92/08/28  08:02:04  bin
                     34:  * Initial revision
                     35:  * 
                     36:  * Revision 1.1  89/02/14  16:47:52  jep
                     37:  * Initial revision
                     38:  * 
                     39:  * Revision 1.1  88/12/23  18:02:09  mark
                     40:  * Initial revision
                     41:  * 
                     42:  */
                     43: 
                     44: #ifndef lint
                     45: static char *ident = "$Id: fileio.c,v 1.1 92/08/28 08:02:04 bin Exp Locker: bin $";
                     46: static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
                     47: #endif /* ! lint */
                     48: 
                     49: 
                     50: /* Headers */
                     51: 
                     52: #include "pax.h"
                     53: 
                     54: #define TAPE_DEV 12    /* Tape's major number. VLAD */
                     55: 
                     56: /* open_archive -  open an archive file.  
                     57:  *
                     58:  * DESCRIPTION
                     59:  *
                     60:  *     Open_archive will open an archive file for reading or writing,
                     61:  *     setting the proper file mode, depending on the "mode" passed to
                     62:  *     it.  All buffer pointers are reset according to the mode
                     63:  *     specified.
                     64:  *
                     65:  * PARAMETERS
                     66:  *
                     67:  *     int     mode    - specifies whether we are reading or writing.   
                     68:  *
                     69:  * RETURNS
                     70:  *
                     71:  *     Returns a zero if successfull, or -1 if an error occured during 
                     72:  *     the open.
                     73:  */
                     74: 
                     75: #if __STDC__
                     76:     
                     77: int open_archive(int mode)
                     78: 
                     79: #else
                     80:     
                     81: int open_archive(mode)
                     82: int             mode;
                     83: 
                     84: #endif
                     85: {
                     86:     struct stat        ap_stat;        /* VLAD */
                     87: 
                     88:     if (ar_file[0] == '-' && ar_file[1] == '\0') {
                     89:        if (mode == AR_READ) {
                     90:            archivefd = STDIN;
                     91:            bufend = bufidx = bufstart;
                     92:        } else {
                     93:            archivefd = STDOUT;
                     94:        }
                     95:     } else if (mode == AR_READ) {
                     96:        archivefd = open(ar_file, O_RDONLY | O_BINARY);
                     97:        bufend = bufidx = bufstart;     /* set up for initial read */
                     98:     } else if (mode == AR_WRITE) {
                     99:        archivefd = open(ar_file, O_WRONLY|O_TRUNC|O_CREAT|O_BINARY, 0666);
                    100:     } else if (mode == AR_APPEND) {
                    101:        if (stat(ar_file, &ap_stat) == -1)      /* VLAD */
                    102:                fatal("cannot define the attributes of a file\n");
                    103:        if (major(ap_stat.st_rdev) == TAPE_DEV)
                    104:                fatal("option 'r' does not work with tape\n");
                    105:        archivefd = open(ar_file, O_RDWR | O_BINARY, 0666);
                    106:        bufend = bufidx = bufstart;     /* set up for initial read */
                    107:     }
                    108: 
                    109:     if (archivefd < 0) {
                    110:        warnarch(strerror(), (OFFSET) 0);
                    111:        return (-1);
                    112:     }
                    113:     ++arvolume;
                    114:     return (0);
                    115: }
                    116: 
                    117: 
                    118: /* close_archive - close the archive file
                    119:  *
                    120:  * DESCRIPTION
                    121:  *
                    122:  *     Closes the current archive and resets the archive end of file
                    123:  *     marker.
                    124:  */
                    125: 
                    126: #if __STDC__
                    127: 
                    128: void close_archive(void)
                    129: 
                    130: #else
                    131:     
                    132: void close_archive()
                    133: 
                    134: #endif
                    135: {
                    136:     if (archivefd != STDIN && archivefd != STDOUT) {
                    137:        close(archivefd);
                    138:     }
                    139:     areof = 0;
                    140: }
                    141: 
                    142: 
                    143: /* openout - open an output file
                    144:  *
                    145:  * DESCRIPTION
                    146:  *
                    147:  *     Openo opens the named file for output.  The file mode and type are
                    148:  *     set based on the values stored in the stat structure for the file.
                    149:  *     If the file is a special file, then no data will be written, the
                    150:  *     file/directory/Fifo, etc., will just be created.  Appropriate
                    151:  *     permission may be required to create special files.
                    152:  *
                    153:  * PARAMETERS
                    154:  *
                    155:  *     char    *name           - The name of the file to create
                    156:  *     Stat    *asb            - Stat structure for the file
                    157:  *     Link    *linkp;         - pointer to link chain for this file
                    158:  *     int      ispass         - true if we are operating in "pass" mode
                    159:  *
                    160:  * RETURNS
                    161:  *
                    162:  *     Returns the output file descriptor, 0 if no data is required or -1 
                    163:  *     if unsuccessful. Note that UNIX open() will never return 0 because 
                    164:  *     the standard input is in use. 
                    165:  */
                    166: 
                    167: #if __STDC__
                    168: 
                    169: int openout(char *name, Stat *asb, Link *linkp, int ispass)
                    170: 
                    171: #else
                    172:     
                    173: int openout(name, asb, linkp, ispass)
                    174: char           *name;
                    175: Stat           *asb;
                    176: Link           *linkp;
                    177: int             ispass;
                    178: 
                    179: #endif
                    180: {
                    181:     int             exists;
                    182:     int             fd;
                    183:     ushort          perm;
                    184:     ushort          operm = 0;
                    185:     Stat            osb;
                    186: #ifdef S_IFLNK
                    187:     int             ssize;
                    188:     char            sname[PATH_MAX + 1];
                    189: #endif /* S_IFLNK */
                    190: 
                    191:     if (exists = (LSTAT(name, &osb) == 0)) {
                    192:        if (ispass && osb.sb_ino == asb->sb_ino && osb.sb_dev == asb->sb_dev) {
                    193:            warn(name, "Same file");
                    194:            return (-1);
                    195:        } else if ((osb.sb_mode & S_IFMT) == (asb->sb_mode & S_IFMT)) {
                    196:            operm = osb.sb_mode & S_IPERM;
                    197:        } else if (REMOVE(name, &osb) < 0) {
                    198:            warn(name, strerror());
                    199:            return (-1);
                    200:        } else {
                    201:            exists = 0;
                    202:        }
                    203:     }
                    204:     if (linkp) {
                    205:        if (exists) {
                    206:            if (asb->sb_ino == osb.sb_ino && asb->sb_dev == osb.sb_dev) {
                    207:                return (0);
                    208:            } else if (unlink(name) < 0) {
                    209:                warn(name, strerror());
                    210:                return (-1);
                    211:            } else {
                    212:                exists = 0;
                    213:            }
                    214:        }
                    215:        if (link(linkp->l_name, name) != 0) {
                    216:            if (errno == ENOENT) {
                    217:                if (f_dir_create) {
                    218:                    if (dirneed(name) != 0 ||
                    219:                            link(linkp->l_name, name) != 0) {
                    220:                            warn(name, strerror());
                    221:                        return (-1);
                    222:                    }
                    223:                } else {
                    224:                    warn(name, 
                    225:                             "Directories are not being created (-d option)");
                    226:                }
                    227:                return(0);
                    228:            } else if (errno != EXDEV) {
                    229:                warn(name, strerror());
                    230:                return (-1);
                    231:            }
                    232:        } else {
                    233:            return(0);
                    234:        } 
                    235:     }
                    236:     perm = asb->sb_mode & S_IPERM;
                    237:     switch (asb->sb_mode & S_IFMT) {
                    238:     case S_IFBLK:
                    239:     case S_IFCHR:
                    240:        fd = 0;
                    241:        if (exists) {
                    242:            if (asb->sb_rdev == osb.sb_rdev) {
                    243:                if (perm != operm && chmod(name, (int) perm) < 0) {
                    244:                    warn(name, strerror());
                    245:                    return (-1);
                    246:                } else {
                    247:                    break;
                    248:                }
                    249:            } else if (REMOVE(name, &osb) < 0) {
                    250:                warn(name, strerror());
                    251:                return (-1);
                    252:            } else {
                    253:                exists = 0;
                    254:            }
                    255:        }
                    256:        if (mknod(name, (int) asb->sb_mode, (int) asb->sb_rdev) < 0) {
                    257:            if (errno == ENOENT) {
                    258:                if (f_dir_create) {
                    259:                    if (dirneed(name) < 0 || mknod(name, (int) asb->sb_mode, 
                    260:                           (int) asb->sb_rdev) < 0) {
                    261:                        warn(name, strerror());
                    262:                        return (-1);
                    263:                    }
                    264:                } else {
                    265:                    warn(name, "Directories are not being created (-d option)");
                    266:                }
                    267:            } else {
                    268:                warn(name, strerror());
                    269:                return (-1);
                    270:            }
                    271:        }
                    272:        return(0);
                    273:        break;
                    274:     case S_IFDIR:
                    275:        if (exists) {
                    276:            if (perm != operm && chmod(name, (int) perm) < 0) {
                    277:                warn(name, strerror());
                    278:                return (-1);
                    279:            }
                    280:        } else if (f_dir_create) {
                    281:            if (dirmake(name, asb) < 0 || dirneed(name) < 0) {
                    282:                warn(name, strerror());
                    283:                return (-1);
                    284:            }
                    285:        } else {
                    286:            warn(name, "Directories are not being created (-d option)");
                    287:        }
                    288:        return (0);
                    289: #ifdef S_IFIFO
                    290:     case S_IFIFO:
                    291:        fd = 0;
                    292:        if (exists) {
                    293:            if (perm != operm && chmod(name, (int) perm) < 0) {
                    294:                warn(name, strerror());
                    295:                return (-1);
                    296:            }
                    297:        } else if (mknod(name, (int) asb->sb_mode, 0) < 0) {
                    298:            if (errno == ENOENT) {
                    299:                if (f_dir_create) {
                    300:                    if (dirneed(name) < 0
                    301:                       || mknod(name, (int) asb->sb_mode, 0) < 0) {
                    302:                        warn(name, strerror());
                    303:                        return (-1);
                    304:                    }
                    305:                } else {
                    306:                    warn(name, "Directories are not being created (-d option)");
                    307:                }
                    308:            } else {
                    309:                warn(name, strerror());
                    310:                return (-1);
                    311:            }
                    312:        }
                    313:        return(0);
                    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 || asb->sb_gid != osb.sb_gid) {
                    389:            chown(name, (int) asb->sb_uid, (int) asb->sb_gid);
                    390:            chmod(name, perm);  /* VLAD */
                    391:        }
                    392:     }
                    393:     return (fd);
                    394: }
                    395: 
                    396: 
                    397: /* openin - open the next input file
                    398:  *
                    399:  * DESCRIPTION
                    400:  *
                    401:  *     Openi will attempt to open the next file for input.  If the file is
                    402:  *     a special file, such as a directory, FIFO, link, character- or
                    403:  *     block-special file, then the file size field of the stat structure
                    404:  *     is zeroed to make sure that no data is written out for the file.
                    405:  *     If the file is a special file, then a file descriptor of 0 is
                    406:  *     returned to the caller, which is handled specially.  If the file
                    407:  *     is a regular file, then the file is opened and a file descriptor
                    408:  *     to the open file is returned to the caller.
                    409:  *
                    410:  * PARAMETERS
                    411:  *
                    412:  *     char   *name    - pointer to the name of the file to open
                    413:  *     Stat   *asb     - pointer to the stat block for the file to open
                    414:  *
                    415:  * RETURNS
                    416:  *
                    417:  *     Returns a file descriptor, 0 if no data exists, or -1 at EOF. This 
                    418:  *     kludge works because standard input is in use, preventing open() from 
                    419:  *     returning zero. 
                    420:  */
                    421: 
                    422: #if __STDC__
                    423: 
                    424: int openin(char *name, Stat *asb)
                    425: 
                    426: #else
                    427:     
                    428: int openin(name, asb)
                    429: char           *name;          /* name of file to open */
                    430: Stat           *asb;           /* pointer to stat structure for file */
                    431: 
                    432: #endif
                    433: {
                    434:     int             fd;
                    435: 
                    436:     switch (asb->sb_mode & S_IFMT) {
                    437:     case S_IFDIR:
                    438:        asb->sb_nlink = 1;
                    439:        asb->sb_size = 0;
                    440:        return (0);
                    441: #ifdef S_IFLNK
                    442:     case S_IFLNK:
                    443:        if ((asb->sb_size = readlink(name,
                    444:                             asb->sb_link, sizeof(asb->sb_link) - 1)) < 0) {
                    445:            warn(name, strerror());
                    446:            return(0);
                    447:        }
                    448:        asb->sb_link[asb->sb_size] = '\0';
                    449:        return (0);
                    450: #endif                         /* S_IFLNK */
                    451:     case S_IFREG:
                    452:        if (asb->sb_size == 0) {
                    453:            return (0);
                    454:        }
                    455:        if ((fd = open(name, O_RDONLY | O_BINARY)) < 0) {
                    456:            warn(name, strerror());
                    457:        }
                    458:        return (fd);
                    459:     default:
                    460:        asb->sb_size = 0;
                    461:        return (0);
                    462:     }
                    463: }

unix.superglobalmegacorp.com

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