/* * find matching entry in fstab and export it * * Copyright (C) 2008 Kay Sievers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif #include #include #include #include #include #include #include #include #include #include #include "../../udev/udev.h" static int debug; static void log_fn(struct udev *udev, int priority, const char *file, int line, const char *fn, const char *format, va_list args) { if (debug) { fprintf(stderr, "%s: ", fn); vfprintf(stderr, format, args); } else { vsyslog(priority, format, args); } } static int matches_device_list(struct udev *udev, char **devices, const char *name) { int i; for (i = 0; devices[i] != NULL; i++) { info(udev, "compare '%s' == '%s'\n", name, devices[i]); if (strcmp(devices[i], name) == 0) return 1; } return 0; } static void print_fstab_entry(struct udev *udev, struct mntent *mnt) { printf("FSTAB_NAME=%s\n", mnt->mnt_fsname); printf("FSTAB_DIR=%s\n", mnt->mnt_dir); printf("FSTAB_TYPE=%s\n", mnt->mnt_type); printf("FSTAB_OPTS=%s\n", mnt->mnt_opts); printf("FSTAB_FREQ=%d\n", mnt->mnt_freq); printf("FSTAB_PASSNO=%d\n", mnt->mnt_passno); } int main(int argc, char *argv[]) { struct udev *udev; static const struct option options[] = { { "export", no_argument, NULL, 'x' }, { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, {} }; char **devices; FILE *fp; struct mntent *mnt; int rc = 1; udev = udev_new(); if (udev == NULL) goto exit; logging_init("fstab_id"); udev_set_log_fn(udev, log_fn); while (1) { int option; option = getopt_long(argc, argv, "dxh", options, NULL); if (option == -1) break; switch (option) { case 'd': debug = 1; if (udev_get_log_priority(udev) < LOG_INFO) udev_set_log_priority(udev, LOG_INFO); break; case 'h': printf("Usage: fstab_id [OPTIONS] name [...]\n" " --export print environment keys\n" " --debug debug to stderr\n" " --help print this help text\n\n"); goto exit; case 'x': break; default: rc = 2; goto exit; } } devices = &argv[optind]; if (devices[0] == NULL) { fprintf(stderr, "error: missing device(s) to match\n"); rc = 3; goto exit; } fp = setmntent ("/etc/fstab", "r"); if (fp == NULL) { fprintf(stderr, "error: opening fstab: %s\n", strerror(errno)); rc = 4; goto exit; } while (1) { mnt = getmntent(fp); if (mnt == NULL) break; info(udev, "found '%s'@'%s'\n", mnt->mnt_fsname, mnt->mnt_dir); /* skip root device */ if (strcmp(mnt->mnt_dir, "/") == 0) continue; /* match LABEL */ if (strncmp(mnt->mnt_fsname, "LABEL=", 6) == 0) { const char *label; char str[256]; label = &mnt->mnt_fsname[6]; if (label[0] == '"' || label[0] == '\'') { char *pos; util_strlcpy(str, &label[1], sizeof(str)); pos = strrchr(str, label[0]); if (pos == NULL) continue; pos[0] = '\0'; label = str; } if (matches_device_list(udev, devices, str)) { print_fstab_entry(udev, mnt); rc = 0; break; } continue; } /* match UUID */ if (strncmp(mnt->mnt_fsname, "UUID=", 5) == 0) { const char *uuid; char str[256]; uuid = &mnt->mnt_fsname[5]; if (uuid[0] == '"' || uuid[0] == '\'') { char *pos; util_strlcpy(str, &uuid[1], sizeof(str)); pos = strrchr(str, uuid[0]); if (pos == NULL) continue; pos[0] = '\0'; uuid = str; } if (matches_device_list(udev, devices, str)) { print_fstab_entry(udev, mnt); rc = 0; break; } continue; } /* only devices */ if (strncmp(mnt->mnt_fsname, udev_get_dev_path(udev), strlen(udev_get_dev_path(udev))) != 0) continue; if (matches_device_list(udev, devices, &mnt->mnt_fsname[strlen(udev_get_dev_path(udev))+1])) { print_fstab_entry(udev, mnt); rc = 0; break; } } endmntent(fp); exit: udev_unref(udev); logging_close(); return rc; }