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