char *getVolumeLabel(int drive, ulg *vtime, ulg *vmode, time_t* vutim) //int drive; /* drive name: 'A' .. 'Z' or '\0' for current drive */ //ulg *vtime; /* volume label creation time (DOS format) */ //ulg *vmode; /* volume label file mode */ //time_t *vutim;/* volume label creationtime (UNIX format) */ /* If a volume label exists for the given drive, return its name and pretend to set its time and mode. The returned name is static data. */ { char rootpath[4]; static char vol[14]; DWORD fnlen, flags; *vmode = A_ARCHIVE | A_LABEL; /* this is what msdos returns */ *vtime = dostime(1980, 1, 1, 0, 0, 0); /* no true date info available */ *vutim = dos2unixtime(*vtime); strcpy(rootpath, "x:\\"); rootpath[0] = (char)drive; if (GetVolumeInformation(drive ? rootpath : NULL, vol, 13, NULL, &fnlen, &flags, NULL, 0)) #ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ return (AnsiToOem(vol, vol), vol); #else return vol; #endif else return NULL;
static int record_zfiles (zipinfo *zinfo) { zlist *z = zfiles; int i, nz = 0; int err = 0; while (z != NULL) { nz++; z = z->nxt; } if (nz == 0) { return ZE_NONE; } err = zipinfo_make_arrays(zinfo, nz); if (err) { return err; } zinfo->nfiles = nz; z = zfiles; for (i=0; i<nz; i++) { zinfo->fnames[i] = g_strdup(z->name); zinfo->fsizes[i] = z->usize; zinfo->mtimes[i] = dos2unixtime(z->time); z = z->nxt; } return err; }
// cached call to 'stat' - return true if not found bool DZOp::ZStat(const DZStrW &fn, struct stati64 *res) { if (!lastStatName.IsEmpty() && ZMatch(lastStatName, fn)) // if (!fn.Compare(lastStatName.c_str())) { memcpy(res, &lastStat, sizeof(struct stati64)); return false; } lastStatName.empty(); bool ok; int drv = Is_Drv(fn); if (drv < 0) { memset(res, 0, sizeof(struct stati64)); ZSData.Number = (-drv) - 2; // stream number ZSData.OpCode = zsaIdentify; int r = StreamCB(); ok = (r == CALLBACK_TRUE); if (ok) { res->st_size = ZSData.ArgLL; res->st_atime = res->st_mtime = res->st_ctime = dos2unixtime(ZSData.ArgD); long attr = (long)ZSData.ArgA; res->st_mode = S_IREAD; if (attr & FILE_ATTRIBUTE_DIRECTORY) res->st_mode |= (S_IFDIR | S_IWRITE | S_IEXEC) ; else { #ifdef _WIN64 res->st_mode |= (unsigned short)S_IFREG; #else res->st_mode |= (mode_t)S_IFREG; #endif if ((attr & FILE_ATTRIBUTE_READONLY) == 0) res->st_mode |= S_IWRITE; } res->st_nlink = 1; } } else ok = !_tstati64(fn.c_str(), res); if (ok) { lastStatName = fn; memcpy(&lastStat, res, sizeof(struct stati64)); } return ok ? false : true; }
/** \brief Set the FileEntry time using a DOS time. * * This function saves the specified \p dostime value as the last modification * date and time of this entry. This is generally used when reading that information * from a Zip archive. Otherwise you probably want to use the setUnixTime() * instead since it is one to one compatible with the value handle by time(), * stat(), and other OS functions. * * \param[in] dostime Set time field as is using this MSDOS date/time value. */ void FileEntry::setTime(dostime_t dostime) { setUnixTime(dos2unixtime(dostime)); }
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_getattr(void *v) { struct vop_getattr_args *ap = v; struct denode *dep = VTODE(ap->a_vp); struct msdosfsmount *pmp = dep->de_pmp; struct vattr *vap = ap->a_vap; struct timespec ts; uint32_t fileid; getnanotime(&ts); DETIMES(dep, &ts, &ts, &ts); vap->va_fsid = dep->de_dev; /* * The following computation of the fileid must be the same as * that used in msdosfs_readdir() to compute d_fileno. If not, * pwd doesn't work. * * We now use the starting cluster number as the fileid/fileno. * This works for both files and directories (including the root * directory, on FAT32). Even on FAT32, this will at most be a * 28-bit number, as the high 4 bits of FAT32 cluster numbers * are reserved. * * However, we do need to do something for 0-length files, which * will not have a starting cluster number. * * These files cannot be directories, since (except for /, which * is special-cased anyway) directories contain entries for . and * .., so must have non-zero length. * * In this case, we just create a non-cryptographic hash of the * original fileid calculation, and set the top bit. * * This algorithm has the benefit that all directories, and all * non-zero-length files, will have fileids that are persistent * across mounts and reboots, and that cannot collide (as long * as the filesystem is not corrupt). Zero-length files will * have fileids that are persistent, but that may collide. We * will just have to live with that. */ fileid = dep->de_StartCluster; if (dep->de_Attributes & ATTR_DIRECTORY) { /* Special-case root */ if (dep->de_StartCluster == MSDOSFSROOT) fileid = FAT32(pmp) ? pmp->pm_rootdirblk : 1; } else { if (dep->de_FileSize == 0) { uint32_t dirsperblk; uint64_t fileid64; dirsperblk = pmp->pm_BytesPerSec / sizeof(struct direntry); fileid64 = (dep->de_dirclust == MSDOSFSROOT) ? roottobn(pmp, 0) : cntobn(pmp, dep->de_dirclust); fileid64 *= dirsperblk; fileid64 += dep->de_diroffset / sizeof(struct direntry); fileid = fileidhash(fileid64); } } vap->va_fileid = fileid; vap->va_mode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) | ((dep->de_Attributes & ATTR_READONLY) ? 0 : (S_IWUSR|S_IWGRP|S_IWOTH)); vap->va_mode &= dep->de_pmp->pm_mask; if (dep->de_Attributes & ATTR_DIRECTORY) { vap->va_mode |= S_IFDIR; if (pmp->pm_flags & MSDOSFSMNT_ALLOWDIRX) { vap->va_mode |= (vap->va_mode & S_IRUSR) ? S_IXUSR : 0; vap->va_mode |= (vap->va_mode & S_IRGRP) ? S_IXGRP : 0; vap->va_mode |= (vap->va_mode & S_IROTH) ? S_IXOTH : 0; } } vap->va_nlink = 1; vap->va_gid = dep->de_pmp->pm_gid; vap->va_uid = dep->de_pmp->pm_uid; vap->va_rdev = 0; vap->va_size = dep->de_FileSize; dos2unixtime(dep->de_MDate, dep->de_MTime, 0, &vap->va_mtime); if (dep->de_pmp->pm_flags & MSDOSFSMNT_LONGNAME) { dos2unixtime(dep->de_ADate, 0, 0, &vap->va_atime); dos2unixtime(dep->de_CDate, dep->de_CTime, dep->de_CTimeHundredth, &vap->va_ctime); } else { vap->va_atime = vap->va_mtime; vap->va_ctime = vap->va_mtime; } vap->va_flags = 0; if ((dep->de_Attributes & ATTR_ARCHIVE) == 0) vap->va_flags |= SF_ARCHIVED; vap->va_gen = 0; vap->va_blocksize = dep->de_pmp->pm_bpcluster; vap->va_bytes = (dep->de_FileSize + dep->de_pmp->pm_crbomask) & ~(dep->de_pmp->pm_crbomask); vap->va_type = ap->a_vp->v_type; return (0); }