smartmontools  SVN Rev 4092
Utility to control and monitor storage systems with "S.M.A.R.T."
utility.h
Go to the documentation of this file.
1 /*
2  * utility.h
3  *
4  * Home page of code is: http://smartmontools.sourceforge.net
5  *
6  * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
7  * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
8  * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2, or (at your option)
13  * any later version.
14  *
15  * You should have received a copy of the GNU General Public License
16  * (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
17  *
18  * This code was originally developed as a Senior Thesis by Michael Cornwell
19  * at the Concurrent Systems Laboratory (now part of the Storage Systems
20  * Research Center), Jack Baskin School of Engineering, University of
21  * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
22  *
23  */
24 
25 #ifndef UTILITY_H_
26 #define UTILITY_H_
27 
28 #define UTILITY_H_CVSID "$Id: utility.h 4028 2014-12-13 14:59:48Z chrfranke $"
29 
30 #include <time.h>
31 #include <sys/types.h> // for regex.h (according to POSIX)
32 #include <regex.h>
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <string>
37 
38 #ifndef __GNUC__
39 #define __attribute_format_printf(x, y) /**/
40 #elif defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO
41 // Check format of __mingw_*printf() instead of MSVCRT.DLL:*printf()
42 #define __attribute_format_printf(x, y) __attribute__((format (gnu_printf, x, y)))
43 #define HAVE_WORKING_SNPRINTF 1
44 #else
45 #define __attribute_format_printf(x, y) __attribute__((format (printf, x, y)))
46 #endif
47 
48 // Make version information string
49 std::string format_version_info(const char * prog_name, bool full = false);
50 
51 // return (v)sprintf() formated std::string
52 std::string strprintf(const char * fmt, ...)
54 std::string vstrprintf(const char * fmt, va_list ap);
55 
56 // Return true if STR starts with PREFIX
57 inline bool str_starts_with(const char * str, const char * prefix)
58  { return !strncmp(str, prefix, strlen(prefix)); }
59 
60 inline bool str_starts_with(const std::string & str, const char * prefix)
61  { return !strncmp(str.c_str(), prefix, strlen(prefix)); }
62 
63 #ifndef HAVE_WORKING_SNPRINTF
64 // Substitute by safe replacement functions
65 int safe_snprintf(char *buf, int size, const char *fmt, ...)
67 int safe_vsnprintf(char *buf, int size, const char *fmt, va_list ap);
68 #define snprintf safe_snprintf
69 #define vsnprintf safe_vsnprintf
70 #endif
71 
72 #ifndef HAVE_STRTOULL
73 // Replacement for missing strtoull() (Linux with libc < 6, MSVC)
74 uint64_t strtoull(const char * p, char * * endp, int base);
75 #endif
76 
77 // Utility function prints current date and time and timezone into a
78 // character buffer of length>=64. All the fuss is needed to get the
79 // right timezone info (sigh).
80 #define DATEANDEPOCHLEN 64
81 void dateandtimezone(char *buffer);
82 // Same, but for time defined by epoch tval
83 void dateandtimezoneepoch(char *buffer, time_t tval);
84 
85 // like printf() except that we can control it better. Note --
86 // although the prototype is given here in utility.h, the function
87 // itself is defined differently in smartctl and smartd. So the
88 // function definition(s) are in smartd.c and in smartctl.c.
89 void pout(const char *fmt, ...)
91 
92 // replacement for perror() with redirected output.
93 void syserror(const char *message);
94 
95 // Function for processing -r option in smartctl and smartd
96 int split_report_arg(char *s, int *i);
97 
98 // Function for processing -t selective... option in smartctl
99 int split_selective_arg(char *s, uint64_t *start, uint64_t *stop, int *mode);
100 
101 // Replacement for exit(status)
102 // (exit is not compatible with C++ destructors)
103 #define EXIT(status) { throw (int)(status); }
104 
105 
106 #ifdef OLD_INTERFACE
107 
108 // Utility function to free memory
109 void *FreeNonZero(void* address, int size, int whatline, const char* file);
110 
111 // A custom version of strdup() that keeps track of how much memory is
112 // being allocated. If mustexist is set, it also throws an error if we
113 // try to duplicate a NULL string.
114 char *CustomStrDup(const char *ptr, int mustexist, int whatline, const char* file);
115 
116 #endif // OLD_INTERFACE
117 
118 // Compile time check of byte ordering
119 // (inline const function allows compiler to remove dead code)
120 inline bool isbigendian()
121 {
122 #ifdef WORDS_BIGENDIAN
123  return true;
124 #else
125  return false;
126 #endif
127 }
128 
129 // Runtime check of ./configure result, throws on error.
130 void check_config();
131 
132 // This value follows the peripheral device type value as defined in
133 // SCSI Primary Commands, ANSI INCITS 301:1997. It is also used in
134 // the ATA standard for packet devices to define the device type.
135 const char *packetdevicetype(int type);
136 
137 // returns true if any of the n bytes are nonzero, else zero.
138 bool nonempty(const void * data, int size);
139 
140 // needed to fix glibc bug
141 void FixGlibcTimeZoneBug();
142 
143 // Format integer with thousands separator
144 const char * format_with_thousands_sep(char * str, int strsize, uint64_t val,
145  const char * thousands_sep = 0);
146 
147 // Format capacity with SI prefixes
148 const char * format_capacity(char * str, int strsize, uint64_t val,
149  const char * decimal_point = 0);
150 
151 // Wrapper class for a raw data buffer
153 {
154 public:
155  explicit raw_buffer(unsigned sz, unsigned char val = 0)
156  : m_data(new unsigned char[sz]),
157  m_size(sz)
158  { memset(m_data, val, m_size); }
159 
161  { delete [] m_data; }
162 
163  unsigned size() const
164  { return m_size; }
165 
166  unsigned char * data()
167  { return m_data; }
168  const unsigned char * data() const
169  { return m_data; }
170 
171 private:
172  unsigned char * m_data;
173  unsigned m_size;
174 
175  raw_buffer(const raw_buffer &);
176  void operator=(const raw_buffer &);
177 };
178 
179 /// Wrapper class for FILE *.
181 {
182 public:
183  explicit stdio_file(FILE * f = 0, bool owner = false)
184  : m_file(f), m_owner(owner) { }
185 
186  stdio_file(const char * name, const char * mode)
187  : m_file(fopen(name, mode)), m_owner(true) { }
188 
190  {
191  if (m_file && m_owner)
192  fclose(m_file);
193  }
194 
195  bool open(const char * name, const char * mode)
196  {
197  m_file = fopen(name, mode);
198  m_owner = true;
199  return !!m_file;
200  }
201 
202  void open(FILE * f, bool owner = false)
203  {
204  m_file = f;
205  m_owner = owner;
206  }
207 
208  bool close()
209  {
210  if (!m_file)
211  return true;
212  bool ok = !ferror(m_file);
213  if (fclose(m_file))
214  ok = false;
215  m_file = 0;
216  return ok;
217  }
218 
219  operator FILE * ()
220  { return m_file; }
221 
222  bool operator!() const
223  { return !m_file; }
224 
225 private:
226  FILE * m_file;
227  bool m_owner;
228 
229  stdio_file(const stdio_file &);
230  void operator=(const stdio_file &);
231 };
232 
233 /// Wrapper class for regex(3).
234 /// Supports copy & assignment and is compatible with STL containers.
236 {
237 public:
238  // Construction & assignment
240 
241  regular_expression(const char * pattern, int flags,
242  bool throw_on_error = true);
243 
245 
247 
249 
250  /// Set and compile new pattern, return false on error.
251  bool compile(const char * pattern, int flags);
252 
253  // Get pattern from last compile().
254  const char * get_pattern() const
255  { return m_pattern.c_str(); }
256 
257  /// Get error message from last compile().
258  const char * get_errmsg() const
259  { return m_errmsg.c_str(); }
260 
261  // Return true if pattern is not set or bad.
262  bool empty() const
263  { return (m_pattern.empty() || !m_errmsg.empty()); }
264 
265  /// Return true if substring matches pattern
266  bool match(const char * str, int flags = 0) const
267  { return !regexec(&m_regex_buf, str, 0, (regmatch_t*)0, flags); }
268 
269  /// Return true if full string matches pattern
270  bool full_match(const char * str, int flags = 0) const
271  {
272  regmatch_t range;
273  return ( !regexec(&m_regex_buf, str, 1, &range, flags)
274  && range.rm_so == 0 && range.rm_eo == (int)strlen(str));
275  }
276 
277  /// Return true if substring matches pattern, fill regmatch_t array.
278  bool execute(const char * str, unsigned nmatch, regmatch_t * pmatch, int flags = 0) const
279  { return !regexec(&m_regex_buf, str, nmatch, pmatch, flags); }
280 
281 private:
282  std::string m_pattern;
283  int m_flags;
284  regex_t m_regex_buf;
285  std::string m_errmsg;
286 
287  void free_buf();
288  void copy(const regular_expression & x);
289  bool compile();
290 };
291 
292 #ifdef _WIN32
293 // Get exe directory
294 //(implemented in os_win32.cpp)
295 std::string get_exe_dir();
296 #endif
297 
298 
299 #ifdef OLD_INTERFACE
300 // remaining controller types in old interface modules
301 #define CONTROLLER_UNKNOWN 0x00
302 #define CONTROLLER_ATA 0x01
303 #define CONTROLLER_SCSI 0x02
304 #endif
305 
306 #endif
307 
regex_t m_regex_buf
Definition: utility.h:284
bool isbigendian()
Definition: utility.h:120
bool nonempty(const void *data, int size)
Definition: utility.cpp:695
u16 s[6]
Definition: megaraid.h:97
int safe_snprintf(char *buf, int size, const char *fmt,...) __attribute_format_printf(3
const char * format_with_thousands_sep(char *str, int strsize, uint64_t val, const char *thousands_sep=0)
Definition: utility.cpp:704
stdio_file(const char *name, const char *mode)
Definition: utility.h:186
u32 size
Definition: megaraid.h:79
bool m_owner
Definition: utility.h:227
~stdio_file()
Definition: utility.h:189
void dateandtimezone(char *buffer)
Definition: utility.cpp:337
bool str_starts_with(const char *str, const char *prefix)
Definition: utility.h:57
bool execute(const char *str, unsigned nmatch, regmatch_t *pmatch, int flags=0) const
Return true if substring matches pattern, fill regmatch_t array.
Definition: utility.h:278
unsigned size() const
Definition: utility.h:163
bool empty() const
Definition: utility.h:262
#define __attribute_format_printf(x, y)
Definition: utility.h:39
u16 flags
Definition: megaraid.h:93
void operator=(const stdio_file &)
void dateandtimezoneepoch(char *buffer, time_t tval)
Definition: utility.cpp:289
Wrapper class for FILE *.
Definition: utility.h:180
void open(FILE *f, bool owner=false)
Definition: utility.h:202
std::string get_exe_dir()
Definition: os_win32.cpp:3907
std::string strprintf(const char *fmt,...) __attribute_format_printf(1
ptr_t data
Definition: megaraid.h:94
int int safe_vsnprintf(char *buf, int size, const char *fmt, va_list ap)
Definition: utility.cpp:806
const unsigned char * data() const
Definition: utility.h:168
std::string m_errmsg
Definition: utility.h:285
std::string m_pattern
Definition: utility.h:282
int split_selective_arg(char *s, uint64_t *start, uint64_t *stop, int *mode)
Definition: utility.cpp:596
void copy(const regular_expression &x)
Definition: utility.cpp:469
~raw_buffer()
Definition: utility.h:160
ptr_t buffer
Definition: megaraid.h:89
const char * get_errmsg() const
Get error message from last compile().
Definition: utility.h:258
unsigned m_size
Definition: utility.h:173
Wrapper class for regex(3).
Definition: utility.h:235
std::string std::string vstrprintf(const char *fmt, va_list ap)
Definition: utility.cpp:779
stdio_file(FILE *f=0, bool owner=false)
Definition: utility.h:183
raw_buffer(unsigned sz, unsigned char val=0)
Definition: utility.h:155
regular_expression & operator=(const regular_expression &x)
Definition: utility.cpp:454
uint64_t strtoull(const char *p, char **endp, int base)
Definition: utility.cpp:545
void FixGlibcTimeZoneBug()
Definition: utility.cpp:167
std::string format_version_info(const char *prog_name, bool full=false)
Definition: utility.cpp:83
bool operator!() const
Definition: utility.h:222
bool open(const char *name, const char *mode)
Definition: utility.h:195
unsigned char * data()
Definition: utility.h:166
unsigned long long uint64_t
Definition: int64.h:54
const char * packetdevicetype(int type)
Definition: utility.cpp:257
bool match(const char *str, int flags=0) const
Return true if substring matches pattern.
Definition: utility.h:266
void pout(const char *fmt,...) __attribute_format_printf(1
void operator=(const raw_buffer &)
int split_report_arg(char *s, int *i)
Definition: utility.cpp:520
const char * format_capacity(char *str, int strsize, uint64_t val, const char *decimal_point=0)
Definition: utility.cpp:736
unsigned char * m_data
Definition: utility.h:172
bool close()
Definition: utility.h:208
void check_config()
Definition: utility.cpp:842
bool full_match(const char *str, int flags=0) const
Return true if full string matches pattern.
Definition: utility.h:270
const char * get_pattern() const
Definition: utility.h:254
void void syserror(const char *message)
Definition: utility.cpp:348
FILE * m_file
Definition: utility.h:226