From ce112dfc4f1d51bb94cf730cf8c90867614dfd90 Mon Sep 17 00:00:00 2001 From: itojun Date: Sun, 7 Sep 2003 22:09:11 +0000 Subject: [PATCH] add -t option for gmt time offset (normally MS-DOS filesystem has timestamp in localtime, not GMT). PR kern/22717 --- sbin/mount_msdos/mount_msdos.8 | 8 +++++++- sbin/mount_msdos/mount_msdos.c | 25 ++++++++++++++++++++----- sys/fs/msdosfs/denode.h | 10 +++++----- sys/fs/msdosfs/direntry.h | 7 ++++--- sys/fs/msdosfs/msdosfs_conv.c | 17 +++++++++-------- sys/fs/msdosfs/msdosfs_vfsops.c | 5 +++-- sys/fs/msdosfs/msdosfs_vnops.c | 27 +++++++++++++++------------ sys/fs/msdosfs/msdosfsmount.h | 4 +++- 8 files changed, 66 insertions(+), 37 deletions(-) diff --git a/sbin/mount_msdos/mount_msdos.8 b/sbin/mount_msdos/mount_msdos.8 index 66a13fcf7cb8..4792b47724ae 100644 --- a/sbin/mount_msdos/mount_msdos.8 +++ b/sbin/mount_msdos/mount_msdos.8 @@ -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 .\" All rights reserved. @@ -45,6 +45,7 @@ .Op Fl g Ar gid .Op Fl m Ar mask .Op Fl M Ar mask +.Op Fl t Ar gmtoff .Op Fl s .Op Fl l .Op Fl 9 @@ -113,6 +114,11 @@ in the file system. The value of is used if it is supplied and .Fl M 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 Force behaviour to ignore and not generate Win'95 long filenames. diff --git a/sbin/mount_msdos/mount_msdos.c b/sbin/mount_msdos/mount_msdos.c index 8eebe3322c46..0d14be365d6e 100644 --- a/sbin/mount_msdos/mount_msdos.c +++ b/sbin/mount_msdos/mount_msdos.c @@ -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 @@ -36,7 +36,7 @@ #include #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 */ #include @@ -51,6 +51,7 @@ __RCSID("$NetBSD: mount_msdos.c,v 1.30 2003/08/02 11:42:20 jdolecek Exp $"); #include #include #include +#include #include #include @@ -87,13 +88,15 @@ mount_msdos(argc, argv) { struct msdosfs_args args; 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]; + 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)); - 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) { case 'G': args.flags |= MSDOSFSMNT_GEMDOSFS; @@ -126,6 +129,10 @@ mount_msdos(argc, argv) case 'o': getmntopts(optarg, mopts, &mntflags, 0); break; + case 't': + args.gmtoff = atoi(optarg); + set_gmtoff = 1; + break; case '?': default: usage(); @@ -175,6 +182,14 @@ mount_msdos(argc, argv) 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.version = MSDOSFSMNT_VERSION; diff --git a/sys/fs/msdosfs/denode.h b/sys/fs/msdosfs/denode.h index 1c4ad866ca9d..193f68556a8e 100644 --- a/sys/fs/msdosfs/denode.h +++ b/sys/fs/msdosfs/denode.h @@ -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. @@ -221,18 +221,18 @@ struct denode { #define VTODE(vp) ((struct denode *)(vp)->v_data) #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)) { \ (dep)->de_flag |= DE_MODIFIED; \ 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; \ } \ if (!((dep)->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95)) { \ 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) \ - 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); \ } diff --git a/sys/fs/msdosfs/direntry.h b/sys/fs/msdosfs/direntry.h index e68e7e861b0c..857fac0930ea 100644 --- a/sys/fs/msdosfs/direntry.h +++ b/sys/fs/msdosfs/direntry.h @@ -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. @@ -119,9 +119,10 @@ struct winentry { #define DD_YEAR_SHIFT 9 #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)); -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 unix2dosfn __P((const u_char *un, u_char dn[12], int unlen, u_int gen)); diff --git a/sys/fs/msdosfs/msdosfs_conv.c b/sys/fs/msdosfs/msdosfs_conv.c index cf8bb7b62115..62eb8cc0d0bd 100644 --- a/sys/fs/msdosfs/msdosfs_conv.c +++ b/sys/fs/msdosfs/msdosfs_conv.c @@ -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. @@ -48,7 +48,7 @@ */ #include -__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. @@ -96,8 +96,9 @@ u_short lastdtime; * file timestamps. The passed in unix time is assumed to be in GMT. */ void -unix2dostime(tsp, ddp, dtp, dhp) +unix2dostime(tsp, gmtoff, ddp, dtp, dhp) struct timespec *tsp; + int gmtoff; u_int16_t *ddp; u_int16_t *dtp; 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 * skip the computations and use the saved result. */ - t = tsp->tv_sec - (rtc_offset * 60) - /* +- daylight savings time correction */ ; + t = tsp->tv_sec + gmtoff; /* time zone correction */ t &= ~1; if (lasttime != t) { lasttime = t; @@ -177,10 +177,11 @@ u_long lastseconds; * not be too efficient. */ void -dos2unixtime(dd, dt, dh, tsp) +dos2unixtime(dd, dt, dh, gmtoff, tsp) u_int dd; u_int dt; u_int dh; + int gmtoff; struct timespec *tsp; { u_long seconds; @@ -227,8 +228,8 @@ dos2unixtime(dd, dt, dh, tsp) days += ((dd & DD_DAY_MASK) >> DD_DAY_SHIFT) - 1; lastseconds = (days * 24 * 60 * 60) + SECONDSTO1980; } - tsp->tv_sec = seconds + lastseconds + (rtc_offset * 60) - /* -+ daylight savings time correction */ ; + tsp->tv_sec = seconds + lastseconds; + tsp->tv_sec -= gmtoff; /* time zone correction */ tsp->tv_nsec = (dh % 100) * 10000000; } diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index a7642214e0ae..cd406c55c5f4 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -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. @@ -48,7 +48,7 @@ */ #include -__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) #include "opt_quota.h" @@ -147,6 +147,7 @@ update_mp(mp, argp) pmp->pm_uid = argp->uid; pmp->pm_mask = argp->mask & ALLPERMS; pmp->pm_dirmask = argp->dirmask & ALLPERMS; + pmp->pm_gmtoff = argp->gmtoff; pmp->pm_flags |= argp->flags & MSDOSFSMNT_MNTOPT; /* diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 844afd8f4a31..19b445740f01 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -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. @@ -48,7 +48,7 @@ */ #include -__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 #include @@ -156,7 +156,7 @@ msdosfs_create(v) ndirent.de_pmp = pdep->de_pmp; ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE; 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) goto bad; if ((cnp->cn_flags & SAVESTART) == 0) @@ -221,7 +221,7 @@ msdosfs_close(v) simple_lock(&vp->v_interlock); if (vp->v_usecount > 1) { 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); return (0); @@ -287,7 +287,7 @@ msdosfs_getattr(v) u_long fileid; TIMEVAL_TO_TIMESPEC(&time, &ts); - DETIMES(dep, &ts, &ts, &ts); + DETIMES(dep, &ts, &ts, &ts, pmp->pm_gmtoff); vap->va_fsid = dep->de_dev; /* * 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_rdev = 0; 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) { - dos2unixtime(dep->de_ADate, 0, 0, &vap->va_atime); - dos2unixtime(dep->de_CDate, dep->de_CTime, dep->de_CHun, &vap->va_ctime); + dos2unixtime(dep->de_ADate, 0, 0, pmp->pm_gmtoff, + &vap->va_atime); + dos2unixtime(dep->de_CDate, dep->de_CTime, dep->de_CHun, + pmp->pm_gmtoff, &vap->va_ctime); } else { vap->va_atime = vap->va_mtime; vap->va_ctime = vap->va_mtime; @@ -398,9 +401,9 @@ msdosfs_setattr(v) return (error); if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 && 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) - 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_flag |= DE_MODIFIED; de_changed = 1; @@ -707,7 +710,7 @@ msdosfs_update(v) TIMEVAL_TO_TIMESPEC(&time, &ts); DETIMES(dep, 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) return (0); dep->de_flag &= ~DE_MODIFIED; @@ -1232,7 +1235,7 @@ msdosfs_mkdir(v) ndirent.de_pmp = pmp; ndirent.de_flag = DE_ACCESS | DE_CREATE | DE_UPDATE; 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 diff --git a/sys/fs/msdosfs/msdosfsmount.h b/sys/fs/msdosfs/msdosfsmount.h index 6c85223cd9c4..e1c6b57131d9 100644 --- a/sys/fs/msdosfs/msdosfsmount.h +++ b/sys/fs/msdosfs/msdosfsmount.h @@ -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. @@ -56,6 +56,7 @@ struct msdosfs_args { uid_t uid; /* uid that owns msdosfs files */ gid_t gid; /* gid that owns msdosfs files */ mode_t mask; /* mask to be applied for msdosfs perms */ + int gmtoff; /* offset from UTC in seconds */ int flags; /* see below */ /* Following items added after versioning support */ @@ -102,6 +103,7 @@ struct msdosfsmount { for files */ mode_t pm_dirmask; /* mask to and with file protection bits for directories */ + int pm_gmtoff; /* offset from UTC in seconds */ struct vnode *pm_devvp; /* vnode for block device mntd */ struct bpb50 pm_bpb; /* BIOS parameter blk for this fs */ u_long pm_FATsecs; /* actual number of fat sectors */