* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
#ifndef lint
static const char rcsid[] =
- "$Id: optr.c,v 1.30 2002/01/25 15:08:59 stelian Exp $";
+ "$Id: optr.c,v 1.40 2006/03/14 11:09:51 stelian Exp $";
#endif /* not lint */
#include <config.h>
#include <time.h>
#include <errno.h>
-#include <fstab.h>
+#include <mntent.h>
+#include <paths.h>
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
* sleep for 2 minutes in case nobody comes to satisfy dump
*/
static void
-alarmcatch(int signo)
+alarmcatch(UNUSED(int signo))
{
int save_errno = errno;
if (notify == 0) {
* Here if an inquisitive operator interrupts the dump program
*/
void
-interrupt(int signo)
+interrupt(UNUSED(int signo))
{
msg("Interrupt received.\n");
if (query("Do you want to abort dump?"))
* we don't actually do it
*/
-static struct fstab *
-allocfsent(struct fstab *fs)
+struct pfstab {
+ struct pfstab *pf_next;
+ struct dumpdates *pf_dd;
+ struct mntent *pf_mntent;
+};
+
+static struct pfstab *table;
+
+static struct mntent *
+allocfsent(struct mntent *fs)
{
- struct fstab *new;
+ struct mntent *new;
+ const char *disk;
+ struct stat buf, tabbuf;
+ struct pfstab *tabpf;
+ struct mntent *tabfs;
- new = (struct fstab *)malloc(sizeof (*fs));
+ new = (struct mntent *)malloc(sizeof (*fs));
if (new == NULL)
quit("%s\n", strerror(errno));
- if (strlen(fs->fs_file) > 1 && fs->fs_file[strlen(fs->fs_file) - 1] == '/')
- fs->fs_file[strlen(fs->fs_file) - 1] = '\0';
- if ((new->fs_file = strdup(fs->fs_file)) == NULL ||
- (new->fs_type = strdup(fs->fs_type)) == NULL ||
- (new->fs_vfstype = strdup(fs->fs_vfstype)) == NULL ||
- (new->fs_spec = strdup(fs->fs_spec)) == NULL)
+
+ /* Translade UUID=, LABEL= ... */
+ disk = get_device_name(fs->mnt_fsname);
+ if (disk == NULL)
+ disk = strdup(fs->mnt_fsname);
+
+ /* Discard non block devices */
+ if (stat(disk, &buf) != 0 || !S_ISBLK(buf.st_mode)) {
+ free(new);
+ return NULL;
+ }
+
+ /* Discard same major/minor devices */
+ for (tabpf = table; tabpf != NULL; tabpf = tabpf->pf_next) {
+ tabfs = tabpf->pf_mntent;
+ if (stat(tabfs->mnt_fsname, &tabbuf) != 0)
+ /* should not happen */
+ quit("Cannot access %s\n", tabfs->mnt_fsname);
+ if (tabbuf.st_rdev == buf.st_rdev) {
+ free(new);
+ /* Copy passno and freq from /etc/fstab because
+ * /etc/mtab does always have them as 0 0 */
+ if (!tabfs->mnt_passno)
+ tabfs->mnt_passno = fs->mnt_passno;
+ if (!tabfs->mnt_freq)
+ tabfs->mnt_freq = fs->mnt_freq;
+ if (tabfs->mnt_freq > 3659)
+ quit("Dump frequency in fstab/mtab for %s is too big: %d > 3659\n",
+ tabfs->mnt_fsname, tabfs->mnt_freq);
+ return NULL;
+ }
+ }
+
+ if (strlen(fs->mnt_dir) > 1 && fs->mnt_dir[strlen(fs->mnt_dir) - 1] == '/')
+ fs->mnt_dir[strlen(fs->mnt_dir) - 1] = '\0';
+ if ((new->mnt_dir = strdup(fs->mnt_dir)) == NULL ||
+ (new->mnt_type = strdup(fs->mnt_type)) == NULL ||
+ (new->mnt_opts = strdup(fs->mnt_opts)) == NULL ||
+ (new->mnt_fsname = strdup(disk)) == NULL)
quit("%s\n", strerror(errno));
- new->fs_passno = fs->fs_passno;
- new->fs_freq = fs->fs_freq;
+ new->mnt_passno = fs->mnt_passno;
+ new->mnt_freq = fs->mnt_freq;
+ if (new->mnt_freq > 3659)
+ quit("Dump frequency in fstab/mtab for %s %s is too big: %d > 3659\n",
+ new->mnt_dir, new->mnt_fsname, new->mnt_freq);
return (new);
}
-struct pfstab {
- struct pfstab *pf_next;
- struct dumpdates *pf_dd;
- struct fstab *pf_fstab;
-};
-
-static struct pfstab *table;
-
void
getfstab(void)
{
- struct fstab *fs;
+ struct mntent *fs;
struct pfstab *pf;
struct pfstab *pfold = NULL;
-
- if (setfsent() == 0) {
- msg("Can't open %s for dump table information: %s\n",
- _PATH_FSTAB, strerror(errno));
- return;
- }
- while ((fs = getfsent()) != NULL) {
- if (strcmp(fs->fs_type, FSTAB_RW) &&
- strcmp(fs->fs_type, FSTAB_RO) &&
- strcmp(fs->fs_type, FSTAB_RQ))
+ FILE *mntfp;
+ char *mnttables[] = { _PATH_MOUNTED, _PATH_MNTTAB, 0 };
+ int i;
+
+ for (i = 0; mnttables[i]; i++) {
+ mntfp = setmntent(mnttables[i], "r");
+ if (mntfp == NULL) {
+ msg("Can't open %s for dump table information: %s\n",
+ mnttables[i], strerror(errno));
continue;
- fs = allocfsent(fs);
- if ((pf = (struct pfstab *)malloc(sizeof (*pf))) == NULL)
- quit("%s\n", strerror(errno));
- pf->pf_fstab = fs;
- pf->pf_next = NULL;
-
- /* keep table in /etc/fstab order for use with -w and -W */
- if (pfold) {
- pfold->pf_next = pf;
- pfold = pf;
- } else
- pfold = table = pf;
-
+ }
+ while ((fs = getmntent(mntfp)) != NULL) {
+ fs = allocfsent(fs);
+ if (!fs)
+ continue;
+ fs->mnt_passno = 0;
+ if ((pf = (struct pfstab *)malloc(sizeof (*pf))) == NULL)
+ quit("%s\n", strerror(errno));
+ pf->pf_mntent = fs;
+ pf->pf_next = NULL;
+
+ /* keep table in /etc/fstab order for use with -w and -W */
+ if (pfold) {
+ pfold->pf_next = pf;
+ pfold = pf;
+ } else
+ pfold = table = pf;
+ }
+ (void) endmntent(mntfp);
}
- (void) endfsent();
}
/*
*
* The file name can omit the leading '/'.
*/
-struct fstab *
+struct mntent *
fstabsearch(const char *key)
{
struct pfstab *pf;
- struct fstab *fs;
+ struct mntent *fs;
const char *rn;
for (pf = table; pf != NULL; pf = pf->pf_next) {
- fs = pf->pf_fstab;
- if (strcmp(fs->fs_file, key) == 0 ||
- strcmp(fs->fs_spec, key) == 0)
+ fs = pf->pf_mntent;
+ if (strcmp(fs->mnt_dir, key) == 0 ||
+ strcmp(fs->mnt_fsname, key) == 0)
return (fs);
- rn = rawname(fs->fs_spec);
+ rn = rawname(fs->mnt_fsname);
if (rn != NULL && strcmp(rn, key) == 0)
return (fs);
if (key[0] != '/') {
- if (*fs->fs_spec == '/' &&
- strcmp(fs->fs_spec + 1, key) == 0)
+ if (*fs->mnt_fsname == '/' &&
+ strcmp(fs->mnt_fsname + 1, key) == 0)
return (fs);
- if (*fs->fs_file == '/' &&
- strcmp(fs->fs_file + 1, key) == 0)
+ if (*fs->mnt_dir == '/' &&
+ strcmp(fs->mnt_dir + 1, key) == 0)
return (fs);
}
}
}
#ifdef __linux__
-struct fstab *
+struct mntent *
fstabsearchdir(const char *key, char *directory)
{
struct pfstab *pf;
- struct fstab *fs;
- struct fstab *found_fs = NULL;
+ struct mntent *fs;
+ struct mntent *found_fs = NULL;
unsigned int size = 0;
struct stat buf;
return NULL;
for (pf = table; pf != NULL; pf = pf->pf_next) {
- fs = pf->pf_fstab;
- if (strlen(fs->fs_file) > size &&
- strlen(key) > strlen(fs->fs_file) &&
- strncmp(fs->fs_file, key, strlen(fs->fs_file)) == 0 &&
- (key[strlen(fs->fs_file)] == '/' ||
- fs->fs_file[strlen(fs->fs_file) - 1] == '/')) {
+ fs = pf->pf_mntent;
+ if (strlen(fs->mnt_dir) > size &&
+ strlen(key) > strlen(fs->mnt_dir) &&
+ strncmp(fs->mnt_dir, key, strlen(fs->mnt_dir)) == 0 &&
+ (key[strlen(fs->mnt_dir)] == '/' ||
+ fs->mnt_dir[strlen(fs->mnt_dir) - 1] == '/')) {
found_fs = fs;
- size = strlen(fs->fs_file);
+ size = strlen(fs->mnt_dir);
}
}
if (found_fs != NULL) {
* Check ddate > 365 to avoid issues with fs in stab but not dumpdates.
* Not a problem, because ddate is in seconds since the epoch anyways.
*/
- if (ddate > 365) {
+ if (level >= 0 && ddate > 365) {
char *date, *d;
date = (char *)ctime(&ddate);
d = strchr(date, '\n');
if (d) *d = '\0';
- printf("Level %c, Date %s\n", level, date);
+ printf("Level %d, Date %s\n", level, date);
} else
printf("never\n");
}
initdumptimes(0); /* dumpdates input */
if (ddatev == NULL && table == NULL) {
(void) printf("No %s or %s file found\n",
- _PATH_FSTAB, _PATH_DUMPDATES);
+ _PATH_MNTTAB, dumpdates);
return;
}
lastname = "??";
ITITERATE(i, dtwalk) {
- struct fstab *dt;
+ struct mntent *dt;
if (strncmp(lastname, dtwalk->dd_name,
sizeof(dtwalk->dd_name)) == 0)
continue;
* change struct fstab format.
* A positive fs_freq means this
* filesystem needs to be dumped.
+ *
+ * UGLY HACK: values in 0-3659 range indicate
+ * original value from /etc/fstab (maximum
+ * 10 years...)
+ *
+ * Values bigger than 3659 indicate that
+ * the fs is to be dumped, and the latest
+ * dump level was x-3660
+ *
+ * Negative values indicate that the fs is
+ * not to be dumped, and the latest dump
+ * level was -x-1
*/
- dt->fs_passno = dtwalk->dd_ddate;
- if (dt->fs_freq > 0 && (dtwalk->dd_ddate <
- tnow - (dt->fs_freq * 86400)))
- dt->fs_freq = dtwalk->dd_level;
+ dt->mnt_passno = dtwalk->dd_ddate;
+ if (dt->mnt_freq > 0 && (dtwalk->dd_ddate <
+ tnow - (dt->mnt_freq * 86400)))
+ dt->mnt_freq = 3660 + dtwalk->dd_level;
else
- dt->fs_freq = -dtwalk->dd_level;
+ dt->mnt_freq = -dtwalk->dd_level - 1;
#ifdef FDEBUG
printf("%s fs_freq set to %d\n", lastname,
- dt->fs_freq);
+ dt->mnt_freq);
#endif
}
}
/* print in /etc/fstab order only those filesystem types we can dump */
for (pf = table; pf != NULL; pf = pf->pf_next) {
- struct fstab *dt = pf->pf_fstab;
+ struct mntent *dt = pf->pf_mntent;
char **type;
for (type = fstypes; *type != NULL; type++) {
- if (strncmp(dt->fs_vfstype, *type,
- sizeof(dt->fs_vfstype)) == 0) {
- const char *disk = get_device_name(dt->fs_spec);
- print_wmsg(arg, dt->fs_freq > 0,
- disk ? disk : dt->fs_spec,
- dt->fs_freq < 0 ? -dt->fs_freq :
- dt->fs_freq,
- dt->fs_file,
- dt->fs_passno);
+ if (strncmp(dt->mnt_type, *type,
+ sizeof(dt->mnt_type)) == 0) {
+ const char *disk = get_device_name(dt->mnt_fsname);
+ print_wmsg(arg, dt->mnt_freq > 0,
+ disk ? disk : dt->mnt_fsname,
+ (dt->mnt_freq < 0 ? -dt->mnt_freq - 1 :
+ dt->mnt_freq < 3660 ? -1 :
+ dt->mnt_freq - 3660),
+ dt->mnt_dir,
+ dt->mnt_passno);
}
}
}