]> git.ipfire.org Git - thirdparty/util-linux.git/blame - disk-utils/raw.c
Imported from util-linux-2.10s tarball.
[thirdparty/util-linux.git] / disk-utils / raw.c
CommitLineData
eb63b9b8
KZ
1/*
2 * raw.c: User mode tool to bind and query raw character devices.
3 *
22853e4a 4 * Stephen Tweedie, 1999, 2000
eb63b9b8
KZ
5 *
6 * This file may be redistributed under the terms of the GNU General
7 * Public License, version 2.
8 *
22853e4a 9 * Copyright Red Hat Software, 1999, 2000
eb63b9b8
KZ
10 *
11 */
12
13#include <stdlib.h>
14#include <stdio.h>
15#include <unistd.h>
16#include <errno.h>
17#include <string.h>
18#include <sys/fcntl.h>
19#include <sys/stat.h>
20#include <sys/ioctl.h>
21#include <sys/sysmacros.h>
22853e4a
KZ
22#include <linux/raw.h>
23#include <linux/major.h>
eb63b9b8 24
22853e4a
KZ
25#ifdef OLD_RAW_DEVS
26#define RAWCTLDEV "/dev/raw"
27#define RAWDEVDIR "/dev/"
28#else
29#define RAWCTLDEV "/dev/rawctl"
30#define RAWDEVDIR "/dev/raw/"
31#endif
eb63b9b8
KZ
32
33
34char * progname;
35int do_query = 0;
36int do_query_all = 0;
37
38int master_fd;
39int raw_minor;
40
41void open_raw_ctl(void);
42int query(int minor, int quiet);
43int bind (int minor, int block_major, int block_minor);
44
45
46static void usage(int err)
47{
48 fprintf(stderr,
49 "Usage:\n"
22853e4a
KZ
50 " %s " RAWDEVDIR "rawN <major> <minor>\n"
51 " %s " RAWDEVDIR "rawN /dev/<blockdev>\n"
52 " %s -q " RAWDEVDIR "rawN\n"
eb63b9b8
KZ
53 " %s -qa\n",
54 progname, progname, progname, progname);
55 exit(err);
56}
57
58
59int main(int argc, char *argv[])
60{
61 char c;
62 char * raw_name;
63 char * block_name;
64 int err;
65 int block_major, block_minor;
66 int i;
67
68 struct stat statbuf;
69
70 progname = argv[0];
71
72 while ((c = getopt(argc, argv, "ahq")) != EOF) {
73 switch (c) {
74 case 'a':
75 do_query_all = 1;
76 break;
77 case 'h':
78 usage(0);
79 case 'q':
80 do_query = 1;
81 break;
82 default:
83 usage(1);
84 }
85 }
86
87 /*
88 * Check for, and open, the master raw device, /dev/raw
89 */
90
91 open_raw_ctl();
92
93 if (do_query_all) {
94 if (optind < argc)
95 usage(1);
96 for (i=1; i<255; i++)
97 query(i, 1);
98 exit(0);
99 }
100
101 /*
102 * It's a bind or a single query. Either way we need a raw device.
103 */
104
105 if (optind >= argc)
106 usage(1);
107 raw_name = argv[optind++];
108
109 err = stat(raw_name, &statbuf);
110 if (err) {
111 fprintf (stderr, "Cannot locate raw device '%s' (%s)\n",
112 raw_name, strerror(errno));
113 exit(2);
114 }
115
116 if (!S_ISCHR(statbuf.st_mode)) {
117 fprintf (stderr, "raw device '%s' is not a character dev\n",
118 raw_name);
119 exit(2);
120 }
121 if (major(statbuf.st_rdev) != RAW_MAJOR) {
122 fprintf (stderr, "Device '%s' is not a raw dev\n",
123 raw_name);
124 exit(2);
125 }
126
127 raw_minor = minor(statbuf.st_rdev);
128
129 if (do_query)
130 return query(raw_minor, 0);
131
132 /*
133 * It's not a query, so we still have some parsing to do. Have
134 * we been given a block device filename or a major/minor pair?
135 */
136
137 switch (argc - optind) {
138 case 1:
139 block_name = argv[optind];
140 err = stat(block_name, &statbuf);
141 if (err) {
142 fprintf (stderr,
143 "Cannot locate block device '%s' (%s)\n",
144 block_name, strerror(errno));
145 exit(2);
146 }
147
148 if (!S_ISBLK(statbuf.st_mode)) {
149 fprintf (stderr, "Device '%s' is not a block dev\n",
150 block_name);
151 exit(2);
152 }
153
154 block_major = major(statbuf.st_rdev);
155 block_minor = minor(statbuf.st_rdev);
156 break;
157
158 case 2:
159 block_major = strtol(argv[optind], 0, 0);
160 block_minor = strtol(argv[optind+1], 0, 0);
161 break;
162
163 default:
66ee8158 164 block_major = block_minor = 0; /* just to keep gcc happy */
eb63b9b8
KZ
165 usage(1);
166 }
167
168 return bind(raw_minor, block_major, block_minor);
169 return 0;
170
171}
172
173
174void open_raw_ctl(void)
175{
22853e4a 176 master_fd = open(RAWCTLDEV, O_RDWR, 0);
eb63b9b8
KZ
177 if (master_fd < 0) {
178 fprintf (stderr,
22853e4a 179 "Cannot open master raw device '" RAWCTLDEV "' (%s)\n",
eb63b9b8
KZ
180 strerror(errno));
181 exit(2);
182 }
183}
184
185int query(int minor, int quiet)
186{
187 struct raw_config_request rq;
188 int err;
189
190 rq.raw_minor = minor;
191 err = ioctl(master_fd, RAW_GETBIND, &rq);
192 if (err < 0) {
193 if (quiet && errno == ENODEV)
194 return 3;
195 fprintf (stderr,
196 "Error querying raw device (%s)\n",
197 strerror(errno));
198 exit(3);
199 }
200 if (quiet && !rq.block_major && !rq.block_minor)
201 return 0;
22853e4a 202 printf (RAWDEVDIR "raw%d: bound to major %d, minor %d\n",
eb63b9b8
KZ
203 minor, (int) rq.block_major, (int) rq.block_minor);
204 return 0;
205}
206
207int bind(int minor, int block_major, int block_minor)
208{
209 struct raw_config_request rq;
210 int err;
211
212 rq.raw_minor = minor;
213 rq.block_major = block_major;
214 rq.block_minor = block_minor;
215 err = ioctl(master_fd, RAW_SETBIND, &rq);
216 if (err < 0) {
217 fprintf (stderr,
218 "Error setting raw device (%s)\n",
219 strerror(errno));
220 exit(3);
221 }
22853e4a 222 printf (RAWDEVDIR "raw%d: bound to major %d, minor %d\n",
eb63b9b8
KZ
223 raw_minor, (int) rq.block_major, (int) rq.block_minor);
224 return 0;
225}
226