add -t option for gmt time offset (normally MS-DOS filesystem has timestamp

in localtime, not GMT).  PR kern/22717
This commit is contained in:
itojun 2003-09-07 22:09:11 +00:00
parent ece5b8e67d
commit ce112dfc4f
8 changed files with 66 additions and 37 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: mount_msdos.8,v 1.27 2003/08/02 11:43:21 jdolecek Exp $ .\" $NetBSD: mount_msdos.8,v 1.28 2003/09/07 22:09:11 itojun Exp $
.\" .\"
.\" Copyright (c) 1993, 1994 Christopher G. Demetriou .\" Copyright (c) 1993, 1994 Christopher G. Demetriou
.\" All rights reserved. .\" All rights reserved.
@ -45,6 +45,7 @@
.Op Fl g Ar gid .Op Fl g Ar gid
.Op Fl m Ar mask .Op Fl m Ar mask
.Op Fl M Ar mask .Op Fl M Ar mask
.Op Fl t Ar gmtoff
.Op Fl s .Op Fl s
.Op Fl l .Op Fl l
.Op Fl 9 .Op Fl 9
@ -113,6 +114,11 @@ in the file system. The value of
is used if it is supplied and is used if it is supplied and
.Fl M .Fl M
is omitted. See description of previous option for details. is omitted. See description of previous option for details.
.It Fl t Ar gmtoff
Set the time zone offset (in seconds) from UTC to
.Ar gmtoff ,
with positive values indicating east of the Prime Meridian.
If not set, the user's current time zone will be used.
.It Fl s .It Fl s
Force behaviour to Force behaviour to
ignore and not generate Win'95 long filenames. ignore and not generate Win'95 long filenames.

View File

@ -1,4 +1,4 @@
/* $NetBSD: mount_msdos.c,v 1.30 2003/08/02 11:42:20 jdolecek Exp $ */ /* $NetBSD: mount_msdos.c,v 1.31 2003/09/07 22:09:11 itojun Exp $ */
/* /*
* Copyright (c) 1994 Christopher G. Demetriou * Copyright (c) 1994 Christopher G. Demetriou
@ -36,7 +36,7 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
#ifndef lint #ifndef lint
__RCSID("$NetBSD: mount_msdos.c,v 1.30 2003/08/02 11:42:20 jdolecek Exp $"); __RCSID("$NetBSD: mount_msdos.c,v 1.31 2003/09/07 22:09:11 itojun Exp $");
#endif /* not lint */ #endif /* not lint */
#include <sys/cdefs.h> #include <sys/cdefs.h>
@ -51,6 +51,7 @@ __RCSID("$NetBSD: mount_msdos.c,v 1.30 2003/08/02 11:42:20 jdolecek Exp $");
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h>
#include <unistd.h> #include <unistd.h>
#include <util.h> #include <util.h>
@ -87,13 +88,15 @@ mount_msdos(argc, argv)
{ {
struct msdosfs_args args; struct msdosfs_args args;
struct stat sb; struct stat sb;
int c, mntflags, set_gid, set_uid, set_mask, set_dirmask; int c, mntflags, set_gid, set_uid, set_mask, set_dirmask, set_gmtoff;
char *dev, *dir, ndir[MAXPATHLEN+1]; char *dev, *dir, ndir[MAXPATHLEN+1];
time_t now;
struct tm *tm;
mntflags = set_gid = set_uid = set_mask = set_dirmask = 0; mntflags = set_gid = set_uid = set_mask = set_dirmask = set_gmtoff = 0;
(void)memset(&args, '\0', sizeof(args)); (void)memset(&args, '\0', sizeof(args));
while ((c = getopt(argc, argv, "Gsl9u:g:m:M:o:")) != -1) { while ((c = getopt(argc, argv, "Gsl9u:g:m:M:o:t:")) != -1) {
switch (c) { switch (c) {
case 'G': case 'G':
args.flags |= MSDOSFSMNT_GEMDOSFS; args.flags |= MSDOSFSMNT_GEMDOSFS;
@ -126,6 +129,10 @@ mount_msdos(argc, argv)
case 'o': case 'o':
getmntopts(optarg, mopts, &mntflags, 0); getmntopts(optarg, mopts, &mntflags, 0);
break; break;
case 't':
args.gmtoff = atoi(optarg);
set_gmtoff = 1;
break;
case '?': case '?':
default: default:
usage(); usage();
@ -175,6 +182,14 @@ mount_msdos(argc, argv)
sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
} }
} }
if (!set_gmtoff) {
/* use user's time zone as default */
time(&now);
tm = localtime(&now);
args.gmtoff = tm->tm_gmtoff;
}
args.flags |= MSDOSFSMNT_VERSIONED; args.flags |= MSDOSFSMNT_VERSIONED;
args.version = MSDOSFSMNT_VERSION; args.version = MSDOSFSMNT_VERSION;

View File

@ -1,4 +1,4 @@
/* $NetBSD: denode.h,v 1.3 2003/06/29 22:31:09 fvdl Exp $ */ /* $NetBSD: denode.h,v 1.4 2003/09/07 22:09:11 itojun Exp $ */
/*- /*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -221,18 +221,18 @@ struct denode {
#define VTODE(vp) ((struct denode *)(vp)->v_data) #define VTODE(vp) ((struct denode *)(vp)->v_data)
#define DETOV(de) ((de)->de_vnode) #define DETOV(de) ((de)->de_vnode)
#define DETIMES(dep, acc, mod, cre) \ #define DETIMES(dep, acc, mod, cre, gmtoff) \
if ((dep)->de_flag & (DE_UPDATE | DE_CREATE | DE_ACCESS)) { \ if ((dep)->de_flag & (DE_UPDATE | DE_CREATE | DE_ACCESS)) { \
(dep)->de_flag |= DE_MODIFIED; \ (dep)->de_flag |= DE_MODIFIED; \
if ((dep)->de_flag & DE_UPDATE) { \ if ((dep)->de_flag & DE_UPDATE) { \
unix2dostime((mod), &(dep)->de_MDate, &(dep)->de_MTime, NULL); \ unix2dostime((mod), gmtoff, &(dep)->de_MDate, &(dep)->de_MTime, NULL); \
(dep)->de_Attributes |= ATTR_ARCHIVE; \ (dep)->de_Attributes |= ATTR_ARCHIVE; \
} \ } \
if (!((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95)) { \ if (!((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95)) { \
if ((dep)->de_flag & DE_ACCESS) \ if ((dep)->de_flag & DE_ACCESS) \
unix2dostime((acc), &(dep)->de_ADate, NULL, NULL); \ unix2dostime((acc), gmtoff, &(dep)->de_ADate, NULL, NULL); \
if ((dep)->de_flag & DE_CREATE) \ if ((dep)->de_flag & DE_CREATE) \
unix2dostime((cre), &(dep)->de_CDate, &(dep)->de_CTime, &(dep)->de_CHun); \ unix2dostime((cre), gmtoff, &(dep)->de_CDate, &(dep)->de_CTime, &(dep)->de_CHun); \
} \ } \
(dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \ (dep)->de_flag &= ~(DE_UPDATE | DE_CREATE | DE_ACCESS); \
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: direntry.h,v 1.1 2002/12/26 12:31:33 jdolecek Exp $ */ /* $NetBSD: direntry.h,v 1.2 2003/09/07 22:09:11 itojun Exp $ */
/*- /*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -119,9 +119,10 @@ struct winentry {
#define DD_YEAR_SHIFT 9 #define DD_YEAR_SHIFT 9
#ifdef _KERNEL #ifdef _KERNEL
void unix2dostime __P((struct timespec *tsp, u_int16_t *ddp, void unix2dostime __P((struct timespec *tsp, int gmtoff, u_int16_t *ddp,
u_int16_t *dtp, u_int8_t *dhp)); u_int16_t *dtp, u_int8_t *dhp));
void dos2unixtime __P((u_int dd, u_int dt, u_int dh, struct timespec *tsp)); void dos2unixtime __P((u_int dd, u_int dt, u_int dh, int gmtoff,
struct timespec *tsp));
int dos2unixfn __P((u_char dn[11], u_char *un, int lower)); int dos2unixfn __P((u_char dn[11], u_char *un, int lower));
int unix2dosfn __P((const u_char *un, u_char dn[12], int unlen, int unix2dosfn __P((const u_char *un, u_char dn[12], int unlen,
u_int gen)); u_int gen));

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_conv.c,v 1.1 2002/12/26 12:31:34 jdolecek Exp $ */ /* $NetBSD: msdosfs_conv.c,v 1.2 2003/09/07 22:09:11 itojun Exp $ */
/*- /*-
* Copyright (C) 1995, 1997 Wolfgang Solfrank. * Copyright (C) 1995, 1997 Wolfgang Solfrank.
@ -48,7 +48,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msdosfs_conv.c,v 1.1 2002/12/26 12:31:34 jdolecek Exp $"); __KERNEL_RCSID(0, "$NetBSD: msdosfs_conv.c,v 1.2 2003/09/07 22:09:11 itojun Exp $");
/* /*
* System include files. * System include files.
@ -96,8 +96,9 @@ u_short lastdtime;
* file timestamps. The passed in unix time is assumed to be in GMT. * file timestamps. The passed in unix time is assumed to be in GMT.
*/ */
void void
unix2dostime(tsp, ddp, dtp, dhp) unix2dostime(tsp, gmtoff, ddp, dtp, dhp)
struct timespec *tsp; struct timespec *tsp;
int gmtoff;
u_int16_t *ddp; u_int16_t *ddp;
u_int16_t *dtp; u_int16_t *dtp;
u_int8_t *dhp; u_int8_t *dhp;
@ -113,8 +114,7 @@ unix2dostime(tsp, ddp, dtp, dhp)
* If the time from the last conversion is the same as now, then * If the time from the last conversion is the same as now, then
* skip the computations and use the saved result. * skip the computations and use the saved result.
*/ */
t = tsp->tv_sec - (rtc_offset * 60) t = tsp->tv_sec + gmtoff; /* time zone correction */
/* +- daylight savings time correction */ ;
t &= ~1; t &= ~1;
if (lasttime != t) { if (lasttime != t) {
lasttime = t; lasttime = t;
@ -177,10 +177,11 @@ u_long lastseconds;
* not be too efficient. * not be too efficient.
*/ */
void void
dos2unixtime(dd, dt, dh, tsp) dos2unixtime(dd, dt, dh, gmtoff, tsp)
u_int dd; u_int dd;
u_int dt; u_int dt;
u_int dh; u_int dh;
int gmtoff;
struct timespec *tsp; struct timespec *tsp;
{ {
u_long seconds; u_long seconds;
@ -227,8 +228,8 @@ dos2unixtime(dd, dt, dh, tsp)
days += ((dd & DD_DAY_MASK) >> DD_DAY_SHIFT) - 1; days += ((dd & DD_DAY_MASK) >> DD_DAY_SHIFT) - 1;
lastseconds = (days * 24 * 60 * 60) + SECONDSTO1980; lastseconds = (days * 24 * 60 * 60) + SECONDSTO1980;
} }
tsp->tv_sec = seconds + lastseconds + (rtc_offset * 60) tsp->tv_sec = seconds + lastseconds;
/* -+ daylight savings time correction */ ; tsp->tv_sec -= gmtoff; /* time zone correction */
tsp->tv_nsec = (dh % 100) * 10000000; tsp->tv_nsec = (dh % 100) * 10000000;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_vfsops.c,v 1.8 2003/08/02 11:41:21 jdolecek Exp $ */ /* $NetBSD: msdosfs_vfsops.c,v 1.9 2003/09/07 22:09:11 itojun Exp $ */
/*- /*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -48,7 +48,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.8 2003/08/02 11:41:21 jdolecek Exp $"); __KERNEL_RCSID(0, "$NetBSD: msdosfs_vfsops.c,v 1.9 2003/09/07 22:09:11 itojun Exp $");
#if defined(_KERNEL_OPT) #if defined(_KERNEL_OPT)
#include "opt_quota.h" #include "opt_quota.h"
@ -147,6 +147,7 @@ update_mp(mp, argp)
pmp->pm_uid = argp->uid; pmp->pm_uid = argp->uid;
pmp->pm_mask = argp->mask & ALLPERMS; pmp->pm_mask = argp->mask & ALLPERMS;
pmp->pm_dirmask = argp->dirmask & ALLPERMS; pmp->pm_dirmask = argp->dirmask & ALLPERMS;
pmp->pm_gmtoff = argp->gmtoff;
pmp->pm_flags |= argp->flags & MSDOSFSMNT_MNTOPT; pmp->pm_flags |= argp->flags & MSDOSFSMNT_MNTOPT;
/* /*

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfs_vnops.c,v 1.6 2003/08/02 11:41:21 jdolecek Exp $ */ /* $NetBSD: msdosfs_vnops.c,v 1.7 2003/09/07 22:09:11 itojun Exp $ */
/*- /*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -48,7 +48,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.6 2003/08/02 11:41:21 jdolecek Exp $"); __KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.7 2003/09/07 22:09:11 itojun Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -156,7 +156,7 @@ msdosfs_create(v)
ndirent.de_pmp = pdep->de_pmp; ndirent.de_pmp = pdep->de_pmp;
ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE; ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE;
TIMEVAL_TO_TIMESPEC(&time, &ts); TIMEVAL_TO_TIMESPEC(&time, &ts);
DETIMES(&ndirent, &ts, &ts, &ts); DETIMES(&ndirent, &ts, &ts, &ts, pdep->de_pmp->pm_gmtoff);
if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0) if ((error = createde(&ndirent, pdep, &dep, cnp)) != 0)
goto bad; goto bad;
if ((cnp->cn_flags & SAVESTART) == 0) if ((cnp->cn_flags & SAVESTART) == 0)
@ -221,7 +221,7 @@ msdosfs_close(v)
simple_lock(&vp->v_interlock); simple_lock(&vp->v_interlock);
if (vp->v_usecount > 1) { if (vp->v_usecount > 1) {
TIMEVAL_TO_TIMESPEC(&time, &ts); TIMEVAL_TO_TIMESPEC(&time, &ts);
DETIMES(dep, &ts, &ts, &ts); DETIMES(dep, &ts, &ts, &ts, dep->de_pmp->pm_gmtoff);
} }
simple_unlock(&vp->v_interlock); simple_unlock(&vp->v_interlock);
return (0); return (0);
@ -287,7 +287,7 @@ msdosfs_getattr(v)
u_long fileid; u_long fileid;
TIMEVAL_TO_TIMESPEC(&time, &ts); TIMEVAL_TO_TIMESPEC(&time, &ts);
DETIMES(dep, &ts, &ts, &ts); DETIMES(dep, &ts, &ts, &ts, pmp->pm_gmtoff);
vap->va_fsid = dep->de_dev; vap->va_fsid = dep->de_dev;
/* /*
* The following computation of the fileid must be the same as that * The following computation of the fileid must be the same as that
@ -316,10 +316,13 @@ msdosfs_getattr(v)
vap->va_nlink = 1; vap->va_nlink = 1;
vap->va_rdev = 0; vap->va_rdev = 0;
vap->va_size = ap->a_vp->v_size; vap->va_size = ap->a_vp->v_size;
dos2unixtime(dep->de_MDate, dep->de_MTime, 0, &vap->va_mtime); dos2unixtime(dep->de_MDate, dep->de_MTime, 0, pmp->pm_gmtoff,
&vap->va_mtime);
if (dep->de_pmp->pm_flags & MSDOSFSMNT_LONGNAME) { if (dep->de_pmp->pm_flags & MSDOSFSMNT_LONGNAME) {
dos2unixtime(dep->de_ADate, 0, 0, &vap->va_atime); dos2unixtime(dep->de_ADate, 0, 0, pmp->pm_gmtoff,
dos2unixtime(dep->de_CDate, dep->de_CTime, dep->de_CHun, &vap->va_ctime); &vap->va_atime);
dos2unixtime(dep->de_CDate, dep->de_CTime, dep->de_CHun,
pmp->pm_gmtoff, &vap->va_ctime);
} else { } else {
vap->va_atime = vap->va_mtime; vap->va_atime = vap->va_mtime;
vap->va_ctime = vap->va_mtime; vap->va_ctime = vap->va_mtime;
@ -398,9 +401,9 @@ msdosfs_setattr(v)
return (error); return (error);
if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 && if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 &&
vap->va_atime.tv_sec != VNOVAL) vap->va_atime.tv_sec != VNOVAL)
unix2dostime(&vap->va_atime, &dep->de_ADate, NULL, NULL); unix2dostime(&vap->va_atime, pmp->pm_gmtoff, &dep->de_ADate, NULL, NULL);
if (vap->va_mtime.tv_sec != VNOVAL) if (vap->va_mtime.tv_sec != VNOVAL)
unix2dostime(&vap->va_mtime, &dep->de_MDate, &dep->de_MTime, NULL); unix2dostime(&vap->va_mtime, pmp->pm_gmtoff, &dep->de_MDate, &dep->de_MTime, NULL);
dep->de_Attributes |= ATTR_ARCHIVE; dep->de_Attributes |= ATTR_ARCHIVE;
dep->de_flag |= DE_MODIFIED; dep->de_flag |= DE_MODIFIED;
de_changed = 1; de_changed = 1;
@ -707,7 +710,7 @@ msdosfs_update(v)
TIMEVAL_TO_TIMESPEC(&time, &ts); TIMEVAL_TO_TIMESPEC(&time, &ts);
DETIMES(dep, DETIMES(dep,
ap->a_access ? ap->a_access : &ts, ap->a_access ? ap->a_access : &ts,
ap->a_modify ? ap->a_modify : &ts, &ts); ap->a_modify ? ap->a_modify : &ts, &ts, dep->de_pmp->pm_gmtoff);
if ((dep->de_flag & DE_MODIFIED) == 0) if ((dep->de_flag & DE_MODIFIED) == 0)
return (0); return (0);
dep->de_flag &= ~DE_MODIFIED; dep->de_flag &= ~DE_MODIFIED;
@ -1232,7 +1235,7 @@ msdosfs_mkdir(v)
ndirent.de_pmp = pmp; ndirent.de_pmp = pmp;
ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE; ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE;
TIMEVAL_TO_TIMESPEC(&time, &ts); TIMEVAL_TO_TIMESPEC(&time, &ts);
DETIMES(&ndirent, &ts, &ts, &ts); DETIMES(&ndirent, &ts, &ts, &ts, pmp->pm_gmtoff);
/* /*
* Now fill the cluster with the "." and ".." entries. And write * Now fill the cluster with the "." and ".." entries. And write

View File

@ -1,4 +1,4 @@
/* $NetBSD: msdosfsmount.h,v 1.3 2003/08/02 11:41:21 jdolecek Exp $ */ /* $NetBSD: msdosfsmount.h,v 1.4 2003/09/07 22:09:11 itojun Exp $ */
/*- /*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@ -56,6 +56,7 @@ struct msdosfs_args {
uid_t uid; /* uid that owns msdosfs files */ uid_t uid; /* uid that owns msdosfs files */
gid_t gid; /* gid that owns msdosfs files */ gid_t gid; /* gid that owns msdosfs files */
mode_t mask; /* mask to be applied for msdosfs perms */ mode_t mask; /* mask to be applied for msdosfs perms */
int gmtoff; /* offset from UTC in seconds */
int flags; /* see below */ int flags; /* see below */
/* Following items added after versioning support */ /* Following items added after versioning support */
@ -102,6 +103,7 @@ struct msdosfsmount {
for files */ for files */
mode_t pm_dirmask; /* mask to and with file protection bits mode_t pm_dirmask; /* mask to and with file protection bits
for directories */ for directories */
int pm_gmtoff; /* offset from UTC in seconds */
struct vnode *pm_devvp; /* vnode for block device mntd */ struct vnode *pm_devvp; /* vnode for block device mntd */
struct bpb50 pm_bpb; /* BIOS parameter blk for this fs */ struct bpb50 pm_bpb; /* BIOS parameter blk for this fs */
u_long pm_FATsecs; /* actual number of fat sectors */ u_long pm_FATsecs; /* actual number of fat sectors */