~ubuntu-branches/ubuntu/precise/util-linux/precise-proposed

« back to all changes in this revision

Viewing changes to sys-utils/rdev.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2011-06-20 22:31:50 UTC
  • mfrom: (1.6.3 upstream) (4.5.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110620223150-lz8wrv0946ihcz3z
Tags: 2.19.1-2ubuntu1
* Merge from Debian unstable, remaining changes:
  - Build for multiarch.
  - Add pre-depends on multiarch-support.
  - configure.ac: don't try to be clever about extracting a path name from
    $libdir to append to /usr in a way that's not overridable; instead,
    reuse the built-in configurable libexecdir.
  - Fix up the .pc.in files to know about libexecdir, so our substitutions
    don't leave us with unusable pkg-config files.
  - Install custom blkid.conf to use /dev/.blkid.tab since we don't
    expect device names to survive a reboot
  - Mention mountall(8) in fstab(5) manpages, along with its special
    options.
  - Since upstart is required in Ubuntu, the hwclock.sh init script is not
    called on startup and the hwclockfirst.sh init script is removed.
  - Drop depends on initscripts for the above.
  - Replace hwclock udev rule with an Upstart job.
  - For the case where mount is called with a directory to mount, look
    that directory up in mountall's /lib/init/fstab if we couldn't find
    it mentioned anywhere else.  This means "mount /proc", "mount /sys",
    etc. work.
  - mount.8 points to the cifs-utils package, not the obsolete smbfs one. 
* Dropped changes:
  - mount.preinst: lsb_release has been fixed in lucid and above to be
    usable without configuration, so we don't have to diverge from Debian
    here anymore.
* Changes merged upstream:
  - sfdisk support for '+' with '-N'
  - mount/umount.c: fix a segfault on umount with empty mtab entry
  - Fix arbitrary unmount with fuse security issue

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 
3
 
  rdev.c  -  query/set root device.
4
 
 
5
 
-------------------------------------------------------------------------
6
 
 
7
 
Date: Sun, 27 Dec 1992 15:55:31 +0000
8
 
Subject: Re: rdev
9
 
From: almesber@nessie.cs.id.ethz.ch (Werner Almesberger)
10
 
To: Rik Faith <faith@cs.unc.edu>
11
 
 
12
 
There are quite a few versions of rdev:
13
 
 
14
 
  - the original rootdev that only printed the current root device, by
15
 
    Linus.
16
 
  - rdev that does what rootdev did and that also allows you to change
17
 
    the root (and swap) device, by me.
18
 
  - rdev got renamed to setroot and I think even to rootdev on various
19
 
    distributions.
20
 
  - Peter MacDonald added video mode and RAM disk setting and included
21
 
    this version on SLS, called rdev again. I've attached his rdev.c to
22
 
    this mail.
23
 
    
24
 
-------------------------------------------------------------------------
25
 
    
26
 
Date: 11 Mar 92 21:37:37 GMT
27
 
Subject: rdev - query/set root device
28
 
From: almesber@nessie.cs.id.ethz.ch (Werner Almesberger)
29
 
Organization: Swiss Federal Institute of Technology (ETH), Zurich, CH
30
 
 
31
 
With all that socket, X11, disk driver and FS hacking going on, apparently
32
 
nobody has found time to address one of the minor nuisances of life: set-
33
 
ting the root FS device is still somewhat cumbersome. I've written a little
34
 
utility which can read and set the root device in boot images:
35
 
 
36
 
rdev accepts an optional offset argument, just in case the address should
37
 
ever move from 508. If called without arguments, rdev outputs an mtab line
38
 
for the current root FS, just like /etc/rootdev does.
39
 
 
40
 
ramsize sets the size of the ramdisk.  If size is zero, no ramdisk is used.
41
 
 
42
 
vidmode sets the default video mode at bootup time.  -1 uses default video
43
 
mode, -2 uses menu.
44
 
 
45
 
-------------------------------------------------------------------------
46
 
 
47
 
Sun Dec 27 10:42:16 1992: Minor usage changes, faith@cs.unc.edu.
48
 
Tue Mar 30 09:31:52 1993: rdev -Rn to set root readonly flag, sct@dcs.ed.ac.uk
49
 
Wed Jun 22 21:12:29 1994: Applied patches from Dave
50
 
                          (gentzel@nova.enet.dec.com) to prevent dereferencing
51
 
                          the NULL pointer, faith@cs.unc.edu
52
 
1999-02-22 Arkadiusz Mi�kiewicz <misiek@pld.ORG.PL>
53
 
- added Native Language Support
54
 
 
55
 
-------------------------------------------------------------------------
56
 
 
57
 
*/
58
 
 
59
 
#include <stdio.h>
60
 
#include <stdlib.h>
61
 
#include <string.h>
62
 
#include <ctype.h>
63
 
#include <errno.h>
64
 
#include <fcntl.h>
65
 
#include <dirent.h>
66
 
#include <unistd.h>
67
 
#include <sys/types.h>
68
 
#include <sys/stat.h>
69
 
 
70
 
#include "nls.h"
71
 
 
72
 
/* rdev.c  -  query/set root device. */
73
 
 
74
 
static void
75
 
usage(void) {
76
 
 
77
 
    puts(_("usage: rdev [ -rv ] [ -o OFFSET ] [ IMAGE [ VALUE [ OFFSET ] ] ]"));
78
 
    puts(_("  rdev /dev/fd0  (or rdev /linux, etc.) displays the current ROOT device"));
79
 
    puts(_("  rdev /dev/fd0 /dev/hda2         sets ROOT to /dev/hda2"));
80
 
    puts(_("  rdev -R /dev/fd0 1              set the ROOTFLAGS (readonly status)"));
81
 
    puts(_("  rdev -r /dev/fd0 627            set the RAMDISK size"));
82
 
    puts(_("  rdev -v /dev/fd0 1              set the bootup VIDEOMODE"));
83
 
    puts(_("  rdev -o N ...                   use the byte offset N"));
84
 
    puts(_("  rootflags ...                   same as rdev -R"));
85
 
    puts(_("  ramsize ...                     same as rdev -r"));
86
 
    puts(_("  vidmode ...                     same as rdev -v"));
87
 
    puts(_("Note: video modes are: -3=Ask, -2=Extended, -1=NormalVga, 1=key1, 2=key2,..."));
88
 
    puts(_("      use -R 1 to mount root readonly, -R 0 for read/write."));
89
 
    exit(-1);
90
 
}
91
 
 
92
 
 
93
 
#define DEFAULT_OFFSET 508
94
 
 
95
 
 
96
 
static void
97
 
die(char *msg) {
98
 
        perror(msg);
99
 
        exit(1);
100
 
}
101
 
 
102
 
/* Earlier rdev fails on /dev/ida/c0d0p1 so we allow for
103
 
   recursion in /dev. -- Paul Clements */
104
 
/* In fact devfs needs deep recursion. */
105
 
 
106
 
static int
107
 
find_dev_recursive(char *dirnamebuf, int number) {
108
 
        DIR *dp;
109
 
        struct dirent *dir;
110
 
        struct stat s;
111
 
        int dirnamelen = 0;
112
 
 
113
 
        if ((dp = opendir(dirnamebuf)) == NULL)
114
 
                die("opendir");
115
 
        dirnamelen = strlen(dirnamebuf);
116
 
        while ((dir = readdir(dp)) != NULL) {
117
 
                if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."))
118
 
                        continue;
119
 
                if (dirnamelen + 1 + strlen(dir->d_name) > PATH_MAX)
120
 
                        continue;
121
 
                dirnamebuf[dirnamelen] = '/';
122
 
                strcpy(dirnamebuf+dirnamelen+1, dir->d_name);
123
 
                if (lstat(dirnamebuf, &s) < 0)
124
 
                        continue;
125
 
                if ((s.st_mode & S_IFMT) == S_IFBLK && s.st_rdev == number)
126
 
                        return 1;
127
 
                if ((s.st_mode & S_IFMT) == S_IFDIR &&
128
 
                    find_dev_recursive(dirnamebuf, number))
129
 
                        return 1;
130
 
        }
131
 
        dirnamebuf[dirnamelen] = 0;
132
 
        closedir(dp);
133
 
        return 0;
134
 
}
135
 
 
136
 
static char *
137
 
find_dev(int number) {
138
 
        static char name[PATH_MAX+1];
139
 
 
140
 
        if (!number)
141
 
                return "Boot device";
142
 
        strcpy(name, "/dev");
143
 
        if (find_dev_recursive(name, number))
144
 
                return name;
145
 
        sprintf(name, "0x%04x", number);
146
 
        return name;
147
 
}
148
 
 
149
 
/* The enum values are significant, things are stored in this order,
150
 
   see bootsect.S */
151
 
enum { RDEV, VIDMODE, RAMSIZE, __swapdev__, __syssize__, ROOTFLAGS };
152
 
char *cmdnames[6] = { "rdev", "vidmode",  "ramsize", "", 
153
 
                      "", "rootflags"};
154
 
char *desc[6] = { "Root device", "Video mode",  "Ramsize",  "",
155
 
                  "", "Root flags"};
156
 
#define shift(n) argv+=n,argc-=n
157
 
 
158
 
int
159
 
main(int argc, char **argv) {
160
 
        int image, offset, dev_nr, i, newoffset=-1;
161
 
        char *ptr;
162
 
        unsigned short val, have_val;
163
 
        struct stat s;
164
 
        int cmd;
165
 
 
166
 
        setlocale(LC_ALL, "");
167
 
        bindtextdomain(PACKAGE, LOCALEDIR);
168
 
        textdomain(PACKAGE);
169
 
 
170
 
        /* use the command name to figure out what we have to do - ugly */
171
 
        cmd = RDEV;
172
 
        if ((ptr = strrchr(argv[0],'/')) != NULL)
173
 
                ptr++;
174
 
        else
175
 
                ptr = argv[0];
176
 
        for (i=0; i<=5; i++) {
177
 
                if (!strcmp(ptr,cmdnames[i])) {
178
 
                        cmd = i;
179
 
                        break;
180
 
                }
181
 
        }
182
 
 
183
 
        while (argc > 1) { 
184
 
                if (argv[1][0] != '-')
185
 
                        break;
186
 
                switch (argv[1][1]) {
187
 
                case 'R':
188
 
                        cmd = ROOTFLAGS;
189
 
                        shift(1);
190
 
                        break;
191
 
                case 'r': 
192
 
                        cmd = RAMSIZE;
193
 
                        shift(1);
194
 
                        break;
195
 
                case 'v':
196
 
                        cmd = VIDMODE;
197
 
                        shift(1);
198
 
                        break;
199
 
                case 'o':
200
 
                        if (argv[1][2]) {
201
 
                                newoffset = atoi(argv[1]+2);
202
 
                                shift(1);
203
 
                                break;
204
 
                        } else if (argc > 2) {
205
 
                                newoffset = atoi(argv[2]);
206
 
                                shift(2);
207
 
                                break;
208
 
                        }
209
 
                        /* Fall through. . . */
210
 
                default:
211
 
                        usage();
212
 
                }
213
 
        }
214
 
 
215
 
        /* Here the only sensible way of using rdev */
216
 
        if (argc == 1) {
217
 
                if (cmd == RDEV) {
218
 
                        if (stat("/",&s) < 0) die("/");
219
 
                        printf("%s /\n", find_dev(s.st_dev));
220
 
                        exit(0);
221
 
                }
222
 
                usage();
223
 
        }
224
 
 
225
 
        if (argc > 4)
226
 
                usage();
227
 
 
228
 
        /* Ancient garbage.. */
229
 
        offset = DEFAULT_OFFSET-cmd*2;
230
 
        if (newoffset >= 0)
231
 
                offset = newoffset;
232
 
        if (argc == 4)
233
 
                offset = atoi(argv[3]);
234
 
 
235
 
        have_val = 0;
236
 
 
237
 
        if (argc >= 3) {
238
 
                if (cmd == RDEV) {
239
 
                        if (isdigit(*argv[2])) {
240
 
                                /* earlier: specify offset */
241
 
                                /* now: specify major,minor */
242
 
                                char *p;
243
 
                                unsigned int ma,mi;
244
 
                                if ((p = strchr(argv[2], ',')) == NULL)
245
 
                                        die(_("missing comma"));
246
 
                                ma = atoi(argv[2]);
247
 
                                mi = atoi(p+1);
248
 
                                val = ((ma<<8) | mi);
249
 
                        } else {
250
 
                                char *device = argv[2];
251
 
                                if (stat(device,&s) < 0)
252
 
                                        die(device);
253
 
                                val = s.st_rdev;
254
 
                        }
255
 
                } else {
256
 
                        val = atoi(argv[2]);
257
 
                }
258
 
                have_val = 1;
259
 
        }
260
 
 
261
 
        if (have_val) {
262
 
                if ((image = open(argv[1],O_WRONLY)) < 0) die(argv[1]);
263
 
                if (lseek(image,offset,0) < 0) die("lseek");
264
 
                if (write(image,(char *)&val,2) != 2) die(argv[1]);
265
 
                if (close(image) < 0) die("close");
266
 
        } else {
267
 
                if ((image = open(argv[1],O_RDONLY)) < 0) die(argv[1]);
268
 
                if (lseek(image,offset,0) < 0) die("lseek");
269
 
                dev_nr = 0;
270
 
                if (read(image,(char *)&dev_nr,2) != 2) die(argv[1]);
271
 
                if (close(image) < 0) die("close");
272
 
                fputs(desc[cmd], stdout);
273
 
                if (cmd == RDEV)
274
 
                        printf(" %s\n", find_dev(dev_nr));
275
 
                else
276
 
                        printf(" %d\n", dev_nr);
277
 
        }
278
 
        return 0;
279
 
}