void ls_list(ARCHD *arcn, time_t now, FILE *fp) { struct stat *sbp; char f_mode[MODELEN]; char f_date[DATELEN]; const char *timefrmt; /* * if not verbose, just print the file name */ if (!vflag) { (void)fprintf(fp, "%s\n", arcn->name); (void)fflush(fp); return; } if (d_first < 0) d_first = 0; /* * user wants long mode */ sbp = &(arcn->sb); #if 0 strmode(sbp->st_mode, f_mode); #else strcpy(f_mode, ""); #endif /* * time format based on age compared to the time pax was started. */ if ((sbp->st_mtime + SIXMONTHS) <= now) timefrmt = d_first ? OLDFRMTD : OLDFRMTM; else timefrmt = d_first ? CURFRMTD : CURFRMTM; /* * print file mode, link count, uid, gid and time */ #if 0 if (strftime(f_date,DATELEN,timefrmt,localtime(&(sbp->st_mtime))) == 0) #endif f_date[0] = '\0'; (void)fprintf(fp, "%s%2u %-*s %-*s ", f_mode, sbp->st_nlink, UT_NAMESIZE, name_uid(sbp->st_uid, 1), UT_GRPSIZE, name_gid(sbp->st_gid, 1)); /* * print device id's for devices, or sizes for other nodes */ if ((arcn->type == PAX_CHR) || (arcn->type == PAX_BLK)) # ifdef NET2_STAT (void)fprintf(fp, "%4u,%4u ", major(sbp->st_rdev), minor(sbp->st_rdev)); # else (void)fprintf(fp, "%4lu,%4lu ", (unsigned long)major(sbp->st_rdev), (unsigned long)minor(sbp->st_rdev)); # endif else {
int ustar_wr(ARCHD *arcn) { HD_USTAR *hd; char *pt; char hdblk[sizeof(HD_USTAR)]; /* * check for those file system types ustar cannot store */ if (arcn->type == PAX_SCK) { paxwarn(1, "Ustar cannot archive a socket %s", arcn->org_name); return(1); } /* * user asked that dirs not be written to the archive */ if (arcn->type == PAX_DIR && tar_nodir) return (1); /* * check the length of the linkname */ if (PAX_IS_LINK(arcn->type) && (arcn->ln_nlen > sizeof(hd->linkname))) { paxwarn(1, "Link name too long for ustar %s", arcn->ln_name); return(1); } /* * split the path name into prefix and name fields (if needed). if * pt != arcn->name, the name has to be split */ if ((pt = name_split(arcn->name, arcn->nlen)) == NULL) { paxwarn(1, "File name too long for ustar %s", arcn->name); return(1); } /* * zero out the header so we don't have to worry about zero fill below */ memset(hdblk, 0, sizeof(hdblk)); hd = (HD_USTAR *)hdblk; arcn->pad = 0; /* * split the name, or zero out the prefix */ if (pt != arcn->name) { /* * name was split, pt points at the / where the split is to * occur, we remove the / and copy the first part to the prefix */ *pt = '\0'; fieldcpy(hd->prefix, sizeof(hd->prefix), arcn->name, sizeof(arcn->name)); *pt++ = '/'; } /* * copy the name part. this may be the whole path or the part after * the prefix */ fieldcpy(hd->name, sizeof(hd->name), pt, sizeof(arcn->name) - (pt - arcn->name)); /* * set the fields in the header that are type dependent */ switch (arcn->type) { case PAX_DIR: hd->typeflag = DIRTYPE; if (ul_oct(0, hd->size, sizeof(hd->size), 3)) goto out; break; case PAX_CHR: case PAX_BLK: if (arcn->type == PAX_CHR) hd->typeflag = CHRTYPE; else hd->typeflag = BLKTYPE; if (ul_oct(MAJOR(arcn->sb.st_rdev), hd->devmajor, sizeof(hd->devmajor), 3) || ul_oct(MINOR(arcn->sb.st_rdev), hd->devminor, sizeof(hd->devminor), 3) || ul_oct(0, hd->size, sizeof(hd->size), 3)) goto out; break; case PAX_FIF: hd->typeflag = FIFOTYPE; if (ul_oct(0, hd->size, sizeof(hd->size), 3)) goto out; break; case PAX_SLK: case PAX_HLK: case PAX_HRG: if (arcn->type == PAX_SLK) hd->typeflag = SYMTYPE; else hd->typeflag = LNKTYPE; fieldcpy(hd->linkname, sizeof(hd->linkname), arcn->ln_name, sizeof(arcn->ln_name)); if (ul_oct(0, hd->size, sizeof(hd->size), 3)) goto out; break; case PAX_REG: case PAX_CTG: default: /* * file data with this type, set the padding */ if (arcn->type == PAX_CTG) hd->typeflag = CONTTYPE; else hd->typeflag = REGTYPE; arcn->pad = TAR_PAD(arcn->sb.st_size); if (ull_oct(arcn->sb.st_size, hd->size, sizeof(hd->size), 3)) { paxwarn(1, "File is too long for ustar %s", arcn->org_name); return(1); } break; } strncpy(hd->magic, TMAGIC, TMAGLEN); strncpy(hd->version, TVERSION, TVERSLEN); /* * set the remaining fields. Some versions want all 16 bits of mode * we better humor them (they really do not meet spec though).... */ if (ul_oct(arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3)) { if (uid_nobody == 0) { if (uid_name("nobody", &uid_nobody) == -1) goto out; } if (uid_warn != arcn->sb.st_uid) { uid_warn = arcn->sb.st_uid; paxwarn(1, "Ustar header field is too small for uid %lu, " "using nobody", (u_long)arcn->sb.st_uid); } if (ul_oct(uid_nobody, hd->uid, sizeof(hd->uid), 3)) goto out; } if (ul_oct(arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3)) { if (gid_nobody == 0) { if (gid_name("nobody", &gid_nobody) == -1) goto out; } if (gid_warn != arcn->sb.st_gid) { gid_warn = arcn->sb.st_gid; paxwarn(1, "Ustar header field is too small for gid %lu, " "using nobody", (u_long)arcn->sb.st_gid); } if (ul_oct(gid_nobody, hd->gid, sizeof(hd->gid), 3)) goto out; } if (ull_oct(arcn->sb.st_mtime < 0 ? 0 : arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 3) || ul_oct(arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3)) goto out; if (!Nflag) { strncpy(hd->uname, name_uid(arcn->sb.st_uid, 0), sizeof(hd->uname)); strncpy(hd->gname, name_gid(arcn->sb.st_gid, 0), sizeof(hd->gname)); } else { strncpy(hd->uname, "", sizeof(hd->uname)); strncpy(hd->gname, "", sizeof(hd->gname)); } /* * calculate and store the checksum write the header to the archive * return 0 tells the caller to now write the file data, 1 says no data * needs to be written */ if (ul_oct(tar_chksm(hdblk, sizeof(HD_USTAR)), hd->chksum, sizeof(hd->chksum), 3)) goto out; if (wr_rdbuf(hdblk, sizeof(HD_USTAR)) < 0) return(-1); if (wr_skip(BLKMULT - sizeof(HD_USTAR)) < 0) return(-1); if (PAX_IS_REG(arcn->type)) return(0); return(1); out: /* * header field is out of range */ paxwarn(1, "Ustar header field is too small for %s", arcn->org_name); return(1); }