]> git.ipfire.org Git - thirdparty/systemd.git/blame - extras/ata_id/ata_id.c
unify string replacement
[thirdparty/systemd.git] / extras / ata_id / ata_id.c
CommitLineData
670e4705
KS
1/*
2 * ata_id - reads product/serial number from ATA drives
3 *
7d563a17 4 * Copyright (C) 2005-2008 Kay Sievers <kay.sievers@vrfy.org>
670e4705 5 *
55e9959b
KS
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.
10 *
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.
15 *
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/>.
670e4705
KS
18 */
19
20#ifndef _GNU_SOURCE
21#define _GNU_SOURCE 1
22#endif
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <unistd.h>
27#include <fcntl.h>
28#include <ctype.h>
1aa1e248 29#include <string.h>
670e4705 30#include <errno.h>
4fa3d99d 31#include <getopt.h>
670e4705
KS
32#include <sys/ioctl.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <linux/types.h>
36#include <linux/hdreg.h>
37
01618658 38#include "../../udev/udev.h"
670e4705 39
7d563a17
KS
40static void log_fn(struct udev *udev, int priority,
41 const char *file, int line, const char *fn,
42 const char *format, va_list args)
670e4705 43{
670e4705 44 vsyslog(priority, format, args);
670e4705 45}
670e4705 46
670e4705
KS
47int main(int argc, char *argv[])
48{
7d563a17 49 struct udev *udev;
670e4705
KS
50 struct hd_driveid id;
51 char model[41];
52 char serial[21];
53 char revision[9];
54 const char *node = NULL;
670e4705
KS
55 int export = 0;
56 int fd;
57 int rc = 0;
4fa3d99d 58 static const struct option options[] = {
033e9f8c
KS
59 { "export", no_argument, NULL, 'x' },
60 { "help", no_argument, NULL, 'h' },
4fa3d99d
KS
61 {}
62 };
670e4705 63
7d563a17
KS
64 udev = udev_new();
65 if (udev == NULL)
66 goto exit;
67
5f84d726 68 logging_init("ata_id");
7d563a17 69 udev_set_log_fn(udev, log_fn);
5f84d726 70
4fa3d99d
KS
71 while (1) {
72 int option;
670e4705 73
4fa3d99d
KS
74 option = getopt_long(argc, argv, "xh", options, NULL);
75 if (option == -1)
76 break;
77
78 switch (option) {
79 case 'x':
670e4705 80 export = 1;
4fa3d99d
KS
81 break;
82 case 'h':
83 printf("Usage: ata_id [--export] [--help] <device>\n"
84 " --export print values as environemt keys\n"
85 " --help print this help text\n\n");
86 default:
87 rc = 1;
88 goto exit;
89 }
670e4705 90 }
4fa3d99d
KS
91
92 node = argv[optind];
93 if (node == NULL) {
7d563a17 94 err(udev, "no node specified\n");
670e4705
KS
95 rc = 1;
96 goto exit;
97 }
98
3515c0ad 99 fd = open(node, O_RDONLY|O_NONBLOCK);
670e4705 100 if (fd < 0) {
7d563a17 101 err(udev, "unable to open '%s'\n", node);
670e4705
KS
102 rc = 1;
103 goto exit;
104 }
105
106 if (ioctl(fd, HDIO_GET_IDENTITY, &id)) {
cfdea0f6 107 if (errno == ENOTTY) {
7d563a17 108 info(udev, "HDIO_GET_IDENTITY unsupported for '%s'\n", node);
cfdea0f6
MS
109 rc = 2;
110 } else {
7d563a17 111 err(udev, "HDIO_GET_IDENTITY failed for '%s'\n", node);
cfdea0f6
MS
112 rc = 3;
113 }
670e4705
KS
114 goto close;
115 }
116
92f43136
KS
117 udev_util_replace_whitespace((char *) id.model, model, 40);
118 udev_util_replace_whitespace((char *) id.serial_no, serial, 20);
119 udev_util_replace_whitespace((char *) id.fw_rev, revision, 8);
670e4705
KS
120
121 if (export) {
aaff09a3
KS
122 if ((id.config >> 8) & 0x80) {
123 /* This is an ATAPI device */
124 switch ((id.config >> 8) & 0x1f) {
125 case 0:
126 printf("ID_TYPE=cd\n");
127 break;
128 case 1:
129 printf("ID_TYPE=tape\n");
130 break;
131 case 5:
132 printf("ID_TYPE=cd\n");
133 break;
134 case 7:
135 printf("ID_TYPE=optical\n");
136 break;
137 default:
138 printf("ID_TYPE=generic\n");
139 break;
140 }
141 } else {
142 printf("ID_TYPE=disk\n");
143 }
670e4705
KS
144 printf("ID_MODEL=%s\n", model);
145 printf("ID_SERIAL=%s\n", serial);
146 printf("ID_REVISION=%s\n", revision);
46f01c6d 147 printf("ID_BUS=ata\n");
e03bce63
KS
148 } else {
149 if (serial[0] != '\0')
150 printf("%s_%s\n", model, serial);
151 else
152 printf("%s\n", model);
153 }
670e4705
KS
154
155close:
156 close(fd);
157exit:
7d563a17 158 udev_unref(udev);
670e4705
KS
159 logging_close();
160 return rc;
161}