1*57198Smuller /*- 2*57198Smuller * Copyright (c) 1992 Keith Muller. 3*57198Smuller * Copyright (c) 1992 The Regents of the University of California. 4*57198Smuller * All rights reserved. 5*57198Smuller * 6*57198Smuller * This code is derived from software contributed to Berkeley by 7*57198Smuller * Keith Muller of the University of California, San Diego. 8*57198Smuller * 9*57198Smuller * %sccs.include.redist.c% 10*57198Smuller */ 11*57198Smuller 12*57198Smuller #ifndef lint 13*57198Smuller static char sccsid[] = "@(#)cpio.c 1.1 (Berkeley) 12/18/92"; 14*57198Smuller #endif /* not lint */ 15*57198Smuller 16*57198Smuller #include <sys/types.h> 17*57198Smuller #include <sys/time.h> 18*57198Smuller #include <sys/stat.h> 19*57198Smuller #include <sys/param.h> 20*57198Smuller #include <string.h> 21*57198Smuller #include <ctype.h> 22*57198Smuller #include <stdio.h> 23*57198Smuller #include <unistd.h> 24*57198Smuller #include <stdlib.h> 25*57198Smuller #include "pax.h" 26*57198Smuller #include "cpio.h" 27*57198Smuller #include "extern.h" 28*57198Smuller static int rd_nm __P((register ARCHD *, int)); 29*57198Smuller static int rd_ln_nm __P((register ARCHD *)); 30*57198Smuller static int com_rd __P((register ARCHD *)); 31*57198Smuller 32*57198Smuller /* 33*57198Smuller * Routines which support the different cpio versions 34*57198Smuller */ 35*57198Smuller 36*57198Smuller static int swp_head; /* binary cpio header byte swap */ 37*57198Smuller 38*57198Smuller /* 39*57198Smuller * Routines common to all versions of cpio 40*57198Smuller */ 41*57198Smuller 42*57198Smuller /* 43*57198Smuller * cpio_strd() 44*57198Smuller * Fire up the hard link detection code 45*57198Smuller * Return: 46*57198Smuller * 0 if ok -1 otherwise (the return values of lnk_start()) 47*57198Smuller */ 48*57198Smuller 49*57198Smuller #if __STDC__ 50*57198Smuller int 51*57198Smuller cpio_strd(void) 52*57198Smuller #else 53*57198Smuller int 54*57198Smuller cpio_strd() 55*57198Smuller #endif 56*57198Smuller { 57*57198Smuller return(lnk_start()); 58*57198Smuller } 59*57198Smuller 60*57198Smuller /* 61*57198Smuller * cpio_trail() 62*57198Smuller * Called to determine if a header block is a valid trailer. We are 63*57198Smuller * passed the block, the in_sync flag (which tells us we are in resync 64*57198Smuller * mode; looking for a valid header), and cnt (which starts at zero) 65*57198Smuller * which is used to count the number of empty blocks we have seen so far. 66*57198Smuller * Return: 67*57198Smuller * 0 if a valid trailer, -1 if not a valid trailer, 68*57198Smuller */ 69*57198Smuller 70*57198Smuller #if __STDC__ 71*57198Smuller int 72*57198Smuller cpio_trail(register ARCHD *arcn) 73*57198Smuller #else 74*57198Smuller int 75*57198Smuller cpio_trail(arcn) 76*57198Smuller register ARCHD *arcn; 77*57198Smuller #endif 78*57198Smuller { 79*57198Smuller /* 80*57198Smuller * look for trailer id in file we are about to process 81*57198Smuller */ 82*57198Smuller if ((strcmp(arcn->name, TRAILER) == 0) && (arcn->sb.st_size == 0)) 83*57198Smuller return(0); 84*57198Smuller return(-1); 85*57198Smuller } 86*57198Smuller 87*57198Smuller /* 88*57198Smuller * com_rd() 89*57198Smuller * operations common to all cpio read functions. 90*57198Smuller * Return: 91*57198Smuller * 0 92*57198Smuller */ 93*57198Smuller 94*57198Smuller #if __STDC__ 95*57198Smuller static int 96*57198Smuller com_rd(register ARCHD *arcn) 97*57198Smuller #else 98*57198Smuller static int 99*57198Smuller com_rd(arcn) 100*57198Smuller register ARCHD *arcn; 101*57198Smuller #endif 102*57198Smuller { 103*57198Smuller arcn->skip = 0; 104*57198Smuller arcn->pat = NULL; 105*57198Smuller arcn->org_name = arcn->name; 106*57198Smuller switch(arcn->sb.st_mode & C_IFMT) { 107*57198Smuller case C_ISFIFO: 108*57198Smuller arcn->type = PAX_FIF; 109*57198Smuller break; 110*57198Smuller case C_ISDIR: 111*57198Smuller arcn->type = PAX_DIR; 112*57198Smuller break; 113*57198Smuller case C_ISBLK: 114*57198Smuller arcn->type = PAX_BLK; 115*57198Smuller break; 116*57198Smuller case C_ISCHR: 117*57198Smuller arcn->type = PAX_CHR; 118*57198Smuller break; 119*57198Smuller case C_ISLNK: 120*57198Smuller arcn->type = PAX_SLK; 121*57198Smuller break; 122*57198Smuller case C_ISOCK: 123*57198Smuller arcn->type = PAX_SCK; 124*57198Smuller break; 125*57198Smuller case C_ISCTG: 126*57198Smuller case C_ISREG: 127*57198Smuller default: 128*57198Smuller /* 129*57198Smuller * we have file data, set up skip (pad is set in the format 130*57198Smuller * specific sections) 131*57198Smuller */ 132*57198Smuller arcn->sb.st_mode = (arcn->sb.st_mode & 0xfff) | C_ISREG; 133*57198Smuller arcn->type = PAX_REG; 134*57198Smuller arcn->skip = arcn->sb.st_size; 135*57198Smuller break; 136*57198Smuller } 137*57198Smuller if (chk_lnk(arcn) < 0) 138*57198Smuller return(-1); 139*57198Smuller return(0); 140*57198Smuller } 141*57198Smuller 142*57198Smuller /* 143*57198Smuller * cpio_end_wr() 144*57198Smuller * write the special file with the name trailer in the proper format 145*57198Smuller * Return: 146*57198Smuller * result of the write of the trailer from the cpio specific write func 147*57198Smuller */ 148*57198Smuller 149*57198Smuller #if __STDC__ 150*57198Smuller int 151*57198Smuller cpio_endwr(void) 152*57198Smuller #else 153*57198Smuller int 154*57198Smuller cpio_endwr() 155*57198Smuller #endif 156*57198Smuller { 157*57198Smuller ARCHD last; 158*57198Smuller 159*57198Smuller /* 160*57198Smuller * create a trailer request and call the proper format write function 161*57198Smuller */ 162*57198Smuller bzero((char *)&last, sizeof(last)); 163*57198Smuller last.nlen = sizeof(TRAILER) - 1; 164*57198Smuller last.type = PAX_REG; 165*57198Smuller last.sb.st_nlink = 1; 166*57198Smuller (void)strcpy(last.name, TRAILER); 167*57198Smuller return((*frmt->wr)(&last)); 168*57198Smuller } 169*57198Smuller 170*57198Smuller /* 171*57198Smuller * rd_nam() 172*57198Smuller * read in the file name which follows the cpio header 173*57198Smuller * Return: 174*57198Smuller * 0 if ok, -1 otherwise 175*57198Smuller */ 176*57198Smuller 177*57198Smuller #if __STDC__ 178*57198Smuller static int 179*57198Smuller rd_nm(register ARCHD *arcn, int nsz) 180*57198Smuller #else 181*57198Smuller static int 182*57198Smuller rd_nm(arcn, nsz) 183*57198Smuller register ARCHD *arcn; 184*57198Smuller int nsz; 185*57198Smuller #endif 186*57198Smuller { 187*57198Smuller /* 188*57198Smuller * do not even try bogus values 189*57198Smuller */ 190*57198Smuller if ((nsz == 0) || (nsz > sizeof(arcn->name))) { 191*57198Smuller warn(1, "Cpio file name length %d is out of range", nsz); 192*57198Smuller return(-1); 193*57198Smuller } 194*57198Smuller 195*57198Smuller /* 196*57198Smuller * read the name and make sure it is not empty and is \0 terminated 197*57198Smuller */ 198*57198Smuller if ((rd_wrbuf(arcn->name,nsz) != nsz) || (arcn->name[nsz-1] != '\0') || 199*57198Smuller (arcn->name[0] == '\0')) { 200*57198Smuller warn(1, "Cpio file name in header is corrupted"); 201*57198Smuller return(-1); 202*57198Smuller } 203*57198Smuller return(0); 204*57198Smuller } 205*57198Smuller 206*57198Smuller /* 207*57198Smuller * rd_ln_nm() 208*57198Smuller * read in the link name for a file with links. The link name is stored 209*57198Smuller * like file data (and is NOT \0 terminated!) 210*57198Smuller * Return: 211*57198Smuller * 0 if ok, -1 otherwise 212*57198Smuller */ 213*57198Smuller 214*57198Smuller #if __STDC__ 215*57198Smuller static int 216*57198Smuller rd_ln_nm(register ARCHD *arcn) 217*57198Smuller #else 218*57198Smuller static int 219*57198Smuller rd_ln_nm(arcn) 220*57198Smuller register ARCHD *arcn; 221*57198Smuller #endif 222*57198Smuller { 223*57198Smuller /* 224*57198Smuller * check the length specified for bogus values 225*57198Smuller */ 226*57198Smuller if ((arcn->sb.st_size == 0) || 227*57198Smuller (arcn->sb.st_size >= sizeof(arcn->ln_name))) { 228*57198Smuller # ifdef NET2_STAT 229*57198Smuller warn(1, "Cpio link name length is invalid: %lu", 230*57198Smuller arcn->sb.st_size); 231*57198Smuller # else 232*57198Smuller warn(1, "Cpio link name length is invalid: %qu", 233*57198Smuller arcn->sb.st_size); 234*57198Smuller # endif 235*57198Smuller return(-1); 236*57198Smuller } 237*57198Smuller 238*57198Smuller /* 239*57198Smuller * read in the link name and \0 terminate it 240*57198Smuller */ 241*57198Smuller if (rd_wrbuf(arcn->ln_name, (int)arcn->sb.st_size) != 242*57198Smuller (int)arcn->sb.st_size) { 243*57198Smuller warn(1, "Cpio link name read error"); 244*57198Smuller return(-1); 245*57198Smuller } 246*57198Smuller arcn->ln_nlen = arcn->sb.st_size; 247*57198Smuller arcn->ln_name[arcn->ln_nlen] = '\0'; 248*57198Smuller 249*57198Smuller /* 250*57198Smuller * watch out for those empty link names 251*57198Smuller */ 252*57198Smuller if (arcn->ln_name[0] == '\0') { 253*57198Smuller warn(1, "Cpio link name is corrupt"); 254*57198Smuller return(-1); 255*57198Smuller } 256*57198Smuller return(0); 257*57198Smuller } 258*57198Smuller 259*57198Smuller /* 260*57198Smuller * Routines common to the extended byte oriented cpio format 261*57198Smuller */ 262*57198Smuller 263*57198Smuller /* 264*57198Smuller * cpio_id() 265*57198Smuller * determine if a block given to us is a valid extended byte oriented 266*57198Smuller * cpio header 267*57198Smuller * Return: 268*57198Smuller * 0 if a valid header, -1 otherwise 269*57198Smuller */ 270*57198Smuller 271*57198Smuller #if __STDC__ 272*57198Smuller int 273*57198Smuller cpio_id(char *blk, int size) 274*57198Smuller #else 275*57198Smuller int 276*57198Smuller cpio_id(blk, size) 277*57198Smuller char *blk; 278*57198Smuller int size; 279*57198Smuller #endif 280*57198Smuller { 281*57198Smuller if ((size < sizeof(HD_CPIO)) || 282*57198Smuller (strncmp(blk, AMAGIC, sizeof(AMAGIC) - 1) != 0)) 283*57198Smuller return(-1); 284*57198Smuller return(0); 285*57198Smuller } 286*57198Smuller 287*57198Smuller /* 288*57198Smuller * cpio_rd() 289*57198Smuller * determine if a buffer is a byte oriented extended cpio archive entry. 290*57198Smuller * convert and store the values in the ARCHD parameter. 291*57198Smuller * Return: 292*57198Smuller * 0 if a valid header, -1 otherwise. 293*57198Smuller */ 294*57198Smuller 295*57198Smuller #if __STDC__ 296*57198Smuller int 297*57198Smuller cpio_rd(register ARCHD *arcn, register char *buf) 298*57198Smuller #else 299*57198Smuller int 300*57198Smuller cpio_rd(arcn, buf) 301*57198Smuller register ARCHD *arcn; 302*57198Smuller register char *buf; 303*57198Smuller #endif 304*57198Smuller { 305*57198Smuller register int nsz; 306*57198Smuller register HD_CPIO *hd; 307*57198Smuller 308*57198Smuller /* 309*57198Smuller * check that this is a valid header, if not return -1 310*57198Smuller */ 311*57198Smuller if (cpio_id(buf, sizeof(HD_CPIO)) < 0) 312*57198Smuller return(-1); 313*57198Smuller hd = (HD_CPIO *)buf; 314*57198Smuller 315*57198Smuller /* 316*57198Smuller * byte oriented cpio (posix) does not have padding! extract the octal 317*57198Smuller * ascii fields from the header 318*57198Smuller */ 319*57198Smuller arcn->pad = 0L; 320*57198Smuller arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT); 321*57198Smuller arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT); 322*57198Smuller arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT); 323*57198Smuller arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT); 324*57198Smuller arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT); 325*57198Smuller arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), 326*57198Smuller OCT); 327*57198Smuller arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT); 328*57198Smuller arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime), 329*57198Smuller OCT); 330*57198Smuller arcn->sb.st_atime = arcn->sb.st_mtime; 331*57198Smuller # ifdef NET2_STAT 332*57198Smuller arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize,sizeof(hd->c_filesize), 333*57198Smuller OCT); 334*57198Smuller # else 335*57198Smuller arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize,sizeof(hd->c_filesize), 336*57198Smuller OCT); 337*57198Smuller # endif 338*57198Smuller 339*57198Smuller /* 340*57198Smuller * check name size and if valid, read in the name of this entry (name 341*57198Smuller * follows header in the archive) 342*57198Smuller */ 343*57198Smuller if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2) 344*57198Smuller return(-1); 345*57198Smuller arcn->nlen = nsz - 1; 346*57198Smuller if (rd_nm(arcn, nsz) < 0) 347*57198Smuller return(-1); 348*57198Smuller 349*57198Smuller if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { 350*57198Smuller /* 351*57198Smuller * no link name to read for this file 352*57198Smuller */ 353*57198Smuller arcn->ln_nlen = 0; 354*57198Smuller arcn->ln_name[0] = '\0'; 355*57198Smuller return(com_rd(arcn)); 356*57198Smuller } 357*57198Smuller 358*57198Smuller /* 359*57198Smuller * check link name size and read in the link name. Link names are 360*57198Smuller * stored like file data. 361*57198Smuller */ 362*57198Smuller if (rd_ln_nm(arcn) < 0) 363*57198Smuller return(-1); 364*57198Smuller 365*57198Smuller /* 366*57198Smuller * we have a valid header (with a link) 367*57198Smuller */ 368*57198Smuller return(com_rd(arcn)); 369*57198Smuller } 370*57198Smuller 371*57198Smuller /* 372*57198Smuller * cpio_endrd() 373*57198Smuller * no cleanup needed here, just return size of the trailer (for append) 374*57198Smuller * Return: 375*57198Smuller * size of trailer header in this format 376*57198Smuller */ 377*57198Smuller 378*57198Smuller #if __STDC__ 379*57198Smuller off_t 380*57198Smuller cpio_endrd(void) 381*57198Smuller #else 382*57198Smuller off_t 383*57198Smuller cpio_endrd() 384*57198Smuller #endif 385*57198Smuller { 386*57198Smuller return((off_t)(sizeof(HD_CPIO) + sizeof(TRAILER))); 387*57198Smuller } 388*57198Smuller 389*57198Smuller /* 390*57198Smuller * cpio_stwr() 391*57198Smuller * start up the device mapping table 392*57198Smuller * Return: 393*57198Smuller * 0 if ok, -1 otherwise (what dev_start() returns) 394*57198Smuller */ 395*57198Smuller 396*57198Smuller #if __STDC__ 397*57198Smuller int 398*57198Smuller cpio_stwr(void) 399*57198Smuller #else 400*57198Smuller int 401*57198Smuller cpio_stwr() 402*57198Smuller #endif 403*57198Smuller { 404*57198Smuller return(dev_start()); 405*57198Smuller } 406*57198Smuller 407*57198Smuller /* 408*57198Smuller * cpio_wr() 409*57198Smuller * copy the data in the ARCHD to buffer in extended byte oriented cpio 410*57198Smuller * format. 411*57198Smuller * Return 412*57198Smuller * 0 if file has data to be written after the header, 1 if file has NO 413*57198Smuller * data to write after the header, -1 if archive write failed 414*57198Smuller */ 415*57198Smuller 416*57198Smuller #if __STDC__ 417*57198Smuller int 418*57198Smuller cpio_wr(register ARCHD *arcn) 419*57198Smuller #else 420*57198Smuller int 421*57198Smuller cpio_wr(arcn) 422*57198Smuller register ARCHD *arcn; 423*57198Smuller #endif 424*57198Smuller { 425*57198Smuller register HD_CPIO *hd; 426*57198Smuller register int nsz; 427*57198Smuller char hdblk[sizeof(HD_CPIO)]; 428*57198Smuller 429*57198Smuller /* 430*57198Smuller * check and repair truncated device and inode fields in the header 431*57198Smuller */ 432*57198Smuller if (map_dev(arcn, (u_long)CPIO_MASK, (u_long)CPIO_MASK) < 0) 433*57198Smuller return(-1); 434*57198Smuller 435*57198Smuller arcn->pad = 0L; 436*57198Smuller nsz = arcn->nlen + 1; 437*57198Smuller hd = (HD_CPIO *)hdblk; 438*57198Smuller if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 439*57198Smuller arcn->sb.st_rdev = 0; 440*57198Smuller 441*57198Smuller switch(arcn->type) { 442*57198Smuller case PAX_CTG: 443*57198Smuller case PAX_REG: 444*57198Smuller case PAX_HRG: 445*57198Smuller /* 446*57198Smuller * set data size for file data 447*57198Smuller */ 448*57198Smuller # ifdef NET2_STAT 449*57198Smuller if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize, 450*57198Smuller sizeof(hd->c_filesize), OCT)) { 451*57198Smuller # else 452*57198Smuller if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, 453*57198Smuller sizeof(hd->c_filesize), OCT)) { 454*57198Smuller # endif 455*57198Smuller warn(1,"File is too large for cpio format %s", 456*57198Smuller arcn->org_name); 457*57198Smuller return(1); 458*57198Smuller } 459*57198Smuller break; 460*57198Smuller case PAX_SLK: 461*57198Smuller /* 462*57198Smuller * set data size to hold link name 463*57198Smuller */ 464*57198Smuller if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, 465*57198Smuller sizeof(hd->c_filesize), OCT)) 466*57198Smuller goto out; 467*57198Smuller break; 468*57198Smuller default: 469*57198Smuller /* 470*57198Smuller * all other file types have no file data 471*57198Smuller */ 472*57198Smuller if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize), 473*57198Smuller OCT)) 474*57198Smuller goto out; 475*57198Smuller break; 476*57198Smuller } 477*57198Smuller 478*57198Smuller /* 479*57198Smuller * copy the values to the header using octal ascii 480*57198Smuller */ 481*57198Smuller if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) || 482*57198Smuller ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev), 483*57198Smuller OCT) || 484*57198Smuller ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), 485*57198Smuller OCT) || 486*57198Smuller ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), 487*57198Smuller OCT) || 488*57198Smuller ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), 489*57198Smuller OCT) || 490*57198Smuller ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), 491*57198Smuller OCT) || 492*57198Smuller ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), 493*57198Smuller OCT) || 494*57198Smuller ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev), 495*57198Smuller OCT) || 496*57198Smuller ul_asc((u_long)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime), 497*57198Smuller OCT) || 498*57198Smuller ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT)) 499*57198Smuller goto out; 500*57198Smuller 501*57198Smuller /* 502*57198Smuller * write the file name to the archive 503*57198Smuller */ 504*57198Smuller if ((wr_rdbuf(hdblk, (int)sizeof(HD_CPIO)) < 0) || 505*57198Smuller (wr_rdbuf(arcn->name, nsz) < 0)) { 506*57198Smuller warn(1, "Unable to write cpio header for %s", arcn->org_name); 507*57198Smuller return(-1); 508*57198Smuller } 509*57198Smuller 510*57198Smuller /* 511*57198Smuller * if this file has data, we are done. The caller will write the file 512*57198Smuller * data, if we are link tell caller we are done, go to next file 513*57198Smuller */ 514*57198Smuller if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 515*57198Smuller (arcn->type == PAX_HRG)) 516*57198Smuller return(0); 517*57198Smuller if (arcn->type != PAX_SLK) 518*57198Smuller return(1); 519*57198Smuller 520*57198Smuller /* 521*57198Smuller * write the link name to the archive, tell the caller to go to the 522*57198Smuller * next file as we are done. 523*57198Smuller */ 524*57198Smuller if (wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) { 525*57198Smuller warn(1,"Unable to write cpio link name for %s",arcn->org_name); 526*57198Smuller return(-1); 527*57198Smuller } 528*57198Smuller return(1); 529*57198Smuller 530*57198Smuller out: 531*57198Smuller /* 532*57198Smuller * header field is out of range 533*57198Smuller */ 534*57198Smuller warn(1, "Cpio header field is too small to store file %s", 535*57198Smuller arcn->org_name); 536*57198Smuller return(1); 537*57198Smuller } 538*57198Smuller 539*57198Smuller /* 540*57198Smuller * Routines common to the system VR4 version of cpio (with/without file CRC) 541*57198Smuller */ 542*57198Smuller 543*57198Smuller /* 544*57198Smuller * vcpio_id() 545*57198Smuller * determine if a block given to us is a valid system VR4 cpio header 546*57198Smuller * WITHOUT crc. WATCH it the magic cookies are in OCTAL, the header 547*57198Smuller * uses HEX 548*57198Smuller * Return: 549*57198Smuller * 0 if a valid header, -1 otherwise 550*57198Smuller */ 551*57198Smuller 552*57198Smuller #if __STDC__ 553*57198Smuller int 554*57198Smuller vcpio_id(char *blk, int size) 555*57198Smuller #else 556*57198Smuller int 557*57198Smuller vcpio_id(blk, size) 558*57198Smuller char *blk; 559*57198Smuller int size; 560*57198Smuller #endif 561*57198Smuller { 562*57198Smuller if ((size < sizeof(HD_VCPIO)) || 563*57198Smuller (strncmp(blk, AVMAGIC, sizeof(AVMAGIC) - 1) != 0)) 564*57198Smuller return(-1); 565*57198Smuller return(0); 566*57198Smuller } 567*57198Smuller 568*57198Smuller /* 569*57198Smuller * crc_id() 570*57198Smuller * determine if a block given to us is a valid system VR4 cpio header 571*57198Smuller * WITH crc. WATCH it the magic cookies are in OCTAL the header uses HEX 572*57198Smuller * Return: 573*57198Smuller * 0 if a valid header, -1 otherwise 574*57198Smuller */ 575*57198Smuller 576*57198Smuller #if __STDC__ 577*57198Smuller int 578*57198Smuller crc_id(char *blk, int size) 579*57198Smuller #else 580*57198Smuller int 581*57198Smuller crc_id(blk, size) 582*57198Smuller char *blk; 583*57198Smuller int size; 584*57198Smuller #endif 585*57198Smuller { 586*57198Smuller if ((size < sizeof(HD_VCPIO)) || 587*57198Smuller (strncmp(blk, AVCMAGIC, sizeof(AVCMAGIC) - 1) != 0)) 588*57198Smuller return(-1); 589*57198Smuller return(0); 590*57198Smuller } 591*57198Smuller 592*57198Smuller /* 593*57198Smuller * crc_strd() 594*57198Smuller w set file data CRC calculations. Fire up the hard link detection code 595*57198Smuller * Return: 596*57198Smuller * 0 if ok -1 otherwise (the return values of lnk_start()) 597*57198Smuller */ 598*57198Smuller 599*57198Smuller #if __STDC__ 600*57198Smuller int 601*57198Smuller crc_strd(void) 602*57198Smuller #else 603*57198Smuller int 604*57198Smuller crc_strd() 605*57198Smuller #endif 606*57198Smuller { 607*57198Smuller docrc = 1; 608*57198Smuller return(lnk_start()); 609*57198Smuller } 610*57198Smuller 611*57198Smuller /* 612*57198Smuller * vcpio_rd() 613*57198Smuller * determine if a buffer is a system VR4 archive entry. (with/without CRC) 614*57198Smuller * convert and store the values in the ARCHD parameter. 615*57198Smuller * Return: 616*57198Smuller * 0 if a valid header, -1 otherwise. 617*57198Smuller */ 618*57198Smuller 619*57198Smuller #if __STDC__ 620*57198Smuller int 621*57198Smuller vcpio_rd(register ARCHD *arcn, register char *buf) 622*57198Smuller #else 623*57198Smuller int 624*57198Smuller vcpio_rd(arcn, buf) 625*57198Smuller register ARCHD *arcn; 626*57198Smuller register char *buf; 627*57198Smuller #endif 628*57198Smuller { 629*57198Smuller register HD_VCPIO *hd; 630*57198Smuller dev_t devminor; 631*57198Smuller dev_t devmajor; 632*57198Smuller register int nsz; 633*57198Smuller 634*57198Smuller /* 635*57198Smuller * during the id phase it was determined if we were using CRC, use the 636*57198Smuller * proper id routine. 637*57198Smuller */ 638*57198Smuller if (docrc) { 639*57198Smuller if (crc_id(buf, sizeof(HD_VCPIO)) < 0) 640*57198Smuller return(-1); 641*57198Smuller } else { 642*57198Smuller if (vcpio_id(buf, sizeof(HD_VCPIO)) < 0) 643*57198Smuller return(-1); 644*57198Smuller } 645*57198Smuller 646*57198Smuller hd = (HD_VCPIO *)buf; 647*57198Smuller arcn->pad = 0L; 648*57198Smuller 649*57198Smuller /* 650*57198Smuller * extract the hex ascii fields from the header 651*57198Smuller */ 652*57198Smuller arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX); 653*57198Smuller arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX); 654*57198Smuller arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX); 655*57198Smuller arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX); 656*57198Smuller arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX); 657*57198Smuller arcn->sb.st_atime = arcn->sb.st_mtime; 658*57198Smuller # ifdef NET2_STAT 659*57198Smuller arcn->sb.st_size = (off_t)asc_ul(hd->c_filesize, 660*57198Smuller sizeof(hd->c_filesize), HEX); 661*57198Smuller # else 662*57198Smuller arcn->sb.st_size = (off_t)asc_uqd(hd->c_filesize, 663*57198Smuller sizeof(hd->c_filesize), HEX); 664*57198Smuller # endif 665*57198Smuller arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink), 666*57198Smuller HEX); 667*57198Smuller devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX); 668*57198Smuller devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX); 669*57198Smuller arcn->sb.st_dev = TODEV(devmajor, devminor); 670*57198Smuller devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX); 671*57198Smuller devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX); 672*57198Smuller arcn->sb.st_rdev = TODEV(devmajor, devminor); 673*57198Smuller arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX); 674*57198Smuller 675*57198Smuller /* 676*57198Smuller * check the length of the file name, if ok read it in, return -1 if 677*57198Smuller * bogus 678*57198Smuller */ 679*57198Smuller if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2) 680*57198Smuller return(-1); 681*57198Smuller arcn->nlen = nsz - 1; 682*57198Smuller if (rd_nm(arcn, nsz) < 0) 683*57198Smuller return(-1); 684*57198Smuller 685*57198Smuller /* 686*57198Smuller * skip padding. header + filename is aligned to 4 byte boundries 687*57198Smuller */ 688*57198Smuller if (rd_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0) 689*57198Smuller return(-1); 690*57198Smuller 691*57198Smuller /* 692*57198Smuller * if not a link (or a file with no data), calculate pad size (for 693*57198Smuller * padding which follows the file data), clear the link name and return 694*57198Smuller */ 695*57198Smuller if (((arcn->sb.st_mode&C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)) { 696*57198Smuller /* 697*57198Smuller * we have a valid header (not a link) 698*57198Smuller */ 699*57198Smuller arcn->ln_nlen = 0; 700*57198Smuller arcn->ln_name[0] = '\0'; 701*57198Smuller arcn->pad = VCPIO_PAD(arcn->sb.st_size); 702*57198Smuller return(com_rd(arcn)); 703*57198Smuller } 704*57198Smuller 705*57198Smuller /* 706*57198Smuller * read in the link name and skip over the padding 707*57198Smuller */ 708*57198Smuller if ((rd_ln_nm(arcn) < 0) || 709*57198Smuller (rd_skip((off_t)(VCPIO_PAD(arcn->sb.st_size))) < 0)) 710*57198Smuller return(-1); 711*57198Smuller 712*57198Smuller /* 713*57198Smuller * we have a valid header (with a link) 714*57198Smuller */ 715*57198Smuller return(com_rd(arcn)); 716*57198Smuller } 717*57198Smuller 718*57198Smuller /* 719*57198Smuller * vcpio_endrd() 720*57198Smuller * no cleanup needed here, just return size of the trailer (for append) 721*57198Smuller * Return: 722*57198Smuller * size of trailer header in this format 723*57198Smuller */ 724*57198Smuller 725*57198Smuller #if __STDC__ 726*57198Smuller off_t 727*57198Smuller vcpio_endrd(void) 728*57198Smuller #else 729*57198Smuller off_t 730*57198Smuller vcpio_endrd() 731*57198Smuller #endif 732*57198Smuller { 733*57198Smuller return((off_t)(sizeof(HD_VCPIO) + sizeof(TRAILER) + 734*57198Smuller (VCPIO_PAD(sizeof(HD_VCPIO) + sizeof(TRAILER))))); 735*57198Smuller } 736*57198Smuller 737*57198Smuller /* 738*57198Smuller * crc_stwr() 739*57198Smuller * start up the device mapping table, enable crc file calculation 740*57198Smuller * Return: 741*57198Smuller * 0 if ok, -1 otherwise (what dev_start() returns) 742*57198Smuller */ 743*57198Smuller 744*57198Smuller #if __STDC__ 745*57198Smuller int 746*57198Smuller crc_stwr(void) 747*57198Smuller #else 748*57198Smuller int 749*57198Smuller crc_stwr() 750*57198Smuller #endif 751*57198Smuller { 752*57198Smuller docrc = 1; 753*57198Smuller return(dev_start()); 754*57198Smuller } 755*57198Smuller 756*57198Smuller /* 757*57198Smuller * vcpio_wr() 758*57198Smuller * copy the data in the ARCHD to buffer in system VR4 cpio 759*57198Smuller * (with/without crc) format. 760*57198Smuller * Return 761*57198Smuller * 0 if file has data to be written after the header, 1 if file has 762*57198Smuller * NO data 763*57198Smuller * to write after the header, -1 if archive write failed 764*57198Smuller */ 765*57198Smuller 766*57198Smuller #if __STDC__ 767*57198Smuller int 768*57198Smuller vcpio_wr(register ARCHD *arcn) 769*57198Smuller #else 770*57198Smuller int 771*57198Smuller vcpio_wr(arcn) 772*57198Smuller register ARCHD *arcn; 773*57198Smuller #endif 774*57198Smuller { 775*57198Smuller register HD_VCPIO *hd; 776*57198Smuller unsigned int nsz; 777*57198Smuller char hdblk[sizeof(HD_VCPIO)]; 778*57198Smuller 779*57198Smuller /* 780*57198Smuller * check and repair truncated device and inode fields in the cpio 781*57198Smuller * header 782*57198Smuller */ 783*57198Smuller if (map_dev(arcn, (u_long)VCPIO_MASK, (u_long)VCPIO_MASK) < 0) 784*57198Smuller return(-1); 785*57198Smuller nsz = arcn->nlen + 1; 786*57198Smuller hd = (HD_VCPIO *)hdblk; 787*57198Smuller if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 788*57198Smuller arcn->sb.st_rdev = 0; 789*57198Smuller 790*57198Smuller /* 791*57198Smuller * add the proper magic value depending whether we were asked for 792*57198Smuller * file data crc's, and the crc if needed. 793*57198Smuller */ 794*57198Smuller if (docrc) { 795*57198Smuller if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic), 796*57198Smuller OCT) || 797*57198Smuller ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum), 798*57198Smuller HEX)) 799*57198Smuller goto out; 800*57198Smuller } else { 801*57198Smuller if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic), 802*57198Smuller OCT) || 803*57198Smuller ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX)) 804*57198Smuller goto out; 805*57198Smuller } 806*57198Smuller 807*57198Smuller switch(arcn->type) { 808*57198Smuller case PAX_CTG: 809*57198Smuller case PAX_REG: 810*57198Smuller case PAX_HRG: 811*57198Smuller /* 812*57198Smuller * caller will copy file data to the archive. tell him how 813*57198Smuller * much to pad. 814*57198Smuller */ 815*57198Smuller arcn->pad = VCPIO_PAD(arcn->sb.st_size); 816*57198Smuller # ifdef NET2_STAT 817*57198Smuller if (ul_asc((u_long)arcn->sb.st_size, hd->c_filesize, 818*57198Smuller sizeof(hd->c_filesize), HEX)) { 819*57198Smuller # else 820*57198Smuller if (uqd_asc((u_quad_t)arcn->sb.st_size, hd->c_filesize, 821*57198Smuller sizeof(hd->c_filesize), HEX)) { 822*57198Smuller # endif 823*57198Smuller warn(1,"File is too large for sv4cpio format %s", 824*57198Smuller arcn->org_name); 825*57198Smuller return(1); 826*57198Smuller } 827*57198Smuller break; 828*57198Smuller case PAX_SLK: 829*57198Smuller /* 830*57198Smuller * no file data for the caller to process, the file data has 831*57198Smuller * the size of the link 832*57198Smuller */ 833*57198Smuller arcn->pad = 0L; 834*57198Smuller if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize, 835*57198Smuller sizeof(hd->c_filesize), HEX)) 836*57198Smuller goto out; 837*57198Smuller break; 838*57198Smuller default: 839*57198Smuller /* 840*57198Smuller * no file data for the caller to process 841*57198Smuller */ 842*57198Smuller arcn->pad = 0L; 843*57198Smuller if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize), 844*57198Smuller HEX)) 845*57198Smuller goto out; 846*57198Smuller break; 847*57198Smuller } 848*57198Smuller 849*57198Smuller /* 850*57198Smuller * set the other fields in the header 851*57198Smuller */ 852*57198Smuller if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino), 853*57198Smuller HEX) || 854*57198Smuller ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode), 855*57198Smuller HEX) || 856*57198Smuller ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid), 857*57198Smuller HEX) || 858*57198Smuller ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid), 859*57198Smuller HEX) || 860*57198Smuller ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime), 861*57198Smuller HEX) || 862*57198Smuller ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink), 863*57198Smuller HEX) || 864*57198Smuller ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj), 865*57198Smuller HEX) || 866*57198Smuller ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min), 867*57198Smuller HEX) || 868*57198Smuller ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj), 869*57198Smuller HEX) || 870*57198Smuller ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min), 871*57198Smuller HEX) || 872*57198Smuller ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX)) 873*57198Smuller goto out; 874*57198Smuller 875*57198Smuller /* 876*57198Smuller * write the header, the file name and padding as required. 877*57198Smuller */ 878*57198Smuller if ((wr_rdbuf(hdblk, (int)sizeof(HD_VCPIO)) < 0) || 879*57198Smuller (wr_rdbuf(arcn->name, (int)nsz) < 0) || 880*57198Smuller (wr_skip((off_t)(VCPIO_PAD(sizeof(HD_VCPIO) + nsz))) < 0)) { 881*57198Smuller warn(1,"Could not write sv4cpio header for %s",arcn->org_name); 882*57198Smuller return(-1); 883*57198Smuller } 884*57198Smuller 885*57198Smuller /* 886*57198Smuller * if we have file data, tell the caller we are done, copy the file 887*57198Smuller */ 888*57198Smuller if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 889*57198Smuller (arcn->type == PAX_HRG)) 890*57198Smuller return(0); 891*57198Smuller 892*57198Smuller /* 893*57198Smuller * if we are not a link, tell the caller we are done, go to next file 894*57198Smuller */ 895*57198Smuller if (arcn->type != PAX_SLK) 896*57198Smuller return(1); 897*57198Smuller 898*57198Smuller /* 899*57198Smuller * write the link name, tell the caller we are done. 900*57198Smuller */ 901*57198Smuller if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 902*57198Smuller (wr_skip((off_t)(VCPIO_PAD(arcn->ln_nlen))) < 0)) { 903*57198Smuller warn(1,"Could not write sv4cpio link name for %s", 904*57198Smuller arcn->org_name); 905*57198Smuller return(-1); 906*57198Smuller } 907*57198Smuller return(1); 908*57198Smuller 909*57198Smuller out: 910*57198Smuller /* 911*57198Smuller * header field is out of range 912*57198Smuller */ 913*57198Smuller warn(1,"Sv4cpio header field is too small for file %s",arcn->org_name); 914*57198Smuller return(1); 915*57198Smuller } 916*57198Smuller 917*57198Smuller /* 918*57198Smuller * Routines common to the old binary header cpio 919*57198Smuller */ 920*57198Smuller 921*57198Smuller /* 922*57198Smuller * bcpio_id() 923*57198Smuller * determine if a block given to us is a old binary cpio header 924*57198Smuller * (with/without header byte swapping) 925*57198Smuller * Return: 926*57198Smuller * 0 if a valid header, -1 otherwise 927*57198Smuller */ 928*57198Smuller 929*57198Smuller #if __STDC__ 930*57198Smuller int 931*57198Smuller bcpio_id(char *blk, int size) 932*57198Smuller #else 933*57198Smuller int 934*57198Smuller bcpio_id(blk, size) 935*57198Smuller char *blk; 936*57198Smuller int size; 937*57198Smuller #endif 938*57198Smuller { 939*57198Smuller if (size < sizeof(HD_BCPIO)) 940*57198Smuller return(-1); 941*57198Smuller 942*57198Smuller /* 943*57198Smuller * check both normal and byte swapped magic cookies 944*57198Smuller */ 945*57198Smuller if (((u_short)SHRT_EXT(blk)) == MAGIC) 946*57198Smuller return(0); 947*57198Smuller if (((u_short)RSHRT_EXT(blk)) == MAGIC) { 948*57198Smuller if (!swp_head) 949*57198Smuller ++swp_head; 950*57198Smuller return(0); 951*57198Smuller } 952*57198Smuller return(-1); 953*57198Smuller } 954*57198Smuller 955*57198Smuller /* 956*57198Smuller * bcpio_rd() 957*57198Smuller * determine if a buffer is a old binary archive entry. (it may have byte 958*57198Smuller * swapped header) convert and store the values in the ARCHD parameter. 959*57198Smuller * This is a very old header format and should not really be used. 960*57198Smuller * Return: 961*57198Smuller * 0 if a valid header, -1 otherwise. 962*57198Smuller */ 963*57198Smuller 964*57198Smuller #if __STDC__ 965*57198Smuller int 966*57198Smuller bcpio_rd(register ARCHD *arcn, register char *buf) 967*57198Smuller #else 968*57198Smuller int 969*57198Smuller bcpio_rd(arcn, buf) 970*57198Smuller register ARCHD *arcn; 971*57198Smuller register char *buf; 972*57198Smuller #endif 973*57198Smuller { 974*57198Smuller register HD_BCPIO *hd; 975*57198Smuller register int nsz; 976*57198Smuller 977*57198Smuller /* 978*57198Smuller * check the header 979*57198Smuller */ 980*57198Smuller if (bcpio_id(buf, sizeof(HD_BCPIO)) < 0) 981*57198Smuller return(-1); 982*57198Smuller 983*57198Smuller arcn->pad = 0L; 984*57198Smuller hd = (HD_BCPIO *)buf; 985*57198Smuller if (swp_head) { 986*57198Smuller /* 987*57198Smuller * header has swapped bytes on 16 bit boundries 988*57198Smuller */ 989*57198Smuller arcn->sb.st_dev = (dev_t)(RSHRT_EXT(hd->h_dev)); 990*57198Smuller arcn->sb.st_ino = (ino_t)(RSHRT_EXT(hd->h_ino)); 991*57198Smuller arcn->sb.st_mode = (mode_t)(RSHRT_EXT(hd->h_mode)); 992*57198Smuller arcn->sb.st_uid = (uid_t)(RSHRT_EXT(hd->h_uid)); 993*57198Smuller arcn->sb.st_gid = (gid_t)(RSHRT_EXT(hd->h_gid)); 994*57198Smuller arcn->sb.st_nlink = (nlink_t)(RSHRT_EXT(hd->h_nlink)); 995*57198Smuller arcn->sb.st_rdev = (dev_t)(RSHRT_EXT(hd->h_rdev)); 996*57198Smuller arcn->sb.st_mtime = (time_t)(RSHRT_EXT(hd->h_mtime_1)); 997*57198Smuller arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 998*57198Smuller ((time_t)(RSHRT_EXT(hd->h_mtime_2))); 999*57198Smuller arcn->sb.st_size = (off_t)(RSHRT_EXT(hd->h_filesize_1)); 1000*57198Smuller arcn->sb.st_size = (arcn->sb.st_size << 16) | 1001*57198Smuller ((off_t)(RSHRT_EXT(hd->h_filesize_2))); 1002*57198Smuller nsz = (int)(RSHRT_EXT(hd->h_namesize)); 1003*57198Smuller } else { 1004*57198Smuller arcn->sb.st_dev = (dev_t)(SHRT_EXT(hd->h_dev)); 1005*57198Smuller arcn->sb.st_ino = (ino_t)(SHRT_EXT(hd->h_ino)); 1006*57198Smuller arcn->sb.st_mode = (mode_t)(SHRT_EXT(hd->h_mode)); 1007*57198Smuller arcn->sb.st_uid = (uid_t)(SHRT_EXT(hd->h_uid)); 1008*57198Smuller arcn->sb.st_gid = (gid_t)(SHRT_EXT(hd->h_gid)); 1009*57198Smuller arcn->sb.st_nlink = (nlink_t)(SHRT_EXT(hd->h_nlink)); 1010*57198Smuller arcn->sb.st_rdev = (dev_t)(SHRT_EXT(hd->h_rdev)); 1011*57198Smuller arcn->sb.st_mtime = (time_t)(SHRT_EXT(hd->h_mtime_1)); 1012*57198Smuller arcn->sb.st_mtime = (arcn->sb.st_mtime << 16) | 1013*57198Smuller ((time_t)(SHRT_EXT(hd->h_mtime_2))); 1014*57198Smuller arcn->sb.st_size = (off_t)(SHRT_EXT(hd->h_filesize_1)); 1015*57198Smuller arcn->sb.st_size = (arcn->sb.st_size << 16) | 1016*57198Smuller ((off_t)(SHRT_EXT(hd->h_filesize_2))); 1017*57198Smuller nsz = (int)(SHRT_EXT(hd->h_namesize)); 1018*57198Smuller } 1019*57198Smuller arcn->sb.st_atime = arcn->sb.st_mtime; 1020*57198Smuller 1021*57198Smuller /* 1022*57198Smuller * check the file name size, if bogus give up. otherwise read the file 1023*57198Smuller * name 1024*57198Smuller */ 1025*57198Smuller if (nsz < 2) 1026*57198Smuller return(-1); 1027*57198Smuller arcn->nlen = nsz - 1; 1028*57198Smuller if (rd_nm(arcn, nsz) < 0) 1029*57198Smuller return(-1); 1030*57198Smuller 1031*57198Smuller /* 1032*57198Smuller * header + file name are aligned to 2 byte boundries, skip if needed 1033*57198Smuller */ 1034*57198Smuller if (rd_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0) 1035*57198Smuller return(-1); 1036*57198Smuller 1037*57198Smuller /* 1038*57198Smuller * if not a link (or a file with no data), calculate pad size (for 1039*57198Smuller * padding which follows the file data), clear the link name and return 1040*57198Smuller */ 1041*57198Smuller if (((arcn->sb.st_mode & C_IFMT) != C_ISLNK)||(arcn->sb.st_size == 0)){ 1042*57198Smuller /* 1043*57198Smuller * we have a valid header (not a link) 1044*57198Smuller */ 1045*57198Smuller arcn->ln_nlen = 0; 1046*57198Smuller arcn->ln_name[0] = '\0'; 1047*57198Smuller arcn->pad = BCPIO_PAD(arcn->sb.st_size); 1048*57198Smuller return(com_rd(arcn)); 1049*57198Smuller } 1050*57198Smuller 1051*57198Smuller if ((rd_ln_nm(arcn) < 0) || 1052*57198Smuller (rd_skip((off_t)(BCPIO_PAD(arcn->sb.st_size))) < 0)) 1053*57198Smuller return(-1); 1054*57198Smuller 1055*57198Smuller /* 1056*57198Smuller * we have a valid header (with a link) 1057*57198Smuller */ 1058*57198Smuller return(com_rd(arcn)); 1059*57198Smuller } 1060*57198Smuller 1061*57198Smuller /* 1062*57198Smuller * bcpio_endrd() 1063*57198Smuller * no cleanup needed here, just return size of the trailer (for append) 1064*57198Smuller * Return: 1065*57198Smuller * size of trailer header in this format 1066*57198Smuller */ 1067*57198Smuller 1068*57198Smuller #if __STDC__ 1069*57198Smuller off_t 1070*57198Smuller bcpio_endrd(void) 1071*57198Smuller #else 1072*57198Smuller off_t 1073*57198Smuller bcpio_endrd() 1074*57198Smuller #endif 1075*57198Smuller { 1076*57198Smuller return((off_t)(sizeof(HD_BCPIO) + sizeof(TRAILER) + 1077*57198Smuller (BCPIO_PAD(sizeof(HD_BCPIO) + sizeof(TRAILER))))); 1078*57198Smuller } 1079*57198Smuller 1080*57198Smuller /* 1081*57198Smuller * bcpio_wr() 1082*57198Smuller * copy the data in the ARCHD to buffer in old binary cpio format 1083*57198Smuller * There is a real chance of field overflow with this critter. So we 1084*57198Smuller * always check the conversion is ok. nobody in his their right mind 1085*57198Smuller * should write an achive in this format... 1086*57198Smuller * Return 1087*57198Smuller * 0 if file has data to be written after the header, 1 if file has NO 1088*57198Smuller * data to write after the header, -1 if archive write failed 1089*57198Smuller */ 1090*57198Smuller 1091*57198Smuller #if __STDC__ 1092*57198Smuller int 1093*57198Smuller bcpio_wr(register ARCHD *arcn) 1094*57198Smuller #else 1095*57198Smuller int 1096*57198Smuller bcpio_wr(arcn) 1097*57198Smuller register ARCHD *arcn; 1098*57198Smuller #endif 1099*57198Smuller { 1100*57198Smuller register HD_BCPIO *hd; 1101*57198Smuller register int nsz; 1102*57198Smuller char hdblk[sizeof(HD_BCPIO)]; 1103*57198Smuller off_t t_offt; 1104*57198Smuller int t_int; 1105*57198Smuller time_t t_timet; 1106*57198Smuller 1107*57198Smuller /* 1108*57198Smuller * check and repair truncated device and inode fields in the cpio 1109*57198Smuller * header 1110*57198Smuller */ 1111*57198Smuller if (map_dev(arcn, (u_long)BCPIO_MASK, (u_long)BCPIO_MASK) < 0) 1112*57198Smuller return(-1); 1113*57198Smuller 1114*57198Smuller if ((arcn->type != PAX_BLK) && (arcn->type != PAX_CHR)) 1115*57198Smuller arcn->sb.st_rdev = 0; 1116*57198Smuller hd = (HD_BCPIO *)hdblk; 1117*57198Smuller 1118*57198Smuller switch(arcn->type) { 1119*57198Smuller case PAX_CTG: 1120*57198Smuller case PAX_REG: 1121*57198Smuller case PAX_HRG: 1122*57198Smuller /* 1123*57198Smuller * caller will copy file data to the archive. tell him how 1124*57198Smuller * much to pad. 1125*57198Smuller */ 1126*57198Smuller arcn->pad = BCPIO_PAD(arcn->sb.st_size); 1127*57198Smuller hd->h_filesize_1[0] = CHR_WR_0(arcn->sb.st_size); 1128*57198Smuller hd->h_filesize_1[1] = CHR_WR_1(arcn->sb.st_size); 1129*57198Smuller hd->h_filesize_2[0] = CHR_WR_2(arcn->sb.st_size); 1130*57198Smuller hd->h_filesize_2[1] = CHR_WR_3(arcn->sb.st_size); 1131*57198Smuller t_offt = (off_t)(SHRT_EXT(hd->h_filesize_1)); 1132*57198Smuller t_offt = (t_offt<<16) | ((off_t)(SHRT_EXT(hd->h_filesize_2))); 1133*57198Smuller if (arcn->sb.st_size != t_offt) { 1134*57198Smuller warn(1,"File is too large for bcpio format %s", 1135*57198Smuller arcn->org_name); 1136*57198Smuller return(1); 1137*57198Smuller } 1138*57198Smuller break; 1139*57198Smuller case PAX_SLK: 1140*57198Smuller /* 1141*57198Smuller * no file data for the caller to process, the file data has 1142*57198Smuller * the size of the link 1143*57198Smuller */ 1144*57198Smuller arcn->pad = 0L; 1145*57198Smuller hd->h_filesize_1[0] = CHR_WR_0(arcn->ln_nlen); 1146*57198Smuller hd->h_filesize_1[1] = CHR_WR_1(arcn->ln_nlen); 1147*57198Smuller hd->h_filesize_2[0] = CHR_WR_2(arcn->ln_nlen); 1148*57198Smuller hd->h_filesize_2[1] = CHR_WR_3(arcn->ln_nlen); 1149*57198Smuller t_int = (int)(SHRT_EXT(hd->h_filesize_1)); 1150*57198Smuller t_int = (t_int << 16) | ((int)(SHRT_EXT(hd->h_filesize_2))); 1151*57198Smuller if (arcn->ln_nlen != t_int) 1152*57198Smuller goto out; 1153*57198Smuller break; 1154*57198Smuller default: 1155*57198Smuller /* 1156*57198Smuller * no file data for the caller to process 1157*57198Smuller */ 1158*57198Smuller arcn->pad = 0L; 1159*57198Smuller hd->h_filesize_1[0] = (char)0; 1160*57198Smuller hd->h_filesize_1[1] = (char)0; 1161*57198Smuller hd->h_filesize_2[0] = (char)0; 1162*57198Smuller hd->h_filesize_2[1] = (char)0; 1163*57198Smuller break; 1164*57198Smuller } 1165*57198Smuller 1166*57198Smuller /* 1167*57198Smuller * build up the rest of the fields 1168*57198Smuller */ 1169*57198Smuller hd->h_magic[0] = CHR_WR_2(MAGIC); 1170*57198Smuller hd->h_magic[1] = CHR_WR_3(MAGIC); 1171*57198Smuller hd->h_dev[0] = CHR_WR_2(arcn->sb.st_dev); 1172*57198Smuller hd->h_dev[1] = CHR_WR_3(arcn->sb.st_dev); 1173*57198Smuller if (arcn->sb.st_dev != (dev_t)(SHRT_EXT(hd->h_dev))) 1174*57198Smuller goto out; 1175*57198Smuller hd->h_ino[0] = CHR_WR_2(arcn->sb.st_ino); 1176*57198Smuller hd->h_ino[1] = CHR_WR_3(arcn->sb.st_ino); 1177*57198Smuller if (arcn->sb.st_ino != (ino_t)(SHRT_EXT(hd->h_ino))) 1178*57198Smuller goto out; 1179*57198Smuller hd->h_mode[0] = CHR_WR_2(arcn->sb.st_mode); 1180*57198Smuller hd->h_mode[1] = CHR_WR_3(arcn->sb.st_mode); 1181*57198Smuller if (arcn->sb.st_mode != (mode_t)(SHRT_EXT(hd->h_mode))) 1182*57198Smuller goto out; 1183*57198Smuller hd->h_uid[0] = CHR_WR_2(arcn->sb.st_uid); 1184*57198Smuller hd->h_uid[1] = CHR_WR_3(arcn->sb.st_uid); 1185*57198Smuller if (arcn->sb.st_uid != (uid_t)(SHRT_EXT(hd->h_uid))) 1186*57198Smuller goto out; 1187*57198Smuller hd->h_gid[0] = CHR_WR_2(arcn->sb.st_gid); 1188*57198Smuller hd->h_gid[1] = CHR_WR_3(arcn->sb.st_gid); 1189*57198Smuller if (arcn->sb.st_gid != (gid_t)(SHRT_EXT(hd->h_gid))) 1190*57198Smuller goto out; 1191*57198Smuller hd->h_nlink[0] = CHR_WR_2(arcn->sb.st_nlink); 1192*57198Smuller hd->h_nlink[1] = CHR_WR_3(arcn->sb.st_nlink); 1193*57198Smuller if (arcn->sb.st_nlink != (nlink_t)(SHRT_EXT(hd->h_nlink))) 1194*57198Smuller goto out; 1195*57198Smuller hd->h_rdev[0] = CHR_WR_2(arcn->sb.st_rdev); 1196*57198Smuller hd->h_rdev[1] = CHR_WR_3(arcn->sb.st_rdev); 1197*57198Smuller if (arcn->sb.st_rdev != (dev_t)(SHRT_EXT(hd->h_rdev))) 1198*57198Smuller goto out; 1199*57198Smuller hd->h_mtime_1[0] = CHR_WR_0(arcn->sb.st_mtime); 1200*57198Smuller hd->h_mtime_1[1] = CHR_WR_1(arcn->sb.st_mtime); 1201*57198Smuller hd->h_mtime_2[0] = CHR_WR_2(arcn->sb.st_mtime); 1202*57198Smuller hd->h_mtime_2[1] = CHR_WR_3(arcn->sb.st_mtime); 1203*57198Smuller t_timet = (time_t)(SHRT_EXT(hd->h_mtime_1)); 1204*57198Smuller t_timet = (t_timet << 16) | ((time_t)(SHRT_EXT(hd->h_mtime_2))); 1205*57198Smuller if (arcn->sb.st_mtime != t_timet) 1206*57198Smuller goto out; 1207*57198Smuller nsz = arcn->nlen + 1; 1208*57198Smuller hd->h_namesize[0] = CHR_WR_2(nsz); 1209*57198Smuller hd->h_namesize[1] = CHR_WR_3(nsz); 1210*57198Smuller if (nsz != (int)(SHRT_EXT(hd->h_namesize))) 1211*57198Smuller goto out; 1212*57198Smuller 1213*57198Smuller /* 1214*57198Smuller * write the header, the file name and padding as required. 1215*57198Smuller */ 1216*57198Smuller if ((wr_rdbuf(hdblk, (int)sizeof(HD_BCPIO)) < 0) || 1217*57198Smuller (wr_rdbuf(arcn->name, nsz) < 0) || 1218*57198Smuller (wr_skip((off_t)(BCPIO_PAD(sizeof(HD_BCPIO) + nsz))) < 0)) { 1219*57198Smuller warn(1, "Could not write bcpio header for %s", arcn->org_name); 1220*57198Smuller return(-1); 1221*57198Smuller } 1222*57198Smuller 1223*57198Smuller /* 1224*57198Smuller * if we have file data, tell the caller we are done 1225*57198Smuller */ 1226*57198Smuller if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG) || 1227*57198Smuller (arcn->type == PAX_HRG)) 1228*57198Smuller return(0); 1229*57198Smuller 1230*57198Smuller /* 1231*57198Smuller * if we are not a link, tell the caller we are done, go to next file 1232*57198Smuller */ 1233*57198Smuller if (arcn->type != PAX_SLK) 1234*57198Smuller return(1); 1235*57198Smuller 1236*57198Smuller /* 1237*57198Smuller * write the link name, tell the caller we are done. 1238*57198Smuller */ 1239*57198Smuller if ((wr_rdbuf(arcn->ln_name, arcn->ln_nlen) < 0) || 1240*57198Smuller (wr_skip((off_t)(BCPIO_PAD(arcn->ln_nlen))) < 0)) { 1241*57198Smuller warn(1,"Could not write bcpio link name for %s",arcn->org_name); 1242*57198Smuller return(-1); 1243*57198Smuller } 1244*57198Smuller return(1); 1245*57198Smuller 1246*57198Smuller out: 1247*57198Smuller /* 1248*57198Smuller * header field is out of range 1249*57198Smuller */ 1250*57198Smuller warn(1,"Bcpio header field is too small for file %s", arcn->org_name); 1251*57198Smuller return(1); 1252*57198Smuller } 1253