1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
4 This file is part of libatasmart.
6 Copyright 2008 Lennart Poettering
8 libatasmart is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as
10 published by the Free Software Foundation, either version 2.1 of the
11 License, or (at your option) any later version.
13 libatasmart is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with libatasmart. If not, If not, see
20 <http://www.gnu.org/licenses/>.
53 int main(int argc, char *argv[]) {
55 const char *device = NULL, *argv0, *p, *file = NULL;
58 SkBool from_blob = FALSE;
60 static const struct option long_options[] = {
61 {"overall", no_argument, &mode, MODE_OVERALL},
62 {"power-on", no_argument, &mode, MODE_POWER_ON},
63 {"power-cycle", no_argument, &mode, MODE_POWER_CYCLE},
64 {"bad", no_argument, &mode, MODE_BAD},
65 {"temperature", no_argument, &mode, MODE_TEMPERATURE},
66 {"can-smart", no_argument, &mode, MODE_CAN_SMART},
67 {"status", no_argument, &mode, MODE_STATUS},
68 {"save", optional_argument, NULL, ARG_SAVE},
69 {"load", optional_argument, NULL, ARG_LOAD},
70 {"help", no_argument, NULL, 'h' },
75 if ((p = strrchr(argv0, '/')))
81 if ((opt = getopt_long(argc, argv, "h", long_options, NULL)) < 0)
90 "Usage: %s [PARAMETERS] DEVICE\n"
91 "Reads ATA SMART data from a device and parses it.\n"
93 "\t--overall \tShow overall status\n"
94 "\t--status \tShow SMART status\n"
95 "\t--can-smart \tShow whether SMART is supported\n"
96 "\t--power-on \tPrint power on time in ms\n"
97 "\t--power-cycle \tPrint number of power cycles\n"
98 "\t--bad \tPrint bad sector count\n"
99 "\t--temperature \tPrint drive temperature in mKelvin\n"
100 "\t--save[=FILENAME]\tSave raw data to file/STDOUT\n"
101 "\t--load[=FILENAME]\tRead data from a file/STDIN instead of device\n"
102 "\t-h | --help \tShow this help\n", argv0);
112 device = optarg ? optarg : "-";
120 fprintf(stderr, "Invalid arguments.\n");
126 if (optind != argc-1) {
127 fprintf(stderr, "No or more than one device specified.\n");
131 device = argv[optind];
133 if (optind != argc) {
134 fprintf(stderr, "Too many arguments.\n");
144 if ((ret = sk_disk_open(NULL, &d)) < 0) {
145 fprintf(stderr, "Failed to open disk: %s\n", strerror(errno));
149 if (strcmp(device, "-")) {
150 if (!(f = fopen(device, "r"))) {
151 fprintf(stderr, "Failed to open file: %s\n", strerror(errno));
156 size = fread(blob, 1, sizeof(blob), f);
161 if (size >= sizeof(blob)) {
162 fprintf(stderr, "File too large for buffer.\n");
166 if ((ret = sk_disk_set_blob(d, blob, size)) < 0) {
167 fprintf(stderr, "Failed to set blob: %s\n", strerror(errno));
172 if ((ret = sk_disk_open(device, &d)) < 0) {
173 fprintf(stderr, "Failed to open disk %s: %s\n", device, strerror(errno));
180 if ((ret = sk_disk_dump(d)) < 0) {
181 fprintf(stderr, "Failed to dump disk data: %s\n", strerror(errno));
187 case MODE_CAN_SMART: {
190 if ((ret = sk_disk_smart_is_available(d, &available)) < 0) {
191 fprintf(stderr, "Failed to query whether SMART is available: %s\n", strerror(errno));
195 printf("%s\n", available ? "YES" : "NO");
196 q = available ? 0 : 1;
201 SkSmartOverall overall;
203 if ((ret = sk_disk_smart_read_data(d)) < 0) {
204 fprintf(stderr, "Failed to read SMART data: %s\n", strerror(errno));
208 if ((ret = sk_disk_smart_get_overall(d, &overall)) < 0) {
209 fprintf(stderr, "Failed to get overall status: %s\n", strerror(errno));
213 printf("%s\n", sk_smart_overall_to_string(overall));
214 q = overall == SK_SMART_OVERALL_GOOD ? 0 : 1;
221 if ((ret = sk_disk_smart_status(d, &good)) < 0) {
222 fprintf(stderr, "Failed to get SMART status: %s\n", strerror(errno));
226 printf("%s\n", good ? "GOOD" : "BAD");
231 case MODE_POWER_ON: {
234 if ((ret = sk_disk_smart_read_data(d)) < 0) {
235 fprintf(stderr, "Failed to read SMART data: %s\n", strerror(errno));
239 if ((ret = sk_disk_smart_get_power_on(d, &ms)) < 0) {
240 fprintf(stderr, "Failed to get power on time: %s\n", strerror(errno));
244 printf("%llu\n", (unsigned long long) ms);
248 case MODE_POWER_CYCLE: {
251 if ((ret = sk_disk_smart_read_data(d)) < 0) {
252 fprintf(stderr, "Failed to read SMART data: %s\n", strerror(errno));
256 if ((ret = sk_disk_smart_get_power_cycle(d, &count)) < 0) {
257 fprintf(stderr, "Failed to get power cycles: %s\n", strerror(errno));
261 printf("%llu\n", (unsigned long long) count);
268 if ((ret = sk_disk_smart_read_data(d)) < 0) {
269 fprintf(stderr, "Failed to read SMART data: %s\n", strerror(errno));
273 if ((ret = sk_disk_smart_get_bad(d, &bad)) < 0) {
274 fprintf(stderr, "Failed to get bad sectors: %s\n", strerror(errno));
278 printf("%llu\n", (unsigned long long) bad);
283 case MODE_TEMPERATURE: {
286 if ((ret = sk_disk_smart_read_data(d)) < 0) {
287 fprintf(stderr, "Failed to read SMART data: %s\n", strerror(errno));
291 if ((ret = sk_disk_smart_get_temperature(d, &mkelvin)) < 0) {
292 fprintf(stderr, "Failed to get temperature: %s\n", strerror(errno));
296 printf("%llu\n", (unsigned long long) mkelvin);
306 if ((ret = sk_disk_smart_read_data(d)) < 0) {
307 fprintf(stderr, "Failed to read SMART data: %s\n", strerror(errno));
311 if ((ret = sk_disk_get_blob(d, &blob, &size)) < 0) {
312 fprintf(stderr, "Failed to get blob: %s\n", strerror(errno));
316 if (file && strcmp(file, "-")) {
317 if (!(f = fopen(file, "w"))) {
318 fprintf(stderr, "Failed to open '%s': %s\n", file, strerror(errno));
323 n = fwrite(blob, 1, size, f);
329 fprintf(stderr, "Failed to write to disk: %s\n", strerror(errno));