Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / disk / smart-c / smart_.c @ 16d38264

Historique | Voir | Annoter | Télécharger (4,68 ko)

1
/*
2
 * Copyright (C) 2017 Bastiaan van Kesteren <bas@edeation.nl> - All rights reserved.
3
 *
4
 * This copyrighted material is made available to anyone wishing to use,
5
 * modify, copy, or redistribute it subject to the terms and conditions
6
 * of the GNU General Public License v.2 or v.3.
7
 */
8

    
9
#include <stdlib.h>
10
#include <stdio.h>
11
#include <unistd.h>
12
#include <string.h>
13
#include <libgen.h>
14
#include <sys/wait.h>
15
#include "common.h"
16

    
17
static char getitem(char *input, unsigned char item, char *output)
18
{
19
        unsigned char i = 0;
20
        unsigned char separators = 0;
21
        char know_this_seperator = 0;
22
        unsigned char start = 0;
23
        unsigned char stop = 0;
24

    
25
        /* Trim starting spaces */
26
        while (input[i] == ' ') {
27
                i++;
28
        }
29

    
30
        /* If we're requested to return the very first item... */
31
        if (separators == item) {
32
                start = i;
33
        }
34

    
35
        while (input[i] && separators < item + 1) {
36
                if (input[i] == ' ') {
37
                        if (know_this_seperator == 0) {
38
                                know_this_seperator = 1;
39
                                separators++;
40
                                if (separators == item + 1) {
41
                                        stop = i;
42
                                        break;
43
                                }
44
                        }
45
                } else if (know_this_seperator) {
46
                        know_this_seperator = 0;
47
                        if (separators == item) {
48
                                start = i;
49
                        }
50
                } else if (input[i] == '\n') {
51
                        input[i] = 0;
52
                        break;
53
                }
54

    
55
                i++;
56
        }
57

    
58
        if (stop) {
59
                /* Found stop, means we have a start as well */
60
                strncpy(output, &input[start], stop - start);
61
                return 1;
62
        } else if (start) {
63
                /* Have a start, no stop. We're returning the last item of the string */
64
                strcpy(output, &input[start]);
65
                return 1;
66
        }
67

    
68
        return 0;
69
}
70

    
71
int main(int argc, char **argv)
72
{
73
        char command[50];
74
        char output[255];
75
        char label[25][100];
76
        char value[25][25];
77
        unsigned char attribute = 0;
78
        FILE *f;
79
        unsigned int i;
80

    
81
        /* Prepare and execute command */
82
        snprintf(command, sizeof(command),
83
                 "smartctl -A -d ata /dev/%s -n standby",
84
                 &basename(argv[0])[6]);
85
        if ((f = popen(command, "r")) == 0) {
86
                return fail("cannot initiate command execution");
87
        }
88

    
89
        /* Process command output */
90
        while (fgets(output, sizeof(output), f) != NULL) {
91
                printf("#%s", output);
92
                /* Filter out attribute lines; look for lines starting with an attribute ID */
93
                if ((output[0] >= '0' && output[0] <= '9') ||
94
                    (output[0] == ' '
95
                     && (output[1] >= '0' && output[1] <= '9'))
96
                    || (output[0] == ' ' && output[1] == ' '
97
                        && (output[2] >= '0' && output[2] <= '9'))) {
98
                        /* Now, print the 2nd column (attribute name) and the 10th (raw value) */
99

    
100
                        getitem(output, 1, label[attribute]);
101
                        getitem(output, 9, value[attribute]);
102
                        attribute++;
103
                        if (attribute == 25) {
104
                                break;
105
                        }
106
                }
107
        }
108

    
109
        /* Close command (this is where we get the exit code! */
110
        {
111
                int status = pclose(f); /* using an explicit temp var, to be compatible with macos & openbsd */
112
                i = WEXITSTATUS(status);
113
        }
114
        if (i == 1 ||                /* smartctl command did not parse */
115
            /*i == 2 || *//* smartctl device open failed */
116
            i == 127) {                /* command not found */
117
                return fail("command execution failed");
118
        }
119

    
120
        /* Setup for caching */
121
        snprintf(command, sizeof(command), "/mnt/ram/smart_%s",
122
                 &basename(argv[0])[6]);
123

    
124
        if (attribute == 0) {
125
                printf("#Cached attributes\n");
126
                /* No output from command, try to fetch attribute-list from disk with NaN values */
127
                if ((f = fopen(command, "r")) == 0) {
128
                        return
129
                            fail
130
                            ("command did not return data, no cached attribute-list");
131
                        return 0;
132
                }
133
        }
134

    
135
        if (argc > 1) {
136
                if (strcmp(argv[1], "config") == 0) {
137
                        printf
138
                            ("graph_title S.M.A.R.T values for drive %s\n"
139
                             "graph_args --base 1000 --lower-limit 0\n"
140
                             "graph_vlabel Attribute S.M.A.R.T value\n"
141
                             "graph_category disk\n",
142
                             &basename(argv[0])[6]);
143

    
144
                        if (attribute == 0) {
145
                                while (fgets(output, sizeof(output), f) !=
146
                                       NULL) {
147
                                        for (i = 0; i < strlen(output);
148
                                             i++) {
149
                                                if (output[i] == '\n') {
150
                                                        output[i] = '\0';
151
                                                        break;
152
                                                }
153
                                        }
154
                                        printf("%s.label %s\n", output,
155
                                               output);
156
                                }
157
                                fclose(f);
158
                        } else {
159
                                f = fopen(command, "w");
160
                                do {
161
                                        attribute--;
162
                                        printf("%s.label %s\n",
163
                                               label[attribute],
164
                                               label[attribute]);
165
                                        if (f) {
166
                                                fprintf(f, "%s\n",
167
                                                        label[attribute]);
168
                                        }
169
                                } while (attribute);
170

    
171
                                if (f) {
172
                                        fclose(f);
173
                                }
174
                        }
175
                        printf("standby.label standby\n");
176
                        return 0;
177
                }
178
        }
179

    
180
        /* Asking for a fetch */
181
        if (attribute == 0) {
182
                /* No data, use cached info */
183
                while (fgets(output, sizeof(output), f) != NULL) {
184
                        for (i = 0; i < strlen(output); i++) {
185
                                if (output[i] == '\n') {
186
                                        output[i] = '\0';
187
                                        break;
188
                                }
189
                        }
190
                        printf("%s.value U\n", output);
191
                }
192
                printf("standby.value 1\n");
193
                fclose(f);
194
        } else {
195
                do {
196
                        attribute--;
197
                        printf("%s.value %s\n", label[attribute],
198
                               value[attribute]);
199
                } while (attribute);
200
                printf("standby.value 0\n");
201
        }
202

    
203
        return 0;
204
}