static void msdosfs_times(struct msdosfsmount *pmp, struct denode *dep, const struct stat *st) { #ifndef HAVE_NBTOOL_CONFIG_H struct timespec at = st->st_atimespec; struct timespec mt = st->st_mtimespec; #else struct timespec at = { st->st_atime, 0 }; struct timespec mt = { st->st_mtime, 0 }; #endif unix2dostime(&at, pmp->pm_gmtoff, &dep->de_ADate, NULL, NULL); unix2dostime(&mt, pmp->pm_gmtoff, &dep->de_MDate, &dep->de_MTime, NULL); }
/* =========================================================================== * If file *f does not exist, return 0. Else, return the file's last * modified date and time as an MSDOS date and time. The date and * time is returned in a long with the date most significant to allow * unsigned integer comparison of absolute times. Also, if a is not * a NULL pointer, store the file attributes there, with the high two * bytes being the Unix attributes, and the low byte being a mapping * of that to DOS attributes. If n is not NULL, store the file size * there. If t is not NULL, the file's access and modification time * are stored there as UNIX time_t values. * If f is "-", use standard input as the file. If f is a device, return * a file size of -1 *f :: Name of file to get info on. *a :: Return value: file attributes. *n :: Return value: file size. *t :: Return value: access and modification time. */ ulg filetime( char *f, ulg *a, long *n, ztimbuf *t, struct Globals *pG ) { struct stat s; /* results of stat() */ char name[FNMAX]; int len = lstrlen( f ), isstdin = !strcmp( f, "-" ); if ( f == pG->label ) { if ( a != NULL ) *a = pG->label_mode; if ( n != NULL ) *n = -2L; /* convention for a label name */ if ( t != NULL ) t->actime = t->modtime = pG->label_utim; return pG->label_time; } lstrcpy( name, f ); /* not all systems allow stat'ing a file with / appended, so remove it */ if ( name[len - 1] == '\\' ) name[len - 1] = '\0'; // SLASH /* Accept about any kind of file including directories */ if ( LSSTAT( GetFullPath( pG, name ), &s ) != 0 ) return 0; // error in stat! if ( a != NULL ) { *a = ( (ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)GetFileMode( pG, name ) ); } if ( n != NULL ) *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; if ( t != NULL ) { t->actime = s.st_atime; t->modtime = s.st_mtime; } return unix2dostime( (time_t *)&s.st_mtime ); }
/** \brief Get the MS-DOS date/time of this entry. * * This function returns the date and time of the entry in MSDOS * date/time format. * * \note * An MS-DOS date is limited to 127 years starting on 1980. * So it will be over after Dec 31, 2107. * * \return The date and time of the entry in MS-DOS format. */ FileEntry::dostime_t FileEntry::getTime() const { return unix2dostime(m_unix_time); }
int main(int argc, char *argv[]) { // define program name g_progname = argv[0]; char *e(strrchr(g_progname, '/')); if(e) { g_progname = e + 1; } e = strrchr(g_progname, '\\'); if(e) { g_progname = e + 1; } // check the various command line options time_mode_t mode(time_mode_t::DOS); for(int i(1); i < argc; ++i) { if(argv[i][0] == '-') { if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { usage(); } if(strcmp(argv[i], "--version") == 0) { // version of this tool (compiled with this version) // it should be the same as the --version std::cout << ZIPIOS_VERSION_STRING << std::endl; exit(0); } if(strcmp(argv[i], "--dec") == 0) { std::cout << std::dec; } else if(strcmp(argv[i], "--dos") == 0) { mode = time_mode_t::DOS; } else if(strcmp(argv[i], "--hex") == 0) { std::cout << std::hex; } else if(strcmp(argv[i], "--unix") == 0) { mode = time_mode_t::UNIX; } } else { // TODO: test that the argument is a valid number int64_t const t(atoll(argv[i])); int64_t r(0); time_t dt(t); switch(mode) { case time_mode_t::DOS: r = unix2dostime(t); break; case time_mode_t::UNIX: r = dos2unixtime(t); dt = r; break; } struct tm *dtm(localtime(&dt)); char buf[256]; if(dt == -1) { strcpy(buf, "- -"); } else { strftime(buf, sizeof(buf), "%Y/%m/%d %T", dtm); } buf[255] = '\0'; std::cout << t << " " << r << " " << buf << std::endl; } } return 0; }
int msdosfs_setattr(void *v) { struct vop_setattr_args *ap = v; int error = 0; struct denode *dep = VTODE(ap->a_vp); struct vattr *vap = ap->a_vap; struct ucred *cred = ap->a_cred; #ifdef MSDOSFS_DEBUG printf("msdosfs_setattr(): vp %08x, vap %08x, cred %08x, p %08x\n", ap->a_vp, vap, cred, ap->a_p); #endif if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL) || (vap->va_uid != VNOVAL) || (vap->va_gid != VNOVAL)) { #ifdef MSDOSFS_DEBUG printf("msdosfs_setattr(): returning EINVAL\n"); printf(" va_type %d, va_nlink %x, va_fsid %x, va_fileid %x\n", vap->va_type, vap->va_nlink, vap->va_fsid, vap->va_fileid); printf(" va_blocksize %x, va_rdev %x, va_bytes %x, va_gen %x\n", vap->va_blocksize, vap->va_rdev, vap->va_bytes, vap->va_gen); printf(" va_uid %x, va_gid %x\n", vap->va_uid, vap->va_gid); #endif return (EINVAL); } /* * Directories must not ever get their attributes modified */ if (ap->a_vp->v_type == VDIR) return (0); if (vap->va_size != VNOVAL) { error = detrunc(dep, (uint32_t)vap->va_size, 0, cred, ap->a_p); if (error) return (error); } if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { if (cred->cr_uid != dep->de_pmp->pm_uid && (error = suser_ucred(cred)) && ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || (error = VOP_ACCESS(ap->a_vp, VWRITE, cred, ap->a_p)))) return (error); if (!(dep->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95) && vap->va_atime.tv_sec != VNOVAL) unix2dostime(&vap->va_atime, &dep->de_ADate, NULL, NULL); if (vap->va_mtime.tv_sec != VNOVAL) unix2dostime(&vap->va_mtime, &dep->de_MDate, &dep->de_MTime, NULL); dep->de_Attributes |= ATTR_ARCHIVE; dep->de_flag |= DE_MODIFIED; } /* * DOS files only have the ability to have their writability * attribute set, so we use the owner write bit to set the readonly * attribute. */ if (vap->va_mode != (mode_t)VNOVAL) { if (cred->cr_uid != dep->de_pmp->pm_uid && (error = suser_ucred(cred))) return (error); /* We ignore the read and execute bits. */ if (vap->va_mode & VWRITE) dep->de_Attributes &= ~ATTR_READONLY; else dep->de_Attributes |= ATTR_READONLY; dep->de_flag |= DE_MODIFIED; } /* * Allow the `archived' bit to be toggled. */ if (vap->va_flags != VNOVAL) { if (cred->cr_uid != dep->de_pmp->pm_uid && (error = suser_ucred(cred))) return (error); if (vap->va_flags & SF_ARCHIVED) dep->de_Attributes &= ~ATTR_ARCHIVE; else dep->de_Attributes |= ATTR_ARCHIVE; dep->de_flag |= DE_MODIFIED; } return (deupdat(dep, 1)); }
// Process -o and -m options (if specified), free up malloc'ed stuff, and // exit with the code e. e :: Exit code. static void finish(struct Globals *pG) { int r; // return value from trash() ulg t; // latest time in zip file struct zlist *z; // pointer into zfile list // If latest, set time to zip file to latest file in zip file if (pG->latest && pG->zipfile && strcmp(pG->zipfile, "-")) { diag("changing time of zip file to time of latest file in it", pG); // find latest time in zip file if (pG->zfiles == NULL) { Inform(pG, 0, IWARNING, "zip file is empty, can't make it as old as latest entry"); } else { t = 0; for (z = pG->zfiles; z != NULL; z = z->nxt) // Ignore directories in time comparisons #ifdef USE_EF_UX_TIME if (z->zname[z->nam - 1] != '\\') { // SLASH ztimbuf z_utim; ulg z_tim; z_tim = (get_ef_ux_ztime(z, &z_utim) ? unix2dostime(&z_utim.modtime): z->tim); if (t < z_tim) t = z_tim; } #else if (z->zname[z->nam - 1] != '\\' && t < z->tim) t = z->tim; // SLASH #endif // set modified time of zip file to that time if (t != 0) stamp(pG->zipfile, t); else { Inform(pG, 0, IWARNING, "zip file has only directories, can't make it as old as latest entry") ; } } } if (pG->tempath != NULL) { FREE(pG->tempath); pG->tempath = NULL; } if (pG->zipfile != NULL) { FREE(pG->zipfile); pG->zipfile = NULL; } // If dispose, delete all files in the zfiles list that are marked if (pG->dispose && !pG->global_abort_sw) { // v1.6017 diag("deleting files that were added to zip file", pG); if ((r = trash(pG)) != ZEN_OK) ziperr(r, pG); return ; } #ifdef CRYPT // RCV: 1.604 added if (pG->user_key) // p release user password { FREE(pG->user_key); pG->user_key = NULL; } #endif // Done! freeup(pG); }