2 * ata_id - reads product/serial number from ATA drives
4 * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
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.
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.
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
31 #include <sys/ioctl.h>
32 #include <sys/types.h>
34 #include <linux/types.h>
35 #include <linux/hdreg.h>
37 #include "../../logging.h"
38 #include "../../udev_utils.h"
41 void log_message(int priority, const char *format, ...)
44 static int udev_log = -1;
49 value = getenv("UDEV_LOG");
51 udev_log = log_priority(value);
56 if (priority > udev_log)
59 va_start(args, format);
60 vsyslog(priority, format, args);
65 static void set_str(char *to, const char *from, size_t count)
69 /* strip trailing whitespace */
70 len = strnlen(from, count);
71 while (isspace(from[len-1]))
74 /* strip leading whitespace */
76 while (isspace(from[i]) && (i < len))
81 /* substitute multiple whitespace */
82 if (isspace(from[i])) {
83 while (isspace(from[i]))
97 int main(int argc, char *argv[])
103 const char *node = NULL;
109 logging_init("ata_id");
111 for (i = 1 ; i < argc; i++) {
114 if (strcmp(arg, "--export") == 0) {
120 err("no node specified");
125 fd = open(node, O_RDONLY);
127 if (errno == ENOMEDIUM)
128 fd = open(node, O_RDONLY|O_NONBLOCK);
130 err("unable to open '%s'", node);
135 if (ioctl(fd, HDIO_GET_IDENTITY, &id)) {
136 err("HDIO_GET_IDENTITY failed for '%s'", node);
141 set_str(model, (char *) id.model, 40);
142 set_str(serial, (char *) id.serial_no, 20);
143 set_str(revision, (char *) id.fw_rev, 8);
146 if ((id.config >> 8) & 0x80) {
147 /* This is an ATAPI device */
148 switch ((id.config >> 8) & 0x1f) {
150 printf("ID_TYPE=cd\n");
153 printf("ID_TYPE=tape\n");
156 printf("ID_TYPE=cd\n");
159 printf("ID_TYPE=optical\n");
162 printf("ID_TYPE=generic\n");
166 printf("ID_TYPE=disk\n");
168 printf("ID_MODEL=%s\n", model);
169 printf("ID_SERIAL=%s\n", serial);
170 printf("ID_REVISION=%s\n", revision);
171 printf("ID_BUS=ata\n");
173 if (serial[0] != '\0')
174 printf("%s_%s\n", model, serial);
176 printf("%s\n", model);