chiark / gitweb /
Merge libudev, udev, and the unconditional extras in a single Makefile.am.
[elogind.git] / extras / fstab_import / fstab_import.c
1 /*
2  * find matching entry in fstab and export it
3  *
4  * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  */
11
12 #ifndef _GNU_SOURCE
13 #define _GNU_SOURCE 1
14 #endif
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <fcntl.h>
20 #include <ctype.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <getopt.h>
24 #include <mntent.h>
25 #include <sys/stat.h>
26
27 #include "libudev.h"
28 #include "libudev-private.h"
29
30 static int debug;
31
32 static void log_fn(struct udev *udev, int priority,
33                    const char *file, int line, const char *fn,
34                    const char *format, va_list args)
35 {
36         if (debug) {
37                 fprintf(stderr, "%s: ", fn);
38                 vfprintf(stderr, format, args);
39         } else {
40                 vsyslog(priority, format, args);
41         }
42 }
43
44 static int matches_device_list(struct udev *udev, char **devices, const char *name)
45 {
46         int i;
47
48         for (i = 0; devices[i] != NULL; i++) {
49                 info(udev, "compare '%s' == '%s'\n", name, devices[i]);
50                 if (strcmp(devices[i], name) == 0)
51                         return 1;
52         }
53         return 0;
54 }
55
56 static void print_fstab_entry(struct udev *udev, struct mntent *mnt)
57 {
58         printf("FSTAB_NAME=%s\n", mnt->mnt_fsname);
59         printf("FSTAB_DIR=%s\n", mnt->mnt_dir);
60         printf("FSTAB_TYPE=%s\n", mnt->mnt_type);
61         printf("FSTAB_OPTS=%s\n", mnt->mnt_opts);
62         printf("FSTAB_FREQ=%d\n", mnt->mnt_freq);
63         printf("FSTAB_PASSNO=%d\n", mnt->mnt_passno);
64 }
65
66 int main(int argc, char *argv[])
67 {
68         struct udev *udev;
69         static const struct option options[] = {
70                 { "export", no_argument, NULL, 'x' },
71                 { "debug", no_argument, NULL, 'd' },
72                 { "help", no_argument, NULL, 'h' },
73                 {}
74         };
75         char **devices;
76         FILE *fp;
77         struct mntent *mnt;
78         int rc = 1;
79
80         udev = udev_new();
81         if (udev == NULL)
82                 goto exit;
83
84         udev_log_init("fstab_id");
85         udev_set_log_fn(udev, log_fn);
86
87         while (1) {
88                 int option;
89
90                 option = getopt_long(argc, argv, "dxh", options, NULL);
91                 if (option == -1)
92                         break;
93
94                 switch (option) {
95                 case 'd':
96                         debug = 1;
97                         if (udev_get_log_priority(udev) < LOG_INFO)
98                                 udev_set_log_priority(udev, LOG_INFO);
99                         break;
100                 case 'h':
101                         printf("Usage: fstab_id [OPTIONS] name [...]\n"
102                                "  --export        print environment keys\n"
103                                "  --debug         debug to stderr\n"
104                                "  --help          print this help text\n\n");
105                         goto exit;
106                 case 'x':
107                         break;
108                 default:
109                         rc = 2;
110                         goto exit;
111                 }
112         }
113
114         devices = &argv[optind];
115         if (devices[0] == NULL) {
116                 fprintf(stderr, "error: missing device(s) to match\n");
117                 rc = 3;
118                 goto exit;
119         }
120
121         fp = setmntent ("/etc/fstab", "r");
122         if (fp == NULL) {
123                 fprintf(stderr, "error: opening fstab: %s\n", strerror(errno));
124                 rc = 4;
125                 goto exit;
126         }
127
128         while (1) {
129                 mnt = getmntent(fp);
130                 if (mnt == NULL)
131                         break;
132
133                 info(udev, "found '%s'@'%s'\n", mnt->mnt_fsname, mnt->mnt_dir);
134
135                 /* skip root device */
136                 if (strcmp(mnt->mnt_dir, "/") == 0)
137                         continue;
138
139                 /* match LABEL */
140                 if (strncmp(mnt->mnt_fsname, "LABEL=", 6) == 0) {
141                         const char *label;
142                         char str[256];
143
144                         label = &mnt->mnt_fsname[6];
145                         if (label[0] == '"' || label[0] == '\'') {
146                                 char *pos;
147
148                                 util_strscpy(str, sizeof(str), &label[1]);
149                                 pos = strrchr(str, label[0]);
150                                 if (pos == NULL)
151                                         continue;
152                                 pos[0] = '\0';
153                                 label = str;
154                         }
155                         if (matches_device_list(udev, devices, str)) {
156                                 print_fstab_entry(udev, mnt);
157                                 rc = 0;
158                                 break;
159                         }
160                         continue;
161                 }
162
163                 /* match UUID */
164                 if (strncmp(mnt->mnt_fsname, "UUID=", 5) == 0) {
165                         const char *uuid;
166                         char str[256];
167
168                         uuid = &mnt->mnt_fsname[5];
169                         if (uuid[0] == '"' || uuid[0] == '\'') {
170                                 char *pos;
171
172                                 util_strscpy(str, sizeof(str), &uuid[1]);
173                                 pos = strrchr(str, uuid[0]);
174                                 if (pos == NULL)
175                                         continue;
176                                 pos[0] = '\0';
177                                 uuid = str;
178                         }
179                         if (matches_device_list(udev, devices, str)) {
180                                 print_fstab_entry(udev, mnt);
181                                 rc = 0;
182                                 break;
183                         }
184                         continue;
185                 }
186
187                 /* only devices */
188                 if (strncmp(mnt->mnt_fsname, udev_get_dev_path(udev), strlen(udev_get_dev_path(udev))) != 0)
189                         continue;
190
191                 if (matches_device_list(udev, devices, &mnt->mnt_fsname[strlen(udev_get_dev_path(udev))+1])) {
192                         print_fstab_entry(udev, mnt);
193                         rc = 0;
194                         break;
195                 }
196         }
197         endmntent(fp);
198
199 exit:
200         udev_unref(udev);
201         udev_log_close();
202         return rc;
203 }