chiark / gitweb /
e793604faa2e2e9019c340d2df157c4df8b384b5
[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 "../../udev/udev.h"
28
29 static int debug;
30
31 static void log_fn(struct udev *udev, int priority,
32                    const char *file, int line, const char *fn,
33                    const char *format, va_list args)
34 {
35         if (debug) {
36                 fprintf(stderr, "%s: ", fn);
37                 vfprintf(stderr, format, args);
38         } else {
39                 vsyslog(priority, format, args);
40         }
41 }
42
43 static int matches_device_list(struct udev *udev, char **devices, const char *name)
44 {
45         int i;
46
47         for (i = 0; devices[i] != NULL; i++) {
48                 info(udev, "compare '%s' == '%s'\n", name, devices[i]);
49                 if (strcmp(devices[i], name) == 0)
50                         return 1;
51         }
52         return 0;
53 }
54
55 static void print_fstab_entry(struct udev *udev, struct mntent *mnt)
56 {
57         printf("FSTAB_NAME=%s\n", mnt->mnt_fsname);
58         printf("FSTAB_DIR=%s\n", mnt->mnt_dir);
59         printf("FSTAB_TYPE=%s\n", mnt->mnt_type);
60         printf("FSTAB_OPTS=%s\n", mnt->mnt_opts);
61         printf("FSTAB_FREQ=%d\n", mnt->mnt_freq);
62         printf("FSTAB_PASSNO=%d\n", mnt->mnt_passno);
63 }
64
65 int main(int argc, char *argv[])
66 {
67         struct udev *udev;
68         static const struct option options[] = {
69                 { "export", no_argument, NULL, 'x' },
70                 { "debug", no_argument, NULL, 'd' },
71                 { "help", no_argument, NULL, 'h' },
72                 {}
73         };
74         char **devices;
75         FILE *fp;
76         struct mntent *mnt;
77         int rc = 1;
78
79         udev = udev_new();
80         if (udev == NULL)
81                 goto exit;
82
83         logging_init("fstab_id");
84         udev_set_log_fn(udev, log_fn);
85
86         while (1) {
87                 int option;
88
89                 option = getopt_long(argc, argv, "dxh", options, NULL);
90                 if (option == -1)
91                         break;
92
93                 switch (option) {
94                 case 'd':
95                         debug = 1;
96                         if (udev_get_log_priority(udev) < LOG_INFO)
97                                 udev_set_log_priority(udev, LOG_INFO);
98                         break;
99                 case 'h':
100                         printf("Usage: fstab_id [OPTIONS] name [...]\n"
101                                "  --export        print environment keys\n"
102                                "  --debug         debug to stderr\n"
103                                "  --help          print this help text\n\n");
104                         goto exit;
105                 case 'x':
106                         break;
107                 default:
108                         rc = 2;
109                         goto exit;
110                 }
111         }
112
113         devices = &argv[optind];
114         if (devices[0] == NULL) {
115                 fprintf(stderr, "error: missing device(s) to match\n");
116                 rc = 3;
117                 goto exit;
118         }
119
120         fp = setmntent ("/etc/fstab", "r");
121         if (fp == NULL) {
122                 fprintf(stderr, "error: opening fstab: %s\n", strerror(errno));
123                 rc = 4;
124                 goto exit;
125         }
126
127         while (1) {
128                 mnt = getmntent(fp);
129                 if (mnt == NULL)
130                         break;
131
132                 info(udev, "found '%s'@'%s'\n", mnt->mnt_fsname, mnt->mnt_dir);
133
134                 /* skip root device */
135                 if (strcmp(mnt->mnt_dir, "/") == 0)
136                         continue;
137
138                 /* match LABEL */
139                 if (strncmp(mnt->mnt_fsname, "LABEL=", 6) == 0) {
140                         const char *label;
141                         char str[256];
142
143                         label = &mnt->mnt_fsname[6];
144                         if (label[0] == '"' || label[0] == '\'') {
145                                 char *pos;
146
147                                 util_strlcpy(str, &label[1], sizeof(str));
148                                 pos = strrchr(str, label[0]);
149                                 if (pos == NULL)
150                                         continue;
151                                 pos[0] = '\0';
152                                 label = str;
153                         }
154                         if (matches_device_list(udev, devices, str)) {
155                                 print_fstab_entry(udev, mnt);
156                                 rc = 0;
157                                 break;
158                         }
159                         continue;
160                 }
161
162                 /* match UUID */
163                 if (strncmp(mnt->mnt_fsname, "UUID=", 5) == 0) {
164                         const char *uuid;
165                         char str[256];
166
167                         uuid = &mnt->mnt_fsname[5];
168                         if (uuid[0] == '"' || uuid[0] == '\'') {
169                                 char *pos;
170
171                                 util_strlcpy(str, &uuid[1], sizeof(str));
172                                 pos = strrchr(str, uuid[0]);
173                                 if (pos == NULL)
174                                         continue;
175                                 pos[0] = '\0';
176                                 uuid = str;
177                         }
178                         if (matches_device_list(udev, devices, str)) {
179                                 print_fstab_entry(udev, mnt);
180                                 rc = 0;
181                                 break;
182                         }
183                         continue;
184                 }
185
186                 /* only devices */
187                 if (strncmp(mnt->mnt_fsname, udev_get_dev_path(udev), strlen(udev_get_dev_path(udev))) != 0)
188                         continue;
189
190                 if (matches_device_list(udev, devices, &mnt->mnt_fsname[strlen(udev_get_dev_path(udev))+1])) {
191                         print_fstab_entry(udev, mnt);
192                         rc = 0;
193                         break;
194                 }
195         }
196         endmntent(fp);
197
198 exit:
199         udev_unref(udev);
200         logging_close();
201         return rc;
202 }