smartctl.cpp 8.62 KB
Newer Older
1
//  $Id: smartctl.cpp,v 1.9 2002/10/15 14:24:27 ballen4705 Exp $
ballen4705's avatar
ballen4705 committed
2
3
4
/*
 * smartctl.c
 *
5
6
 * Home page of code is: http://smartmontools.sourceforge.net
 *
ballen4705's avatar
ballen4705 committed
7
 * Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
ballen4705's avatar
ballen4705 committed
8
9
10
11
12
13
14
15
16
17
 * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * You should have received a copy of the GNU General Public License
 * (for example COPYING); if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
ballen4705's avatar
ballen4705 committed
18
19
20
21
22
23
 *
 * This code was originally developed as a Senior Thesis by Michael Cornwell
 * at the Concurrent Systems Laboratory (now part of the Storage Systems
 * Research Center), Jack Baskin School of Engineering, University of
 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
 *
ballen4705's avatar
ballen4705 committed
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 */


#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/hdreg.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <string.h>
#include "smartctl.h"
#include "atacmds.h"
#include "ataprint.h"
#include "scsicmds.h"
#include "scsiprint.h"

unsigned char driveinfo               = FALSE;
unsigned char checksmart              = FALSE;
unsigned char smartvendorattrib       = FALSE;
unsigned char generalsmartvalues      = FALSE;
unsigned char smartselftestlog        = FALSE;
unsigned char smarterrorlog           = FALSE;
unsigned char smartdisable            = FALSE;
unsigned char smartenable             = FALSE;
unsigned char smartstatus             = FALSE;
unsigned char smartexeoffimmediate    = FALSE;
unsigned char smartshortselftest      = FALSE;
unsigned char smartextendselftest     = FALSE;
unsigned char smartshortcapselftest   = FALSE;
unsigned char smartextendcapselftest  = FALSE;
unsigned char smartselftestabort      = FALSE;
unsigned char smartautoofflineenable  = FALSE;
unsigned char smartautoofflinedisable = FALSE;
unsigned char smartautosaveenable     = FALSE;
unsigned char smartautosavedisable    = FALSE;
unsigned char printcopyleft           = FALSE;
60
unsigned char smart009minutes         = FALSE;
ballen4705's avatar
ballen4705 committed
61
62
63
64
65
66
67
68
69
70


/*  void Usage (void) 
	prints help information for command syntax */



void Usage ( void){
  printf( "usage: smartctl -[options] [device]\n");
  printf( "Read Only Options:\n");
71
72
73
74
75
76
77
78
79
80
81
  printf( "\t\t%c\t\tShow version, copyright and license information\n", PRINTCOPYLEFT);
  printf( "\t\t%c\t\tShow all S.M.A.R.T. Information (ATA and SCSI)\n",  SMARTVERBOSEALL);
  printf( "\t\t%c\t\tShow S.M.A.R.T. Drive Info      (ATA and SCSI)\n",  DRIVEINFO);
  printf( "\t\t%c\t\tShow S.M.A.R.T. Status          (ATA and SCSI)\n",  CHECKSMART);
  printf( "\t\t%c\t\tShow S.M.A.R.T. General Attributes  (ATA Only)\n",  GENERALSMARTVALUES);
  printf( "\t\t%c\t\tShow S.M.A.R.T. Vendor Attributes   (ATA Only)\n",  SMARTVENDORATTRIB);
  printf( "\t\t%c\t\tShow S.M.A.R.T. Drive Error Log     (ATA Only\n",   SMARTERRORLOG);
  printf( "\t\t%c\t\tShow S.M.A.R.T. Drive Self Test Log (ATA Only)\n",  SMARTSELFTESTLOG);
  printf( "\n");
  printf( "Vendor-specific Display Options:\n");
  printf( "\t\t%c\t\tRaw Attribute 009 is minutes        (ATA Only)\n",  SMART009MINUTES);
ballen4705's avatar
ballen4705 committed
82
83
  printf( "\n");
  printf( "Enable/Disable Options:\n");
84
85
86
87
88
89
  printf( "\t\t%c\t\tEnable  S.M.A.R.T. data collection    (ATA and SCSI)\n",SMARTENABLE);
  printf( "\t\t%c\t\tDisable S.M.A.R.T. data collection    (ATA and SCSI)\n",SMARTDISABLE);
  printf( "\t\t%c\t\tEnable  S.M.A.R.T. Automatic Offline Test (ATA Only)\n",SMARTAUTOOFFLINEENABLE);
  printf( "\t\t%c\t\tDisable S.M.A.R.T. Automatic Offline Test (ATA Only)\n",SMARTAUTOOFFLINEDISABLE);
  printf( "\t\t%c\t\tEnable  S.M.A.R.T. Attribute Autosave     (ATA Only)\n",SMARTAUTOSAVEENABLE);
  printf( "\t\t%c\t\tDisable S.M.A.R.T. Attribute Autosave     (ATA Only)\n",SMARTAUTOSAVEDISABLE);
ballen4705's avatar
ballen4705 committed
90
91
  printf( "\n");
  printf( "Test Options:\n");
92
93
94
95
96
97
  printf( "\t\t%c\t\tExecute Off-line data collection (ATA Only)\n",          SMARTEXEOFFIMMEDIATE);
  printf( "\t\t%c\t\tExecute Short Self Test (ATA Only)\n",                   SMARTSHORTSELFTEST );
  printf( "\t\t%c\t\tExecute Short Self Test (Captive Mode) (ATA Only)\n",    SMARTSHORTCAPSELFTEST );
  printf( "\t\t%c\t\tExecute Extended Self Test (ATA Only)\n",                SMARTEXTENDSELFTEST );
  printf( "\t\t%c\t\tExecute Extended Self Test (Captive Mode) (ATA Only)\n", SMARTEXTENDCAPSELFTEST );
  printf( "\t\t%c\t\tExecute Self Test Abort (ATA Only)\n\n",                 SMARTSELFTESTABORT );
ballen4705's avatar
ballen4705 committed
98
99
100
101
102
103
104
105
  printf( "Examples:\n");
  printf("\tsmartctl -etf /dev/hda   (Enables S.M.A.R.T. on first disk)\n");
  printf("\tsmartctl -a   /dev/hda   (Prints all S.M.A.R.T. information)\n");
  printf("\tsmartctl -X   /dev/hda   (Executes extended disk self-test)\n");
  printf("Please see the man pages or the web site for further information.\n");

}

106
107
108
109
110
111
const char opts[] = { 
  DRIVEINFO, CHECKSMART, SMARTVERBOSEALL, SMARTVENDORATTRIB,
  GENERALSMARTVALUES, SMARTERRORLOG, SMARTSELFTESTLOG, SMARTDISABLE,
  SMARTENABLE, SMARTAUTOOFFLINEENABLE, SMARTAUTOOFFLINEDISABLE,
  SMARTEXEOFFIMMEDIATE, SMARTSHORTSELFTEST, SMARTEXTENDSELFTEST, 
  SMARTSHORTCAPSELFTEST, SMARTEXTENDCAPSELFTEST, SMARTSELFTESTABORT,
112
  SMARTAUTOSAVEENABLE,SMARTAUTOSAVEDISABLE,PRINTCOPYLEFT,SMART009MINUTES,'\0'
113
};
ballen4705's avatar
ballen4705 committed
114

115
/*      Takes command options and sets features to be run */	
ballen4705's avatar
ballen4705 committed
116
void ParseOpts (int argc, char** argv){
117
118
119
  int optchar;
  extern char *optarg;
  extern int optopt, optind, opterr;
ballen4705's avatar
ballen4705 committed
120
  
121
122
  opterr=1;
  while (-1 != (optchar = getopt(argc, argv, opts))) {
ballen4705's avatar
ballen4705 committed
123
    switch (optchar){
124
125
126
    case SMART009MINUTES:
      smart009minutes=TRUE;
      break;
ballen4705's avatar
ballen4705 committed
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
    case PRINTCOPYLEFT :
      printcopyleft=TRUE;
      break;
    case DRIVEINFO :
      driveinfo  = TRUE;
      break;		
    case CHECKSMART :
      driveinfo  = TRUE;
      checksmart = TRUE;		
      break;
    case SMARTVERBOSEALL :
      driveinfo = TRUE;
      checksmart = TRUE;
      generalsmartvalues = TRUE;
      smartvendorattrib = TRUE;
      smarterrorlog = TRUE;
      smartselftestlog = TRUE;
      break;
    case SMARTVENDORATTRIB :
      smartvendorattrib = TRUE;
      break;
    case GENERALSMARTVALUES :
      generalsmartvalues = TRUE;
      break;
    case SMARTERRORLOG :
      smarterrorlog = TRUE;
      break;
    case SMARTSELFTESTLOG :
      smartselftestlog = TRUE;
      break;
    case SMARTDISABLE :
      smartdisable = TRUE;
      break;
    case SMARTENABLE :
      smartenable   = TRUE;
      break;
    case SMARTAUTOSAVEENABLE:
      smartautosaveenable = TRUE;
      break;
    case SMARTAUTOSAVEDISABLE:
      smartautosavedisable = TRUE;
      break;
    case SMARTAUTOOFFLINEENABLE: 
      smartautoofflineenable = TRUE;
      break;
    case SMARTAUTOOFFLINEDISABLE:
      smartautoofflinedisable = TRUE;
      break;
    case SMARTEXEOFFIMMEDIATE:
      smartexeoffimmediate = TRUE;
      break;
    case SMARTSHORTSELFTEST :
      smartshortselftest = TRUE;
      break;
    case SMARTEXTENDSELFTEST :
      smartextendselftest = TRUE;
      break;
    case SMARTSHORTCAPSELFTEST:
      smartshortcapselftest = TRUE;
      break;
    case SMARTEXTENDCAPSELFTEST:
      smartextendcapselftest = TRUE;
      break;
    case SMARTSELFTESTABORT:
      smartselftestabort = TRUE;
      break;
    default:
      Usage();
      exit (-1);	
    }
    
    if ( (smartexeoffimmediate + smartshortselftest +
	  smartextendselftest + smartshortcapselftest +
	  smartextendcapselftest ) > 1){
      Usage();
      printf ("\n ERROR: smartctl can only run a single test at a time \n");
      exit(-1);
    }
  }
}

/* Main Program */

int main (int argc, char **argv){
  int fd;
  char *device;
  
214
  printf("smartctl version %d.%d-%d Copyright (C) 2002 Bruce Allen\n",RELEASE_MAJOR,RELEASE_MINOR,SMARTMONTOOLS_VERSION);
215
  printf("Home page of smartctl is %s\n\n",PROJECTHOME);
216
  
ballen4705's avatar
ballen4705 committed
217
218
219
220
221
222
223
224
  // Part input arguments
  ParseOpts (argc,argv);
  
  // Print Copyright/License info if needed
  if (printcopyleft){
    printf("smartctl comes with ABSOLUTELY NO WARRANTY. This\n");
    printf("is free software, and you are welcome to redistribute it\n");
    printf("under the terms of the GNU General Public License Version 2.\n");
225
    printf("See http://www.gnu.org for further details.\n\n");
226
    printf("CVS version ID %s\n","$Id: smartctl.cpp,v 1.9 2002/10/15 14:24:27 ballen4705 Exp $");
ballen4705's avatar
ballen4705 committed
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
    exit(0);
 }

  // Further argument checking
  if ( argc != 3 ){
    Usage();
    exit (-1);
  }
    
  /* open device */
  fd = open ( device=argv[2], O_RDWR );
  
  if ( fd < 0) {
    perror ( "Device open failed");
    exit(-1);
  }
  
  if ( device[5] == 'h')
    ataPrintMain (fd );
  else if (device[5] == 's')
    scsiPrintMain (fd);
  else 
    Usage();
  
  return 0;
}