1 /*
2  * os_generic.cpp
3  *
4  * Home page of code is: http://www.smartmontools.org
5  *
6  * Copyright (C) YEAR YOUR_NAME
7  * Copyright (C) 2003-8 Bruce Allen
8  * Copyright (C) 2008-18 Christian Franke
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12 
13 
14 /*
15     NOTE: The code in this file is only called when smartmontools has
16     been compiled on an unrecognized/unsupported platform.  This file
17     can then serve as a "template" to make os_myOS.cpp if you wish to
18     build support for that platform.
19 
20 
21  PORTING NOTES AND COMMENTS
22  --------------------------
23 
24  To port smartmontools to the OS of your choice, please:
25 
26  [0] Contact smartmontools-support@listi.jpberlin.de to check
27      that it's not already been done.
28 
29  [1] Make copies of os_generic.h and os_generic.cpp called os_myOS.h
30      and os_myOS.cpp .
31 
32  [2] Modify configure.in so that case "${host}" includes myOS.
33 
34  [3] Verify that ./autogen.sh && ./configure && make compiles the
35      code.  If not, fix any compilation problems.  If your OS lacks
36      some function that is used elsewhere in the code, then add a
37      AC_CHECK_FUNCS([missingfunction]) line to configure.in, and
38      surround uses of the function with:
39      #ifdef HAVE_MISSINGFUNCTION
40      ...
41      #endif
42      where the macro HAVE_MISSINGFUNCTION is (or is not) defined in
43      config.h.
44 
45  [4] Now that you have a working build environment, you have to
46      replace the 'stub' function calls provided in this file.
47 
48      Provide the functions defined in this file by fleshing out the
49      skeletons below.
50 
51  [5] Contact smartmontools-support@listi.jpberlin.de to see
52      about checking your code into the smartmontools CVS archive.
53 */
54 
55 /*
56  Developer's note: for testing this file, use an unsupported system,
57  for example: ./configure --build=rs6000-ibm-aix && make
58 */
59 
60 
61 // This is needed for the various HAVE_* macros and PROJECT_* macros.
62 #include "config.h"
63 
64 // These are needed to define prototypes and structures for the
65 // functions defined below
66 #include "atacmds.h"
67 #include "utility.h"
68 
69 // This is to include whatever structures and prototypes you define in
70 // os_generic.h
71 #include "os_generic.h"
72 
73 // Needed by '-V' option (CVS versioning) of smartd/smartctl.  You
74 // should have one *_H_CVSID macro appearing below for each file
75 // appearing with #include "*.h" above.  Please list these (below) in
76 // alphabetic/dictionary order.
77 const char * os_XXXX_cpp_cvsid="$Id: os_generic.cpp 4842 2018-12-02 16:07:26Z chrfranke $"
78   ATACMDS_H_CVSID CONFIG_H_CVSID OS_GENERIC_H_CVSID UTILITY_H_CVSID;
79 
80 // This is here to prevent compiler warnings for unused arguments of
81 // functions.
82 #define ARGUSED(x) ((void)(x))
83 
84 // print examples for smartctl.  You should modify this function so
85 // that the device paths are sensible for your OS, and to eliminate
86 // unsupported commands (eg, 3ware controllers).
print_smartctl_examples()87 static void print_smartctl_examples(){
88   printf("=================================================== SMARTCTL EXAMPLES =====\n\n"
89          "  smartctl -a /dev/hda                       (Prints all SMART information)\n\n"
90          "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
91          "                                              (Enables SMART on first disk)\n\n"
92          "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n\n"
93          "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
94          "                                      (Prints Self-Test & Attribute errors)\n"
95          "  smartctl -a --device=3ware,2 /dev/sda\n"
96          "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
97          );
98   return;
99 }
100 
101 /////////////////////////////////////////////////////////////////////////////
102 
103 namespace generic { // No need to publish anything, name provided for Doxygen
104 
105 class generic_smart_interface
106 : public /*implements*/ smart_interface
107 {
108 public:
109 #ifdef HAVE_GET_OS_VERSION_STR
110   virtual const char * get_os_version_str();
111 #endif
112 
113   virtual std::string get_app_examples(const char * appname);
114 
115   virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
116     const char * pattern = 0);
117 
118 protected:
119   virtual ata_device * get_ata_device(const char * name, const char * type);
120 
121   virtual scsi_device * get_scsi_device(const char * name, const char * type);
122 
123   virtual smart_device * autodetect_smart_device(const char * name);
124 
125   virtual smart_device * get_custom_smart_device(const char * name, const char * type);
126 
127   virtual std::string get_valid_custom_dev_types_str();
128 };
129 
130 
131 //////////////////////////////////////////////////////////////////////
132 
133 #ifdef HAVE_GET_OS_VERSION_STR
134 /// Return build host and OS version as static string
get_os_version_str()135 const char * generic_smart_interface::get_os_version_str()
136 {
137   return ::get_os_version_str();
138 }
139 #endif
140 
get_app_examples(const char * appname)141 std::string generic_smart_interface::get_app_examples(const char * appname)
142 {
143   if (!strcmp(appname, "smartctl"))
144     ::print_smartctl_examples(); // this prints to stdout ...
145   return ""; // ... so don't print again.
146 }
147 
148 // Return ATA device object for the given device name or NULL
149 // the type is always set to "ata"
get_ata_device(const char * name,const char * type)150 ata_device * generic_smart_interface::get_ata_device(const char * name, const char * type)
151 {
152   ARGUSED(name);
153   ARGUSED(type);
154   return NULL;
155 }
156 
157 // Return SCSI device object for the given device name or NULL
158 // the type is always set to "scsi"
get_scsi_device(const char * name,const char * type)159 scsi_device * generic_smart_interface::get_scsi_device(const char * name, const char * type)
160 {
161   ARGUSED(name);
162   ARGUSED(type);
163   return NULL;
164 }
165 
166 
167 // Return device object for the given device name (autodetect the device type)
autodetect_smart_device(const char * name)168 smart_device * generic_smart_interface::autodetect_smart_device(const char * name)
169 {
170   ARGUSED(name);
171   // for the given name return the appropriate device type
172   return NULL;
173 }
174 
175 
176 // Fill devlist with all OS's disk devices of given type that match the pattern
scan_smart_devices(smart_device_list & devlist,const char * type,const char * pattern)177 bool generic_smart_interface::scan_smart_devices(smart_device_list & devlist,
178   const char * type, const char * pattern /*= 0*/)
179 {
180   ARGUSED(devlist);
181   ARGUSED(type);
182   ARGUSED(pattern);
183   return false;
184 }
185 
186 
187 // Return device object of the given type with specified name or NULL
get_custom_smart_device(const char * name,const char * type)188 smart_device * generic_smart_interface::get_custom_smart_device(const char * name, const char * type)
189 {
190   ARGUSED(name);
191   ARGUSED(type);
192   return NULL;
193 }
194 
get_valid_custom_dev_types_str()195 std::string generic_smart_interface::get_valid_custom_dev_types_str()
196 {
197   return "";
198 }
199 
200 } // namespace
201 
202 
203 /////////////////////////////////////////////////////////////////////////////
204 /// Initialize platform interface and register with smi()
205 
init()206 void smart_interface::init()
207 {
208   static generic::generic_smart_interface the_interface;
209   smart_interface::set(&the_interface);
210 }
211