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