Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

lib/cpio.c

Go to the documentation of this file.
00001 
00010 #include "system.h"
00011 #include <rpmlib.h>
00012 
00013 #include "fsm.h"
00014 #include "rpmerr.h"
00015 #include "debug.h"
00016 
00017 /*@access FSM_t @*/
00018 
00019 /*@-exportheadervar@*/
00020 extern int _fsm_debug;
00021 /*@=exportheadervar@*/
00022 
00031 static int strntoul(const char *str, /*@out@*/char **endptr, int base, int num)
00032         /*@modifies *endptr @*/
00033 {
00034     char * buf, * end;
00035     unsigned long ret;
00036 
00037     buf = alloca(num + 1);
00038     strncpy(buf, str, num);
00039     buf[num] = '\0';
00040 
00041     ret = strtoul(buf, &end, base);
00042     if (*end != '\0')
00043         *endptr = ((char *)str) + (end - buf);  /* XXX discards const */
00044     else
00045         *endptr = ((char *)str) + strlen(buf);
00046 
00047     return ret;
00048 }
00049 
00050 #define GET_NUM_FIELD(phys, log) \
00051         log = strntoul(phys, &end, 16, sizeof(phys)); \
00052         if ( (end - phys) != sizeof(phys) ) return CPIOERR_BAD_HEADER;
00053 #define SET_NUM_FIELD(phys, val, space) \
00054         sprintf(space, "%8.8lx", (unsigned long) (val)); \
00055         memcpy(phys, space, 8);
00056 
00057 int cpioTrailerWrite(FSM_t fsm)
00058 {
00059     struct cpioCrcPhysicalHeader * hdr =
00060         (struct cpioCrcPhysicalHeader *)fsm->rdbuf;
00061     int rc;
00062 
00063     memset(hdr, '0', PHYS_HDR_SIZE);
00064     memcpy(hdr->magic, CPIO_NEWC_MAGIC, sizeof(hdr->magic));
00065     memcpy(hdr->nlink, "00000001", 8);
00066     memcpy(hdr->namesize, "0000000b", 8);
00067     memcpy(fsm->rdbuf + PHYS_HDR_SIZE, CPIO_TRAILER, sizeof(CPIO_TRAILER));
00068 
00069     /* XXX DWRITE uses rdnb for I/O length. */
00070     fsm->rdnb = PHYS_HDR_SIZE + sizeof(CPIO_TRAILER);
00071     rc = fsmStage(fsm, FSM_DWRITE);
00072 
00073     /*
00074      * GNU cpio pads to 512 bytes here, but we don't. This may matter for
00075      * tape device(s) and/or concatenated cpio archives. <shrug>
00076      */
00077     if (!rc)
00078         rc = fsmStage(fsm, FSM_PAD);
00079 
00080     return rc;
00081 }
00082 
00083 int cpioHeaderWrite(FSM_t fsm, struct stat * st)
00084 {
00085     struct cpioCrcPhysicalHeader * hdr = (struct cpioCrcPhysicalHeader *)fsm->rdbuf;
00086     char field[64];
00087     size_t len;
00088     dev_t dev;
00089     int rc = 0;
00090 
00091     memcpy(hdr->magic, CPIO_NEWC_MAGIC, sizeof(hdr->magic));
00092     SET_NUM_FIELD(hdr->inode, st->st_ino, field);
00093     SET_NUM_FIELD(hdr->mode, st->st_mode, field);
00094     SET_NUM_FIELD(hdr->uid, st->st_uid, field);
00095     SET_NUM_FIELD(hdr->gid, st->st_gid, field);
00096     SET_NUM_FIELD(hdr->nlink, st->st_nlink, field);
00097     SET_NUM_FIELD(hdr->mtime, st->st_mtime, field);
00098     SET_NUM_FIELD(hdr->filesize, st->st_size, field);
00099 
00100     dev = major((unsigned)st->st_dev); SET_NUM_FIELD(hdr->devMajor, dev, field);
00101     dev = minor((unsigned)st->st_dev); SET_NUM_FIELD(hdr->devMinor, dev, field);
00102     dev = major((unsigned)st->st_rdev); SET_NUM_FIELD(hdr->rdevMajor, dev, field);
00103     dev = minor((unsigned)st->st_rdev); SET_NUM_FIELD(hdr->rdevMinor, dev, field);
00104 
00105     len = strlen(fsm->path) + 1; SET_NUM_FIELD(hdr->namesize, len, field);
00106     memcpy(hdr->checksum, "00000000", 8);
00107     memcpy(fsm->rdbuf + PHYS_HDR_SIZE, fsm->path, len);
00108 
00109     /* XXX DWRITE uses rdnb for I/O length. */
00110     fsm->rdnb = PHYS_HDR_SIZE + len;
00111     rc = fsmStage(fsm, FSM_DWRITE);
00112     if (!rc && fsm->rdnb != fsm->wrnb)
00113         rc = CPIOERR_WRITE_FAILED;
00114     if (!rc)
00115         rc = fsmStage(fsm, FSM_PAD);
00116     return rc;
00117 }
00118 
00119 int cpioHeaderRead(FSM_t fsm, struct stat * st)
00120         /*@modifies fsm, *st @*/
00121 {
00122     struct cpioCrcPhysicalHeader hdr;
00123     int nameSize;
00124     char * end;
00125     int major, minor;
00126     int rc = 0;
00127 
00128     fsm->wrlen = PHYS_HDR_SIZE;
00129     rc = fsmStage(fsm, FSM_DREAD);
00130     if (!rc && fsm->rdnb != fsm->wrlen)
00131         rc = CPIOERR_READ_FAILED;
00132     if (rc) return rc;
00133     memcpy(&hdr, fsm->wrbuf, fsm->rdnb);
00134 
00135     if (strncmp(CPIO_CRC_MAGIC, hdr.magic, sizeof(CPIO_CRC_MAGIC)-1) &&
00136         strncmp(CPIO_NEWC_MAGIC, hdr.magic, sizeof(CPIO_NEWC_MAGIC)-1))
00137         return CPIOERR_BAD_MAGIC;
00138 
00139     GET_NUM_FIELD(hdr.inode, st->st_ino);
00140     GET_NUM_FIELD(hdr.mode, st->st_mode);
00141     GET_NUM_FIELD(hdr.uid, st->st_uid);
00142     GET_NUM_FIELD(hdr.gid, st->st_gid);
00143     GET_NUM_FIELD(hdr.nlink, st->st_nlink);
00144     GET_NUM_FIELD(hdr.mtime, st->st_mtime);
00145     GET_NUM_FIELD(hdr.filesize, st->st_size);
00146 
00147     GET_NUM_FIELD(hdr.devMajor, major);
00148     GET_NUM_FIELD(hdr.devMinor, minor);
00149     st->st_dev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ;
00150 
00151     GET_NUM_FIELD(hdr.rdevMajor, major);
00152     GET_NUM_FIELD(hdr.rdevMinor, minor);
00153     st->st_rdev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ;
00154 
00155     GET_NUM_FIELD(hdr.namesize, nameSize);
00156     if (nameSize >= fsm->wrsize)
00157         return CPIOERR_BAD_HEADER;
00158 
00159     {   char * t = xmalloc(nameSize + 1);
00160         fsm->wrlen = nameSize;
00161         rc = fsmStage(fsm, FSM_DREAD);
00162         if (!rc && fsm->rdnb != fsm->wrlen)
00163             rc = CPIOERR_BAD_HEADER;
00164         if (rc) {
00165             t = _free(t);
00166             fsm->path = NULL;
00167             return rc;
00168         }
00169         memcpy(t, fsm->wrbuf, fsm->rdnb);
00170         t[nameSize] = '\0';
00171         fsm->path = t;
00172     }
00173 
00174     return 0;
00175 }
00176 
00177 const char *const cpioStrerror(int rc)
00178 {
00179     static char msg[256];
00180     char *s;
00181     int l, myerrno = errno;
00182 
00183     strcpy(msg, "cpio: ");
00184     switch (rc) {
00185     default:
00186         s = msg + strlen(msg);
00187         sprintf(s, _("(error 0x%x)"), (unsigned)rc);
00188         s = NULL;
00189         break;
00190     case CPIOERR_BAD_MAGIC:     s = _("Bad magic");             break;
00191     case CPIOERR_BAD_HEADER:    s = _("Bad/unreadable  header");break;
00192 
00193     case CPIOERR_OPEN_FAILED:   s = "open";     break;
00194     case CPIOERR_CHMOD_FAILED:  s = "chmod";    break;
00195     case CPIOERR_CHOWN_FAILED:  s = "chown";    break;
00196     case CPIOERR_WRITE_FAILED:  s = "write";    break;
00197     case CPIOERR_UTIME_FAILED:  s = "utime";    break;
00198     case CPIOERR_UNLINK_FAILED: s = "unlink";   break;
00199     case CPIOERR_RENAME_FAILED: s = "rename";   break;
00200     case CPIOERR_SYMLINK_FAILED: s = "symlink"; break;
00201     case CPIOERR_STAT_FAILED:   s = "stat";     break;
00202     case CPIOERR_LSTAT_FAILED:  s = "lstat";    break;
00203     case CPIOERR_MKDIR_FAILED:  s = "mkdir";    break;
00204     case CPIOERR_RMDIR_FAILED:  s = "rmdir";    break;
00205     case CPIOERR_MKNOD_FAILED:  s = "mknod";    break;
00206     case CPIOERR_MKFIFO_FAILED: s = "mkfifo";   break;
00207     case CPIOERR_LINK_FAILED:   s = "link";     break;
00208     case CPIOERR_READLINK_FAILED: s = "readlink";       break;
00209     case CPIOERR_READ_FAILED:   s = "read";     break;
00210     case CPIOERR_COPY_FAILED:   s = "copy";     break;
00211 
00212     case CPIOERR_HDR_SIZE:      s = _("Header size too big");   break;
00213     case CPIOERR_UNKNOWN_FILETYPE: s = _("Unknown file type");  break;
00214     case CPIOERR_MISSING_HARDLINK: s = _("Missing hard link(s)"); break;
00215     case CPIOERR_MD5SUM_MISMATCH: s = _("MD5 sum mismatch");    break;
00216     case CPIOERR_INTERNAL:      s = _("Internal error");        break;
00217     case CPIOERR_UNMAPPED_FILE: s = _("Archive file not in header"); break;
00218     }
00219 
00220     l = sizeof(msg) - strlen(msg) - 1;
00221     if (s != NULL) {
00222         if (l > 0) strncat(msg, s, l);
00223         l -= strlen(s);
00224     }
00225     if ((rc & CPIOERR_CHECK_ERRNO) && myerrno) {
00226         s = _(" failed - ");
00227         if (l > 0) strncat(msg, s, l);
00228         l -= strlen(s);
00229         if (l > 0) strncat(msg, strerror(myerrno), l);
00230     }
00231     return msg;
00232 }

Generated at Wed Mar 27 03:56:48 2002 for rpm by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001