6 #define CPIO_NEWC_MAGIC "070701"
7 #define CPIO_CRC_MAGIC "070702"
8 #define TRAILER "TRAILER!!!"
10 /* FIXME: We don't translate between cpio and system mode bits! These
11 should both be the same, but really odd things are going to happen if
15 struct hardLink * next;
16 const char ** files; /* nlink of these, used by install */
17 int * fileMaps; /* used by build */
26 struct cpioCrcPhysicalHeader {
40 char checksum[8]; /* ignored !! */
43 #define PHYS_HDR_SIZE 110 /* don't depend on sizeof(struct) */
54 /*@owned@*/char * path;
57 static inline off_t saferead(FD_t cfd, /*@out@*/void * vbuf, size_t amount)
65 nb = Fread(buf, sizeof(buf[0]), amount, cfd);
77 static inline off_t ourread(FD_t cfd, /*@out@*/void * buf, size_t size)
79 off_t i = saferead(cfd, buf, size);
81 fdSetCpioPos(cfd, fdGetCpioPos(cfd) + i);
85 static inline void padinfd(FD_t cfd, int modulo)
90 amount = (modulo - fdGetCpioPos(cfd) % modulo) % modulo;
91 (void)ourread(cfd, buf, amount);
94 static inline off_t safewrite(FD_t cfd, const void * vbuf, size_t amount)
97 const char * buf = vbuf;
102 nb = Fwrite(buf, sizeof(buf[0]), amount, cfd);
115 static inline int padoutfd(FD_t cfd, size_t * where, int modulo)
117 static int buf[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
120 amount = (modulo - *where % modulo) % modulo;
123 if (safewrite(cfd, buf, amount) != amount)
124 return CPIOERR_WRITE_FAILED;
128 static int strntoul(const char *str, /*@out@*/char **endptr, int base, int num)
133 buf = alloca(num + 1);
134 strncpy(buf, str, num);
137 ret = strtoul(buf, &end, base);
139 *endptr = ((char *)str) + (end - buf); /* XXX discards const */
141 *endptr = ((char *)str) + strlen(str);
143 return strtoul(buf, endptr, base);
146 #define GET_NUM_FIELD(phys, log) \
147 log = strntoul(phys, &end, 16, sizeof(phys)); \
148 if (*end) return CPIOERR_BAD_HEADER;
149 #define SET_NUM_FIELD(phys, val, space) \
150 sprintf(space, "%8.8lx", (unsigned long) (val)); \
151 memcpy(phys, space, 8);
153 static int getNextHeader(FD_t cfd, /*@out@*/ struct cpioHeader * chPtr)
155 struct cpioCrcPhysicalHeader physHeader;
160 if (ourread(cfd, &physHeader, PHYS_HDR_SIZE) != PHYS_HDR_SIZE)
161 return CPIOERR_READ_FAILED;
163 if (strncmp(CPIO_CRC_MAGIC, physHeader.magic, sizeof(CPIO_CRC_MAGIC)-1) &&
164 strncmp(CPIO_NEWC_MAGIC, physHeader.magic, sizeof(CPIO_NEWC_MAGIC)-1))
165 return CPIOERR_BAD_MAGIC;
167 GET_NUM_FIELD(physHeader.inode, chPtr->inode);
168 GET_NUM_FIELD(physHeader.mode, chPtr->mode);
169 GET_NUM_FIELD(physHeader.uid, chPtr->uid);
170 GET_NUM_FIELD(physHeader.gid, chPtr->gid);
171 GET_NUM_FIELD(physHeader.nlink, chPtr->nlink);
172 GET_NUM_FIELD(physHeader.mtime, chPtr->mtime);
173 GET_NUM_FIELD(physHeader.filesize, chPtr->size);
175 GET_NUM_FIELD(physHeader.devMajor, major);
176 GET_NUM_FIELD(physHeader.devMinor, minor);
177 chPtr->dev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ;
179 GET_NUM_FIELD(physHeader.rdevMajor, major);
180 GET_NUM_FIELD(physHeader.rdevMinor, minor);
181 chPtr->rdev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ;
183 GET_NUM_FIELD(physHeader.namesize, nameSize);
185 chPtr->path = xmalloc(nameSize + 1);
186 if (ourread(cfd, chPtr->path, nameSize) != nameSize) {
189 return CPIOERR_BAD_HEADER;
192 /* this is unecessary chPtr->path[nameSize] = '\0'; */
199 int cpioFileMapCmp(const void * a, const void * b)
201 const struct cpioFileMapping * first = a;
202 const struct cpioFileMapping * second = b;
204 return (strcmp(first->archivePath, second->archivePath));
207 /* This could trash files in the path! I'm not sure that's a good thing */
208 static int createDirectory(char * path, mode_t perms)
212 if (!lstat(path, &sb)) {
213 int dounlink = 0; /* XXX eliminate, dounlink==1 on all paths */
214 if (S_ISDIR(sb.st_mode)) {
216 } else if (S_ISLNK(sb.st_mode)) {
217 if (stat(path, &sb)) {
219 return CPIOERR_STAT_FAILED;
222 if (S_ISDIR(sb.st_mode))
230 if (dounlink && unlink(path)) {
231 return CPIOERR_UNLINK_FAILED;
235 if (mkdir(path, 000))
236 return CPIOERR_MKDIR_FAILED;
238 if (chmod(path, perms))
239 return CPIOERR_CHMOD_FAILED;
244 static int setInfo(struct cpioHeader * hdr)
247 struct utimbuf stamp;
249 stamp.actime = hdr->mtime;
250 stamp.modtime = hdr->mtime;
252 if (!S_ISLNK(hdr->mode)) {
253 if (!getuid() && chown(hdr->path, hdr->uid, hdr->gid))
254 rc = CPIOERR_CHOWN_FAILED;
255 if (!rc && chmod(hdr->path, hdr->mode & 07777))
256 rc = CPIOERR_CHMOD_FAILED;
257 if (!rc && utime(hdr->path, &stamp))
258 rc = CPIOERR_UTIME_FAILED;
260 # if ! CHOWN_FOLLOWS_SYMLINK
261 if (!getuid() && !rc && lchown(hdr->path, hdr->uid, hdr->gid))
262 rc = CPIOERR_CHOWN_FAILED;
269 static int checkDirectory(const char * filename)
271 /*@only@*/ static char * lastDir = NULL; /* XXX memory leak */
272 static int lastDirLength = 0;
273 static int lastDirAlloced = 0;
274 int length = strlen(filename);
279 buf = alloca(length + 1);
280 strcpy(buf, filename);
282 for (chptr = buf + length - 1; chptr > buf; chptr--) {
283 if (*chptr == '/') break;
286 if (chptr == buf) return 0; /* /filename - no directories */
288 *chptr = '\0'; /* buffer is now just directories */
290 length = strlen(buf);
291 if (lastDirLength == length && !strcmp(buf, lastDir)) return 0;
293 if (lastDirAlloced < (length + 1)) {
294 lastDirAlloced = length + 100;
295 lastDir = xrealloc(lastDir, lastDirAlloced); /* XXX memory leak */
298 strcpy(lastDir, buf);
299 lastDirLength = length;
301 for (chptr = buf + 1; *chptr; chptr++) {
304 rc = createDirectory(buf, 0755);
309 rc = createDirectory(buf, 0755);
314 static int expandRegular(FD_t cfd, struct cpioHeader * hdr,
315 cpioCallback cb, void * cbData)
320 int left = hdr->size;
322 struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
325 /* Rename the old file before attempting unlink to avoid EBUSY errors */
326 if (!lstat(hdr->path, &sb)) {
327 strcpy(buf, hdr->path);
328 strcat(buf, "-RPMDELETE");
329 if (rename(hdr->path, buf)) {
330 fprintf(stderr, _("can't rename %s to %s: %s\n"),
331 hdr->path, buf, strerror(errno));
332 return CPIOERR_UNLINK_FAILED;
336 fprintf(stderr, _("can't unlink %s: %s\n"),
337 buf, strerror(errno));
339 return CPIOERR_UNLINK_FAILED;
344 ofd = Fopen(hdr->path, "w.ufdio");
345 if (ofd == NULL || Ferror(ofd))
346 return CPIOERR_OPEN_FAILED;
348 cbInfo.file = hdr->path;
349 cbInfo.fileSize = hdr->size;
352 bytesRead = ourread(cfd, buf, left < sizeof(buf) ? left : sizeof(buf));
353 if (bytesRead <= 0) {
354 rc = CPIOERR_READ_FAILED;
358 if (Fwrite(buf, sizeof(buf[0]), bytesRead, ofd) != bytesRead) {
359 rc = CPIOERR_COPY_FAILED;
365 /* don't call this with fileSize == fileComplete */
366 if (!rc && cb && left) {
367 cbInfo.fileComplete = hdr->size - left;
368 cbInfo.bytesProcessed = fdGetCpioPos(cfd);
378 static int expandSymlink(FD_t cfd, struct cpioHeader * hdr)
380 char buf[2048], buf2[2048];
384 if ((hdr->size + 1)> sizeof(buf))
385 return CPIOERR_HDR_SIZE;
387 if (ourread(cfd, buf, hdr->size) != hdr->size)
388 return CPIOERR_READ_FAILED;
390 buf[hdr->size] = '\0';
392 if (!lstat(hdr->path, &sb)) {
393 if (S_ISLNK(sb.st_mode)) {
394 len = readlink(hdr->path, buf2, sizeof(buf2) - 1);
397 if (!strcmp(buf, buf2)) return 0;
401 if (unlink(hdr->path))
402 return CPIOERR_UNLINK_FAILED;
405 if (symlink(buf, hdr->path) < 0)
406 return CPIOERR_SYMLINK_FAILED;
411 static int expandFifo( /*@unused@*/ FD_t cfd, struct cpioHeader * hdr)
415 if (!lstat(hdr->path, &sb)) {
416 if (S_ISFIFO(sb.st_mode)) return 0;
418 if (unlink(hdr->path))
419 return CPIOERR_UNLINK_FAILED;
422 if (mkfifo(hdr->path, 0))
423 return CPIOERR_MKFIFO_FAILED;
428 static int expandDevice( /*@unused@*/ FD_t cfd, struct cpioHeader * hdr)
432 if (!lstat(hdr->path, &sb)) {
433 if ((S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) &&
434 (sb.st_rdev == hdr->rdev))
436 if (unlink(hdr->path))
437 return CPIOERR_UNLINK_FAILED;
440 if ( /*@-unrecog@*/ mknod(hdr->path, hdr->mode & (~0777), hdr->rdev) /*@=unrecog@*/ )
441 return CPIOERR_MKNOD_FAILED;
446 static void freeLink( /*@only@*/ struct hardLink * li)
450 for (i = 0; i < li->nlink; i++) {
451 if (li->files[i] == NULL) continue;
452 /*@-unqualifiedtrans@*/ free((void *)li->files[i]) /*@=unqualifiedtrans@*/ ;
458 static int createLinks(struct hardLink * li, /*@out@*/const char ** failedFile)
463 for (i = 0; i < li->nlink; i++) {
464 if (i == li->createdPath) continue;
465 if (!li->files[i]) continue;
467 if (!lstat(li->files[i], &sb)) {
468 if (unlink(li->files[i])) {
470 *failedFile = xstrdup(li->files[i]);
471 return CPIOERR_UNLINK_FAILED;
475 if (link(li->files[li->createdPath], li->files[i])) {
477 *failedFile = xstrdup(li->files[i]);
478 return CPIOERR_LINK_FAILED;
481 /*@-unqualifiedtrans@*/ free((void *)li->files[i]) /*@=unqualifiedtrans@*/ ;
489 static int eatBytes(FD_t cfd, int amount)
495 bite = (amount > sizeof(buf)) ? sizeof(buf) : amount;
496 if (ourread(cfd, buf, bite) != bite)
497 return CPIOERR_READ_FAILED;
504 int cpioInstallArchive(FD_t cfd, struct cpioFileMapping * mappings,
505 int numMappings, cpioCallback cb, void * cbData,
506 const char ** failedFile)
508 struct cpioHeader ch;
511 struct cpioFileMapping * map = NULL;
512 struct cpioFileMapping needle;
515 struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
516 struct hardLink * links = NULL;
517 struct hardLink * li = NULL;
519 fdSetCpioPos(cfd, 0);
525 if ((rc = getNextHeader(cfd, &ch))) {
526 #if 0 /* XXX this is the failure point for an unreadable rpm */
527 fprintf(stderr, _("getNextHeader: %s\n"), cpioStrerror(rc));
532 if (!strcmp(ch.path, TRAILER)) {
533 if (ch.path) free(ch.path);
538 needle.archivePath = ch.path;
539 map = bsearch(&needle, mappings, numMappings, sizeof(needle),
543 if (mappings && !map) {
544 eatBytes(cfd, ch.size);
549 if (map->mapFlags & CPIO_MAP_PATH) {
550 if (ch.path) free(ch.path);
551 ch.path = xstrdup(map->fsPath);
554 if (map->mapFlags & CPIO_MAP_MODE)
555 ch.mode = map->finalMode;
556 if (map->mapFlags & CPIO_MAP_UID)
557 ch.uid = map->finalUid;
558 if (map->mapFlags & CPIO_MAP_GID)
559 ch.gid = map->finalGid;
562 /* This won't get hard linked symlinks right, but I can't seem
563 to create those anyway */
565 if (S_ISREG(ch.mode) && ch.nlink > 1) {
566 for (li = links; li; li = li->next) {
567 if (li->inode == ch.inode && li->dev == ch.dev) break;
571 li = xmalloc(sizeof(*li));
572 li->inode = ch.inode;
574 li->nlink = ch.nlink;
575 li->linksLeft = ch.nlink;
576 li->createdPath = -1;
577 li->files = xcalloc(li->nlink,(sizeof(*li->files)));
582 for (linkNum = 0; linkNum < li->nlink; linkNum++)
583 if (!li->files[linkNum]) break;
584 li->files[linkNum] = xstrdup(ch.path);
587 if ((ch.nlink > 1) && S_ISREG(ch.mode) && !ch.size &&
588 li->createdPath == -1) {
589 /* defer file creation */
590 } else if ((ch.nlink > 1) && S_ISREG(ch.mode) &&
591 (li->createdPath != -1)) {
592 createLinks(li, failedFile);
594 /* this only happens for cpio archives which contain
595 hardlinks w/ the contents of each hardlink being
596 listed (intead of the data being given just once. This
597 shouldn't happen, but I've made it happen w/ buggy
598 code, so what the heck? GNU cpio handles this well fwiw */
599 if (ch.size) eatBytes(cfd, ch.size);
601 rc = checkDirectory(ch.path);
604 if (S_ISREG(ch.mode))
605 rc = expandRegular(cfd, &ch, cb, cbData);
606 else if (S_ISDIR(ch.mode))
607 rc = createDirectory(ch.path, 000);
608 else if (S_ISLNK(ch.mode))
609 rc = expandSymlink(cfd, &ch);
610 else if (S_ISFIFO(ch.mode))
611 rc = expandFifo(cfd, &ch);
612 else if (S_ISCHR(ch.mode) || S_ISBLK(ch.mode))
613 rc = expandDevice(cfd, &ch);
614 else if (S_ISSOCK(ch.mode)) {
615 /* this mimicks cpio but probably isnt' right */
616 rc = expandFifo(cfd, &ch);
618 rc = CPIOERR_UNKNOWN_FILETYPE;
625 if (S_ISREG(ch.mode) && ch.nlink > 1) {
626 li->createdPath = linkNum;
628 rc = createLinks(li, failedFile);
632 if (rc && failedFile && *failedFile == NULL) {
633 *failedFile = xstrdup(ch.path);
644 cbInfo.file = ch.path;
645 cbInfo.fileSize = ch.size;
646 cbInfo.fileComplete = ch.size;
647 cbInfo.bytesProcessed = fdGetCpioPos(cfd);
651 if (ch.path) free(ch.path);
658 if (li->createdPath == -1)
659 rc = CPIOERR_MISSING_HARDLINK;
661 rc = createLinks(li, failedFile);
673 /* if an error got us here links will still be eating some memory */
684 static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map,
685 /*@out@*/size_t * sizep, int writeData)
687 struct cpioCrcPhysicalHeader hdr;
688 char buf[8192], symbuf[2048];
691 size_t size, amount = 0;
694 if (!(map->mapFlags & CPIO_MAP_PATH))
695 map->archivePath = map->fsPath;
696 if (map->mapFlags & CPIO_MAP_MODE)
697 sb.st_mode = (sb.st_mode & S_IFMT) | map->finalMode;
698 if (map->mapFlags & CPIO_MAP_UID)
699 sb.st_uid = map->finalUid;
700 if (map->mapFlags & CPIO_MAP_GID)
701 sb.st_gid = map->finalGid;
703 if (!writeData || S_ISDIR(sb.st_mode)) {
705 } else if (S_ISLNK(sb.st_mode)) {
706 /* While linux puts the size of a symlink in the st_size field,
707 I don't think that's a specified standard */
709 amount = Readlink(map->fsPath, symbuf, sizeof(symbuf));
711 return CPIOERR_READLINK_FAILED;
717 memcpy(hdr.magic, CPIO_NEWC_MAGIC, sizeof(hdr.magic));
718 SET_NUM_FIELD(hdr.inode, sb.st_ino, buf);
719 SET_NUM_FIELD(hdr.mode, sb.st_mode, buf);
720 SET_NUM_FIELD(hdr.uid, sb.st_uid, buf);
721 SET_NUM_FIELD(hdr.gid, sb.st_gid, buf);
722 SET_NUM_FIELD(hdr.nlink, sb.st_nlink, buf);
723 SET_NUM_FIELD(hdr.mtime, sb.st_mtime, buf);
724 SET_NUM_FIELD(hdr.filesize, sb.st_size, buf);
726 num = major((unsigned)sb.st_dev); SET_NUM_FIELD(hdr.devMajor, num, buf);
727 num = minor((unsigned)sb.st_dev); SET_NUM_FIELD(hdr.devMinor, num, buf);
728 num = major((unsigned)sb.st_rdev); SET_NUM_FIELD(hdr.rdevMajor, num, buf);
729 num = minor((unsigned)sb.st_rdev); SET_NUM_FIELD(hdr.rdevMinor, num, buf);
731 num = strlen(map->archivePath) + 1; SET_NUM_FIELD(hdr.namesize, num, buf);
732 memcpy(hdr.checksum, "00000000", 8);
734 if ((rc = safewrite(cfd, &hdr, PHYS_HDR_SIZE)) != PHYS_HDR_SIZE)
736 if ((rc = safewrite(cfd, map->archivePath, num)) != num)
738 size = PHYS_HDR_SIZE + num;
739 if ((rc = padoutfd(cfd, &size, 4)))
742 if (writeData && S_ISREG(sb.st_mode)) {
749 /* XXX unbuffered mmap generates *lots* of fdio debugging */
750 datafd = Fopen(map->fsPath, "r.ufdio");
751 if (datafd == NULL || Ferror(datafd))
752 return CPIOERR_OPEN_FAILED;
756 mapped = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, Fileno(datafd), 0);
757 if (mapped != (void *)-1) {
759 nmapped = sb.st_size;
770 if (mapped != (void *)-1) {
775 amount = Fread(b, sizeof(buf[0]),
776 (sb.st_size > sizeof(buf) ? sizeof(buf) : sb.st_size),
782 return CPIOERR_READ_FAILED;
786 if ((rc = safewrite(cfd, b, amount)) != amount) {
793 sb.st_size -= amount;
797 if (mapped != (void *)-1) {
798 munmap(mapped, nmapped);
803 } else if (writeData && S_ISLNK(sb.st_mode)) {
804 if ((rc = safewrite(cfd, symbuf, amount)) != amount)
809 /* this is a noop for most file types */
810 if ((rc = padoutfd(cfd, &size, 4)))
819 static int writeLinkedFile(FD_t cfd, struct hardLink * hlink,
820 struct cpioFileMapping * mappings,
821 cpioCallback cb, void * cbData,
822 /*@out@*/size_t * sizep,
823 /*@out@*/const char ** failedFile)
827 struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
831 for (i = hlink->nlink - 1; i > hlink->linksLeft; i--) {
832 if ((rc = writeFile(cfd, hlink->sb, mappings + hlink->fileMaps[i],
835 *failedFile = xstrdup(mappings[hlink->fileMaps[i]].fsPath);
842 cbInfo.file = mappings[i].archivePath;
847 if ((rc = writeFile(cfd, hlink->sb,
848 mappings + hlink->fileMaps[hlink->linksLeft],
853 *failedFile = xstrdup(mappings[hlink->fileMaps[hlink->linksLeft]].fsPath);
862 cbInfo.file = mappings[i].archivePath;
869 int cpioBuildArchive(FD_t cfd, struct cpioFileMapping * mappings,
870 int numMappings, cpioCallback cb, void * cbData,
871 unsigned int * archiveSize, const char ** failedFile)
873 size_t size, totalsize = 0;
876 struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
877 struct cpioCrcPhysicalHeader hdr;
880 struct hardLink hlinkList = { NULL };
882 struct hardLink * hlink, * parent;
884 hlinkList.next = NULL;
886 for (i = 0; i < numMappings; i++) {
887 if (mappings[i].mapFlags & CPIO_FOLLOW_SYMLINKS)
888 rc = Stat(mappings[i].fsPath, &sb);
890 rc = Lstat(mappings[i].fsPath, &sb);
894 *failedFile = xstrdup(mappings[i].fsPath);
895 return CPIOERR_STAT_FAILED;
898 if (!S_ISDIR(sb.st_mode) && sb.st_nlink > 1) {
899 hlink = hlinkList.next;
901 (hlink->dev != sb.st_dev || hlink->inode != sb.st_ino))
904 hlink = xmalloc(sizeof(*hlink));
905 hlink->next = hlinkList.next;
906 hlinkList.next = hlink;
907 hlink->sb = sb; /* structure assignment */
908 hlink->dev = sb.st_dev;
909 hlink->inode = sb.st_ino;
910 hlink->nlink = sb.st_nlink;
911 hlink->linksLeft = sb.st_nlink;
912 hlink->fileMaps = xmalloc(sizeof(*hlink->fileMaps) *
916 hlink->fileMaps[--hlink->linksLeft] = i;
918 if (!hlink->linksLeft) {
919 if ((rc = writeLinkedFile(cfd, hlink, mappings, cb, cbData,
925 free(hlink->fileMaps);
928 while (parent->next != hlink) parent = parent->next;
929 parent->next = parent->next->next;
933 if ((rc = writeFile(cfd, sb, mappings + i, &size, 1))) {
935 *failedFile = xstrdup(mappings[i].fsPath);
940 cbInfo.file = mappings[i].archivePath;
948 hlink = hlinkList.next;
950 if ((rc = writeLinkedFile(cfd, hlink, mappings, cb, cbData,
953 free(hlink->fileMaps);
961 memset(&hdr, '0', PHYS_HDR_SIZE);
962 memcpy(hdr.magic, CPIO_NEWC_MAGIC, sizeof(hdr.magic));
963 memcpy(hdr.nlink, "00000001", 8);
964 memcpy(hdr.namesize, "0000000b", 8);
965 if ((rc = safewrite(cfd, &hdr, PHYS_HDR_SIZE)) != PHYS_HDR_SIZE)
967 if ((rc = safewrite(cfd, "TRAILER!!!", 11)) != 11)
969 totalsize += PHYS_HDR_SIZE + 11;
971 /* GNU cpio pads to 512 bytes here, but we don't. I'm not sure if
974 if ((rc = padoutfd(cfd, &totalsize, 4)))
977 if (archiveSize) *archiveSize = totalsize;
982 const char * cpioStrerror(int rc)
984 static char msg[256];
986 int l, myerrno = errno;
988 strcpy(msg, "cpio: ");
991 s = msg + strlen(msg);
992 sprintf(s, _("(error 0x%x)"), (unsigned)rc);
995 case CPIOERR_BAD_MAGIC: s = _("Bad magic"); break;
996 case CPIOERR_BAD_HEADER: s = _("Bad/unreadable header");break;
998 case CPIOERR_OPEN_FAILED: s = "open"; break;
999 case CPIOERR_CHMOD_FAILED: s = "chmod"; break;
1000 case CPIOERR_CHOWN_FAILED: s = "chown"; break;
1001 case CPIOERR_WRITE_FAILED: s = "write"; break;
1002 case CPIOERR_UTIME_FAILED: s = "utime"; break;
1003 case CPIOERR_UNLINK_FAILED: s = "unlink"; break;
1004 case CPIOERR_SYMLINK_FAILED: s = "symlink"; break;
1005 case CPIOERR_STAT_FAILED: s = "stat"; break;
1006 case CPIOERR_MKDIR_FAILED: s = "mkdir"; break;
1007 case CPIOERR_MKNOD_FAILED: s = "mknod"; break;
1008 case CPIOERR_MKFIFO_FAILED: s = "mkfifo"; break;
1009 case CPIOERR_LINK_FAILED: s = "link"; break;
1010 case CPIOERR_READLINK_FAILED: s = "readlink"; break;
1011 case CPIOERR_READ_FAILED: s = "read"; break;
1012 case CPIOERR_COPY_FAILED: s = "copy"; break;
1014 case CPIOERR_HDR_SIZE: s = _("Header size too big"); break;
1015 case CPIOERR_UNKNOWN_FILETYPE: s = _("Unknown file type"); break;
1016 case CPIOERR_MISSING_HARDLINK: s = _("Missing hard link"); break;
1017 case CPIOERR_INTERNAL: s = _("Internal error"); break;
1020 l = sizeof(msg) - strlen(msg) - 1;
1022 if (l > 0) strncat(msg, s, l);
1025 if (rc & CPIOERR_CHECK_ERRNO) {
1026 s = _(" failed - ");
1027 if (l > 0) strncat(msg, s, l);
1029 if (l > 0) strncat(msg, strerror(myerrno), l);