create_floppy_devices.c revision ad29a9f14fa8b1932c0e418bfcf1c10ce6a35a33
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering/*
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * Create all possible floppy device based on the CMOS type.
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * Based upon code from drivers/block/floppy.c
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering *
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * Copyright(C) 2005, SUSE Linux Products GmbH
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering *
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * Author: Hannes Reinecke <hare@suse.de>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering *
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * This program is free software: you can redistribute it and/or modify
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * it under the terms of the GNU General Public License as published by
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * the Free Software Foundation, either version 2 of the License, or
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * (at your option) any later version.
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering *
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * This program is distributed in the hope that it will be useful,
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * but WITHOUT ANY WARRANTY; without even the implied warranty of
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * GNU General Public License for more details.
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering *
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * You should have received a copy of the GNU General Public License
1b00a255225bd65bcc3f6257bd4b1e2089f231b4Tollef Fog Heen * along with this program. If not, see <http://www.gnu.org/licenses/>.
e99e38bbdcca3fe5956823bdb3d38544ccf93221Lennart Poettering */
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <stdio.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <stdlib.h>
e99e38bbdcca3fe5956823bdb3d38544ccf93221Lennart Poettering#include <sys/types.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <sys/stat.h>
1b322bdb2a147e999c3861cba8a6b3ac0f3b712aTollef Fog Heen#include <fcntl.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <unistd.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <string.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <pwd.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <grp.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include "libudev.h"
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include "libudev-private.h"
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poetteringstatic char *table[] = {
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering "", "d360", "h1200", "u360", "u720", "h360", "h720",
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering "u1440", "u2880", "CompaQ", "h1440", "u1680", "h410",
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering "u820", "h1476", "u1722", "h420", "u830", "h1494", "u1743",
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering "h880", "u1040", "u1120", "h1600", "u1760", "u1920",
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering "u3200", "u3520", "u3840", "u1840", "u800", "u1600",
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering NULL
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering};
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poetteringstatic int t360[] = { 1, 0 };
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poetteringstatic int t1200[] = { 2, 5, 6, 10, 12, 14, 16, 18, 20, 23, 0 };
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poetteringstatic int t3in[] = { 8, 9, 26, 27, 28, 7, 11, 15, 19, 24, 25, 29, 31, 3, 4, 13, 17, 21, 22, 30, 0 };
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poetteringstatic int *table_sup[] = { NULL, t360, t1200, t3in+5+8, t3in+5, t3in, t3in };
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poetteringstatic void log_fn(struct udev *udev, int priority,
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering const char *file, int line, const char *fn,
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering const char *format, va_list args)
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering{
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering vsyslog(priority, format, args);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering}
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poetteringint main(int argc, char **argv)
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering{
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering struct udev *udev;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering char *dev;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering char *devname;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering char node[64];
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering int type = 0, i, fdnum, c;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering int major = 2, minor;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering uid_t uid = 0;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering gid_t gid = 0;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering mode_t mode = 0660;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering int create_nodes = 0;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering int print_nodes = 0;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering int is_err = 0;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering udev = udev_new();
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (udev == NULL)
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering goto exit;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering udev_log_init("create_floppy_devices");
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering udev_set_log_fn(udev, log_fn);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering udev_selinux_init(udev);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering while ((c = getopt(argc, argv, "cudm:U:G:M:t:")) != -1) {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering switch (c) {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering case 'c':
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering create_nodes = 1;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering break;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering case 'd':
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering print_nodes = 1;
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering break;
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering case 'U':
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering uid = util_lookup_user(udev, optarg);
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering break;
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering case 'G':
b237ef2cfac7ab0b33170809e8cb64628606207dTollef Fog Heen gid = util_lookup_group(udev, optarg);
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer break;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering case 'M':
e1ce2c2782015579f042d4d6963ed039333fb8c2Lennart Poettering mode = strtol(optarg, NULL, 0);
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering mode = mode & 0666;
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering break;
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering case 'm':
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering major = strtol(optarg, NULL, 0);
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering break;
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering case 't':
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering type = strtol(optarg, NULL, 0);
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering break;
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering default:
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering is_err++;
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering break;
53f7d807bff9c39e9e565ad2fb20f29b4306af40Lennart Poettering }
53f7d807bff9c39e9e565ad2fb20f29b4306af40Lennart Poettering }
53f7d807bff9c39e9e565ad2fb20f29b4306af40Lennart Poettering
53f7d807bff9c39e9e565ad2fb20f29b4306af40Lennart Poettering if (is_err || optind >= argc) {
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer printf("Usage: %s [OPTION] device\n"
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer " -c create\n"
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer " -d debug\n"
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer " -m Major number\n"
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer " -t floppy type number\n"
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer " -U device node user ownership\n"
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer " -G device node group owner\n"
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer " -M device node mode\n"
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer "\n", argv[0]);
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer return 1;
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer }
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer dev = argv[optind];
e12891f70c264683f4f2b99dd6c535c73f1d26a5Robert Gerus devname = strrchr(dev, '/');
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering if (devname != NULL)
42e39f0b326d27f6392a81a7400f9af7cf0af3abLennart Poettering devname = &devname[1];
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering else
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering devname = dev;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (strncmp(devname, "fd", 2) != 0) {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering fprintf(stderr,"Device '%s' is not a floppy device\n", dev);
5e6afdd3d359fc42de7ac432243e98673577e81fLennart Poettering return 1;
5e6afdd3d359fc42de7ac432243e98673577e81fLennart Poettering }
9f2c5942e1e10099027f0da438aafdd9f40440baLennart Poettering
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering fdnum = strtol(&devname[2], NULL, 10);
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering if (fdnum < 0 || fdnum > 7) {
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering fprintf(stderr,"Floppy device number %d out of range (0-7)\n", fdnum);
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering return 1;
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering }
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering if (fdnum > 3)
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering fdnum += 124;
d7c114c00030309435fc56c77c8578a25d228ebeDave Reisner
f2b4af1cd4112df6ce56f8fc1e677639935e3d0eFabian Henze if (major < 1) {
65c8976ab12f13fc339a16d108e620bf2fd703f4Malcolm Studd fprintf(stderr,"Invalid major number %d\n", major);
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering return 1;
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering }
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering if (type < 0 || type >= (int) ARRAY_SIZE(table_sup)) {
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering fprintf(stderr,"Invalid CMOS type %d\n", type);
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering return 1;
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering }
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering if (type == 0)
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering return 0;
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering i = 0;
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering while (table_sup[type][i]) {
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering sprintf(node, "%s%s", dev, table[table_sup[type][i]]);
12e84679cc81cdf5f042540e54131a0ce37147adLennart Poettering minor = (table_sup[type][i] << 2) + fdnum;
12e84679cc81cdf5f042540e54131a0ce37147adLennart Poettering if (print_nodes)
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering printf("%s b %.4o %d %d\n", node, mode, major, minor);
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering if (create_nodes) {
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering unlink(node);
0571e0111d76cf96aa4069d9c7a6e24d97aa7e48Lennart Poettering udev_selinux_setfscreatecon(udev, node, S_IFBLK | mode);
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering mknod(node, S_IFBLK | mode, makedev(major,minor));
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering udev_selinux_resetfscreatecon(udev);
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering chown(node, uid, gid);
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering chmod(node, S_IFBLK | mode);
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering }
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering i++;
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering }
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering udev_selinux_exit(udev);
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering udev_unref(udev);
34eff652cedec3cac34b92629ead5f140334b689Lennart Poettering udev_log_close();
a7b6f8e578724c3b4f0cfc8777d9b4a8e29207b0Lennart Poetteringexit:
a7b6f8e578724c3b4f0cfc8777d9b4a8e29207b0Lennart Poettering return 0;
2c696a96a2bd63d2ff0d5595622124ef9270b172Lennart Poettering}
12e84679cc81cdf5f042540e54131a0ce37147adLennart Poettering