Line data Source code
1 : #include <stdio.h>
2 : #include <stdlib.h>
3 : #include <libgen.h>
4 : #include <sysexits.h>
5 :
6 : #include <sys/types.h>
7 : #include <sys/stat.h>
8 : #include <fcntl.h>
9 :
10 :
11 : #include <libintl.h>
12 : #define _(String) gettext(String)
13 :
14 : #include <string.h>
15 : #include <errno.h>
16 : #include <unistd.h>
17 : #include "tunegfs2.h"
18 :
19 : static struct tunegfs2 tunegfs2_struct;
20 : static struct tunegfs2 *tfs = &tunegfs2_struct;
21 :
22 0 : static void parse_mount_options(char *arg)
23 : {
24 : struct opt_map *m;
25 : char *s, *c;
26 : int l;
27 : struct opt_map {
28 : const char *tag;
29 : int *flag;
30 : char **val;
31 0 : } map[]= {
32 0 : { "lockproto=", &tfs->opt_proto, &tfs->proto },
33 0 : { "locktable=", &tfs->opt_table, &tfs->table },
34 : { NULL, NULL, NULL }
35 : };
36 :
37 0 : s = arg;
38 0 : for (m = &map[0]; m->tag; m++) {
39 0 : l = strlen(m->tag);
40 0 : if (!strncmp(s, m->tag, l)) {
41 0 : *(m->flag) = 1;
42 0 : *(m->val) = s + l;
43 0 : c = strchr(*(m->val), ',');
44 0 : if (!c)
45 0 : break;
46 0 : *c='\0';
47 0 : s = c+1;
48 : }
49 : }
50 0 : }
51 :
52 1 : static void usage(char *name)
53 : {
54 1 : printf("%s %s [-hlV] [-L <%s>] [-U <%s>] [-o <%s>] [-r <%s>] <%s>\n",
55 : _("Usage:"), basename(name), _("label"), _("UUID"),
56 : _("mount options"), _("version"), _("device"));
57 1 : }
58 :
59 0 : static void version(void)
60 : {
61 0 : printf("tunegfs2 (%s %s)\n", __DATE__, __TIME__);
62 0 : }
63 :
64 : #ifndef UNITTESTS
65 9 : int main(int argc, char **argv)
66 : {
67 : int c, status;
68 9 : int flags = O_RDWR | O_EXCL;
69 :
70 9 : memset(tfs, 0, sizeof(struct tunegfs2));
71 17 : while((c = getopt(argc, argv, "hL:U:lo:Vr:")) != -1) {
72 9 : switch(c) {
73 0 : case 'h':
74 0 : usage(argv[0]);
75 0 : return 0;
76 0 : case 'L':
77 0 : tfs->opt_label = 1;
78 0 : tfs->label = optarg;
79 0 : break;
80 1 : case 'U':
81 1 : tfs->opt_uuid = 1;
82 1 : tfs->uuid = optarg;
83 1 : break;
84 3 : case 'l':
85 3 : tfs->opt_list = 1;
86 3 : flags = O_RDONLY;
87 3 : break;
88 0 : case 'o':
89 0 : parse_mount_options(optarg);
90 0 : break;
91 0 : case 'V':
92 0 : version();
93 0 : return 0;
94 4 : case 'r':
95 4 : tfs->opt_format = 1;
96 4 : tfs->format = optarg;
97 4 : break;
98 1 : default:
99 1 : fprintf(stderr, _("Invalid option: %c\n"), c);
100 1 : usage(argv[0]);
101 1 : return EX_USAGE;
102 : }
103 : }
104 :
105 8 : if ((argc - optind) != 1) {
106 0 : fprintf(stderr, _("Incorrect number of arguments\n"));
107 0 : usage(argv[0]);
108 0 : return EX_USAGE;
109 : }
110 :
111 8 : if (tfs->opt_label && tfs->opt_table) {
112 0 : fprintf(stderr, _("The -L argument cannot be used with the 'locktable' option\n"));
113 0 : usage(argv[0]);
114 0 : return EX_USAGE;
115 : }
116 :
117 8 : tfs->devicename = argv[optind];
118 8 : tfs->fd = open(tfs->devicename, flags);
119 :
120 8 : if (tfs->fd < 0) {
121 0 : fprintf(stderr, _("Unable to open device %s: %s\n"),
122 0 : tfs->devicename, strerror(errno));
123 0 : return EX_IOERR;
124 : }
125 :
126 8 : status = read_super(tfs);
127 8 : if (status)
128 2 : goto out;
129 :
130 6 : if (tfs->opt_uuid) {
131 1 : status = change_uuid(tfs, tfs->uuid);
132 1 : if (status)
133 0 : goto out;
134 : }
135 :
136 6 : if (tfs->opt_proto) {
137 0 : status = change_lockproto(tfs, tfs->proto);
138 0 : if (status)
139 0 : goto out;
140 : }
141 :
142 6 : if (tfs->opt_label) {
143 0 : status = change_locktable(tfs, tfs->label);
144 0 : if (status)
145 0 : goto out;
146 : }
147 :
148 6 : if (tfs->opt_table) {
149 0 : status = change_locktable(tfs, tfs->table);
150 0 : if (status)
151 0 : goto out;
152 : }
153 6 : if (tfs->opt_format) {
154 4 : status = change_format(tfs, tfs->format);
155 4 : if (status)
156 3 : goto out;
157 : }
158 3 : if (tfs->opt_label || tfs->opt_uuid || tfs->opt_table ||
159 2 : tfs->opt_proto || tfs->opt_format) {
160 2 : status = write_super(tfs);
161 2 : if (status)
162 0 : goto out;
163 : }
164 :
165 3 : if (tfs->opt_list)
166 1 : print_super(tfs);
167 :
168 3 : close(tfs->fd);
169 8 : out:
170 8 : return status;
171 : }
172 : #endif /* UNITTESTS */
|