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;
Example #2
0
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;
}
Example #3
0
// 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;
}
Example #4
0
/** \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));
}
Example #5
0
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;
}
Example #6
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);
}