chiark / gitweb /
rename udev_volume_id to vol_id and add --export option
[elogind.git] / extras / ata_id / ata_id.c
1 /*
2  * ata_id - reads product/serial number from ATA drives
3  *
4  * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
5  *
6  *      This library is free software; you can redistribute it and/or
7  *      modify it under the terms of the GNU Lesser General Public
8  *      License as published by the Free Software Foundation; either
9  *      version 2.1 of the License, or (at your option) any later version.
10  *
11  *      This library is distributed in the hope that it will be useful,
12  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  *      Lesser General Public License for more details.
15  *
16  *      You should have received a copy of the GNU Lesser General Public
17  *      License along with this library; if not, write to the Free Software
18  *      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20
21 #ifndef _GNU_SOURCE
22 #define _GNU_SOURCE 1
23 #endif
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <ctype.h>
30 #include <errno.h>
31 #include <sys/ioctl.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <linux/types.h>
35 #include <linux/hdreg.h>
36
37 #include "../../logging.h"
38 #include "../../udev_utils.h"
39
40 #ifdef USE_LOG
41 void log_message(int priority, const char *format, ...)
42 {
43         va_list args;
44         static int udev_log = -1;
45
46         if (udev_log == -1) {
47                 const char *value;
48
49                 value = getenv("UDEV_LOG");
50                 if (value)
51                         udev_log = log_priority(value);
52                 else
53                         udev_log = LOG_ERR;
54         }
55
56         if (priority > udev_log)
57                 return;
58
59         va_start(args, format);
60         vsyslog(priority, format, args);
61         va_end(args);
62 }
63 #endif
64
65 static void set_str(char *to, const unsigned char *from, int count)
66 {
67         int i, j;
68         int len;
69
70         len = strnlen(from, count);
71         while (isspace(from[len-1]))
72                 len--;
73
74         i = 0;
75         while (isspace(from[i]) && (i < len))
76                 i++;
77
78         j = 0;
79         while (i < len) {
80                 switch(from[i]) {
81                 case '/':
82                 case ' ':
83                         to[j++] = '_';
84                         break;
85                 default:
86                         to[j++] = from[i];
87                 }
88                 i++;
89         }
90         to[j] = '\0';
91 }
92
93 int main(int argc, char *argv[])
94 {
95         struct hd_driveid id;
96         char model[41];
97         char serial[21];
98         char revision[9];
99         const char *node = NULL;
100         int i;
101         int export = 0;
102         int fd;
103         int rc = 0;
104
105         for (i = 1 ; i < argc; i++) {
106                 char *arg = argv[i];
107
108                 if (strcmp(arg, "--export") == 0) {
109                         export = 1;
110                 } else
111                         node = arg;
112         }
113         if (!node) {
114                 err("no node specified");
115                 rc = 1;
116                 goto exit;
117         }
118
119         fd = open(node, O_RDONLY);
120         if (fd < 0)
121                 if (errno == ENOMEDIUM)
122                         fd = open(node, O_RDONLY|O_NONBLOCK);
123         if (fd < 0) {
124                 err("unable to open '%s'", node);
125                 rc = 1;
126                 goto exit;
127         }
128
129         if (ioctl(fd, HDIO_GET_IDENTITY, &id)) {
130                 err("HDIO_GET_IDENTITY failed for '%s'", node);
131                 rc = 3;
132                 goto close;
133         }
134
135         set_str(model, id.model, 40);
136         set_str(serial, id.serial_no, 20);
137         set_str(revision, id.fw_rev, 8);
138
139         if (export) {
140                 printf("ID_MODEL=%s\n", model);
141                 printf("ID_SERIAL=%s\n", serial);
142                 printf("ID_REVISION=%s\n", revision);
143         } else
144                 printf("%s_%s\n", model, serial);
145
146 close:
147         close(fd);
148 exit:
149         logging_close();
150         return rc;
151 }