3 * Handle cpio payloads within rpm packages.
5 * \warning FIXME: We don't translate between cpio and system mode bits! These
6 * should both be the same, but really odd things are going to happen if
13 #include <sys/mkdev.h>
14 #elif MAJOR_IN_SYSMACROS
15 #include <sys/sysmacros.h>
17 #include <sys/types.h> /* already included from system.h */
21 #include <rpm/rpmio.h>
22 #include <rpm/rpmlog.h>
31 * Convert string to unsigned integer (with buffer size check).
32 * @param str input string
33 * @retval endptr address of 1st character not processed
34 * @param base numerical conversion base
35 * @param num max no. of bytes to read
36 * @return converted integer
38 static unsigned long strntoul(const char *str,char **endptr, int base, size_t num)
40 char buf[num+1], * end;
43 strncpy(buf, str, num);
46 ret = strtoul(buf, &end, base);
48 *endptr = ((char *)str) + (end - buf); /* XXX discards const */
50 *endptr = ((char *)str) + strlen(buf);
55 #define GET_NUM_FIELD(phys, log) \
57 log = strntoul(phys, &end, 16, sizeof(phys)); \
59 if ( (end - phys) != sizeof(phys) ) return CPIOERR_BAD_HEADER;
60 #define SET_NUM_FIELD(phys, val, space) \
61 sprintf(space, "%8.8lx", (unsigned long) (val)); \
63 memcpy(phys, space, 8) \
65 int cpioTrailerWrite(FSM_t fsm)
67 struct cpioCrcPhysicalHeader * hdr =
68 (struct cpioCrcPhysicalHeader *)fsm->rdbuf;
71 memset(hdr, '0', PHYS_HDR_SIZE);
72 memcpy(hdr->magic, CPIO_NEWC_MAGIC, sizeof(hdr->magic));
73 memcpy(hdr->nlink, "00000001", 8);
74 memcpy(hdr->namesize, "0000000b", 8);
75 memcpy(fsm->rdbuf + PHYS_HDR_SIZE, CPIO_TRAILER, sizeof(CPIO_TRAILER));
77 /* XXX DWRITE uses rdnb for I/O length. */
78 fsm->rdnb = PHYS_HDR_SIZE + sizeof(CPIO_TRAILER);
79 rc = fsmNext(fsm, FSM_DWRITE);
82 * GNU cpio pads to 512 bytes here, but we don't. This may matter for
83 * tape device(s) and/or concatenated cpio archives. <shrug>
86 rc = fsmNext(fsm, FSM_PAD);
91 int cpioHeaderWrite(FSM_t fsm, struct stat * st)
93 struct cpioCrcPhysicalHeader * hdr = (struct cpioCrcPhysicalHeader *)fsm->rdbuf;
99 memcpy(hdr->magic, CPIO_NEWC_MAGIC, sizeof(hdr->magic));
100 SET_NUM_FIELD(hdr->inode, st->st_ino, field);
101 SET_NUM_FIELD(hdr->mode, st->st_mode, field);
102 SET_NUM_FIELD(hdr->uid, st->st_uid, field);
103 SET_NUM_FIELD(hdr->gid, st->st_gid, field);
104 SET_NUM_FIELD(hdr->nlink, st->st_nlink, field);
105 SET_NUM_FIELD(hdr->mtime, st->st_mtime, field);
106 SET_NUM_FIELD(hdr->filesize, st->st_size, field);
108 dev = major(st->st_dev); SET_NUM_FIELD(hdr->devMajor, dev, field);
109 dev = minor(st->st_dev); SET_NUM_FIELD(hdr->devMinor, dev, field);
110 dev = major(st->st_rdev); SET_NUM_FIELD(hdr->rdevMajor, dev, field);
111 dev = minor(st->st_rdev); SET_NUM_FIELD(hdr->rdevMinor, dev, field);
113 len = strlen(fsm->path) + 1; SET_NUM_FIELD(hdr->namesize, len, field);
114 memcpy(hdr->checksum, "00000000", 8);
115 memcpy(fsm->rdbuf + PHYS_HDR_SIZE, fsm->path, len);
117 /* XXX DWRITE uses rdnb for I/O length. */
118 fsm->rdnb = PHYS_HDR_SIZE + len;
119 rc = fsmNext(fsm, FSM_DWRITE);
120 if (!rc && fsm->rdnb != fsm->wrnb)
121 rc = CPIOERR_WRITE_FAILED;
123 rc = fsmNext(fsm, FSM_PAD);
127 int cpioHeaderRead(FSM_t fsm, struct stat * st)
129 struct cpioCrcPhysicalHeader hdr;
132 unsigned int major, minor;
136 fsm->wrlen = PHYS_HDR_SIZE;
137 rc = fsmNext(fsm, FSM_DREAD);
138 if (!rc && fsm->rdnb != fsm->wrlen)
139 rc = CPIOERR_READ_FAILED;
141 memcpy(&hdr, fsm->wrbuf, fsm->rdnb);
143 if (strncmp(CPIO_CRC_MAGIC, hdr.magic, sizeof(CPIO_CRC_MAGIC)-1) &&
144 strncmp(CPIO_NEWC_MAGIC, hdr.magic, sizeof(CPIO_NEWC_MAGIC)-1))
145 return CPIOERR_BAD_MAGIC;
147 GET_NUM_FIELD(hdr.inode, st->st_ino);
148 GET_NUM_FIELD(hdr.mode, st->st_mode);
149 GET_NUM_FIELD(hdr.uid, st->st_uid);
150 GET_NUM_FIELD(hdr.gid, st->st_gid);
151 GET_NUM_FIELD(hdr.nlink, st->st_nlink);
152 GET_NUM_FIELD(hdr.mtime, st->st_mtime);
153 GET_NUM_FIELD(hdr.filesize, st->st_size);
155 GET_NUM_FIELD(hdr.devMajor, major);
156 GET_NUM_FIELD(hdr.devMinor, minor);
157 st->st_dev = makedev(major, minor);
159 GET_NUM_FIELD(hdr.rdevMajor, major);
160 GET_NUM_FIELD(hdr.rdevMinor, minor);
161 st->st_rdev = makedev(major, minor);
163 GET_NUM_FIELD(hdr.namesize, nameSize);
164 if (nameSize >= fsm->wrsize)
165 return CPIOERR_BAD_HEADER;
167 fsm->wrlen = nameSize;
168 rc = fsmNext(fsm, FSM_DREAD);
169 if (!rc && fsm->rdnb != fsm->wrlen)
170 rc = CPIOERR_BAD_HEADER;
173 path = xmalloc(nameSize + 1);
174 memcpy(path, fsm->wrbuf, fsm->rdnb);
175 path[nameSize] = '\0';
181 const char * cpioStrerror(int rc)
183 static char msg[256];
188 strcpy(msg, "cpio: ");
191 char *t = msg + strlen(msg);
192 sprintf(t, _("(error 0x%x)"), (unsigned)rc);
196 case CPIOERR_BAD_MAGIC: s = _("Bad magic"); break;
197 case CPIOERR_BAD_HEADER: s = _("Bad/unreadable header");break;
199 case CPIOERR_OPEN_FAILED: s = "open"; break;
200 case CPIOERR_CHMOD_FAILED: s = "chmod"; break;
201 case CPIOERR_CHOWN_FAILED: s = "chown"; break;
202 case CPIOERR_WRITE_FAILED: s = "write"; break;
203 case CPIOERR_UTIME_FAILED: s = "utime"; break;
204 case CPIOERR_UNLINK_FAILED: s = "unlink"; break;
205 case CPIOERR_RENAME_FAILED: s = "rename"; break;
206 case CPIOERR_SYMLINK_FAILED: s = "symlink"; break;
207 case CPIOERR_STAT_FAILED: s = "stat"; break;
208 case CPIOERR_LSTAT_FAILED: s = "lstat"; break;
209 case CPIOERR_MKDIR_FAILED: s = "mkdir"; break;
210 case CPIOERR_RMDIR_FAILED: s = "rmdir"; break;
211 case CPIOERR_MKNOD_FAILED: s = "mknod"; break;
212 case CPIOERR_MKFIFO_FAILED: s = "mkfifo"; break;
213 case CPIOERR_LINK_FAILED: s = "link"; break;
214 case CPIOERR_READLINK_FAILED: s = "readlink"; break;
215 case CPIOERR_READ_FAILED: s = "read"; break;
216 case CPIOERR_COPY_FAILED: s = "copy"; break;
217 case CPIOERR_LSETFCON_FAILED: s = "lsetfilecon"; break;
218 case CPIOERR_SETCAP_FAILED: s = "cap_set_file"; break;
220 case CPIOERR_HDR_SIZE: s = _("Header size too big"); break;
221 case CPIOERR_UNKNOWN_FILETYPE: s = _("Unknown file type"); break;
222 case CPIOERR_MISSING_HARDLINK: s = _("Missing hard link(s)"); break;
223 case CPIOERR_DIGEST_MISMATCH: s = _("Digest mismatch"); break;
224 case CPIOERR_INTERNAL: s = _("Internal error"); break;
225 case CPIOERR_UNMAPPED_FILE: s = _("Archive file not in header"); break;
226 case CPIOERR_ENOENT: s = strerror(ENOENT); break;
227 case CPIOERR_ENOTEMPTY: s = strerror(ENOTEMPTY); break;
230 l = sizeof(msg) - strlen(msg) - 1;
232 if (l > 0) strncat(msg, s, l);
235 if ((rc & CPIOERR_CHECK_ERRNO) && myerrno) {
237 if (l > 0) strncat(msg, s, l);
239 if (l > 0) strncat(msg, strerror(myerrno), l);