2 * ata_id - reads product/serial number from ATA drives
4 * Copyright (C) 2005-2008 Kay Sievers <kay.sievers@vrfy.org>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * This program 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
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
35 #include <linux/types.h>
36 #include <linux/hdreg.h>
39 #include "libudev-private.h"
41 static void log_fn(struct udev *udev, int priority,
42 const char *file, int line, const char *fn,
43 const char *format, va_list args)
45 vsyslog(priority, format, args);
48 int main(int argc, char *argv[])
56 const char *node = NULL;
60 static const struct option options[] = {
61 { "export", no_argument, NULL, 'x' },
62 { "help", no_argument, NULL, 'h' },
70 udev_log_init("ata_id");
71 udev_set_log_fn(udev, log_fn);
76 option = getopt_long(argc, argv, "xh", options, NULL);
85 printf("Usage: ata_id [--export] [--help] <device>\n"
86 " --export print values as environment keys\n"
87 " --help print this help text\n\n");
96 err(udev, "no node specified\n");
101 fd = open(node, O_RDONLY|O_NONBLOCK);
103 err(udev, "unable to open '%s'\n", node);
108 if (ioctl(fd, HDIO_GET_IDENTITY, &id)) {
109 if (errno == ENOTTY) {
110 info(udev, "HDIO_GET_IDENTITY unsupported for '%s'\n", node);
113 err(udev, "HDIO_GET_IDENTITY failed for '%s'\n", node);
119 memcpy (model, id.model, 40);
121 udev_util_encode_string(model, model_enc, sizeof(model_enc));
122 udev_util_replace_whitespace((char *) id.model, model, 40);
123 udev_util_replace_chars(model, NULL);
124 udev_util_replace_whitespace((char *) id.serial_no, serial, 20);
125 udev_util_replace_chars(serial, NULL);
126 udev_util_replace_whitespace((char *) id.fw_rev, revision, 8);
127 udev_util_replace_chars(revision, NULL);
130 if ((id.config >> 8) & 0x80) {
131 /* This is an ATAPI device */
132 switch ((id.config >> 8) & 0x1f) {
134 printf("ID_TYPE=cd\n");
137 printf("ID_TYPE=tape\n");
140 printf("ID_TYPE=cd\n");
143 printf("ID_TYPE=optical\n");
146 printf("ID_TYPE=generic\n");
150 printf("ID_TYPE=disk\n");
152 printf("ID_BUS=ata\n");
153 printf("ID_MODEL=%s\n", model);
154 printf("ID_MODEL_ENC=%s\n", model_enc);
155 printf("ID_REVISION=%s\n", revision);
156 printf("ID_SERIAL=%s_%s\n", model, serial);
157 printf("ID_SERIAL_SHORT=%s\n", serial);
159 if (serial[0] != '\0')
160 printf("%s_%s\n", model, serial);
162 printf("%s\n", model);