smartmontools  SVN Rev 4335
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://www.smartmontools.org
5  *
6  * Copyright (C) 2002-11 Bruce Allen
7  * Copyright (C) 2008-16 Christian Franke
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 4309 2016-04-24 14:59:15Z 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 -t selective... option in smartctl
96 int split_selective_arg(char *s, uint64_t *start, uint64_t *stop, int *mode);
97 
98 // Replacement for exit(status)
99 // (exit is not compatible with C++ destructors)
100 #define EXIT(status) { throw (int)(status); }
101 
102 // Compile time check of byte ordering
103 // (inline const function allows compiler to remove dead code)
104 inline bool isbigendian()
105 {
106 #ifdef WORDS_BIGENDIAN
107  return true;
108 #else
109  return false;
110 #endif
111 }
112 
113 // Runtime check of ./configure result, throws on error.
114 void check_config();
115 
116 // This value follows the peripheral device type value as defined in
117 // SCSI Primary Commands, ANSI INCITS 301:1997. It is also used in
118 // the ATA standard for packet devices to define the device type.
119 const char *packetdevicetype(int type);
120 
121 // returns true if any of the n bytes are nonzero, else zero.
122 bool nonempty(const void * data, int size);
123 
124 // needed to fix glibc bug
125 void FixGlibcTimeZoneBug();
126 
127 // Copy not null terminated char array to null terminated string.
128 // Replace non-ascii characters. Remove leading and trailing blanks.
129 const char * format_char_array(char * str, int strsize, const char * chr, int chrsize);
130 
131 // Version for fixed size buffers.
132 template<size_t STRSIZE, size_t CHRSIZE>
133 inline const char * format_char_array(char (& str)[STRSIZE], const char (& chr)[CHRSIZE])
134  { return format_char_array(str, (int)STRSIZE, chr, (int)CHRSIZE); }
135 
136 // Format integer with thousands separator
137 const char * format_with_thousands_sep(char * str, int strsize, uint64_t val,
138  const char * thousands_sep = 0);
139 
140 // Format capacity with SI prefixes
141 const char * format_capacity(char * str, int strsize, uint64_t val,
142  const char * decimal_point = 0);
143 
144 // Wrapper class for a raw data buffer
146 {
147 public:
148  explicit raw_buffer(unsigned sz, unsigned char val = 0)
149  : m_data(new unsigned char[sz]),
150  m_size(sz)
151  { memset(m_data, val, m_size); }
152 
154  { delete [] m_data; }
155 
156  unsigned size() const
157  { return m_size; }
158 
159  unsigned char * data()
160  { return m_data; }
161  const unsigned char * data() const
162  { return m_data; }
163 
164 private:
165  unsigned char * m_data;
166  unsigned m_size;
167 
168  raw_buffer(const raw_buffer &);
169  void operator=(const raw_buffer &);
170 };
171 
172 /// Wrapper class for FILE *.
174 {
175 public:
176  explicit stdio_file(FILE * f = 0, bool owner = false)
177  : m_file(f), m_owner(owner) { }
178 
179  stdio_file(const char * name, const char * mode)
180  : m_file(fopen(name, mode)), m_owner(true) { }
181 
183  {
184  if (m_file && m_owner)
185  fclose(m_file);
186  }
187 
188  bool open(const char * name, const char * mode)
189  {
190  if (m_file && m_owner)
191  fclose(m_file);
192  m_file = fopen(name, mode);
193  m_owner = true;
194  return !!m_file;
195  }
196 
197  void open(FILE * f, bool owner = false)
198  {
199  if (m_file && m_owner)
200  fclose(m_file);
201  m_file = f;
202  m_owner = owner;
203  }
204 
205  bool close()
206  {
207  if (!m_file)
208  return true;
209  bool ok = !ferror(m_file);
210  if (fclose(m_file))
211  ok = false;
212  m_file = 0;
213  return ok;
214  }
215 
216  operator FILE * ()
217  { return m_file; }
218 
219  bool operator!() const
220  { return !m_file; }
221 
222 private:
223  FILE * m_file;
224  bool m_owner;
225 
226  stdio_file(const stdio_file &);
227  void operator=(const stdio_file &);
228 };
229 
230 /// Wrapper class for regex(3).
231 /// Supports copy & assignment and is compatible with STL containers.
233 {
234 public:
235  // Construction & assignment
237 
238  regular_expression(const char * pattern, int flags,
239  bool throw_on_error = true);
240 
242 
244 
246 
247  /// Set and compile new pattern, return false on error.
248  bool compile(const char * pattern, int flags);
249 
250  // Get pattern from last compile().
251  const char * get_pattern() const
252  { return m_pattern.c_str(); }
253 
254  /// Get error message from last compile().
255  const char * get_errmsg() const
256  { return m_errmsg.c_str(); }
257 
258  // Return true if pattern is not set or bad.
259  bool empty() const
260  { return (m_pattern.empty() || !m_errmsg.empty()); }
261 
262  /// Return true if substring matches pattern
263  bool match(const char * str, int flags = 0) const
264  { return !regexec(&m_regex_buf, str, 0, (regmatch_t*)0, flags); }
265 
266  /// Return true if full string matches pattern
267  bool full_match(const char * str, int flags = 0) const
268  {
269  regmatch_t range;
270  return ( !regexec(&m_regex_buf, str, 1, &range, flags)
271  && range.rm_so == 0 && range.rm_eo == (int)strlen(str));
272  }
273 
274  /// Return true if substring matches pattern, fill regmatch_t array.
275  bool execute(const char * str, unsigned nmatch, regmatch_t * pmatch, int flags = 0) const
276  { return !regexec(&m_regex_buf, str, nmatch, pmatch, flags); }
277 
278 private:
279  std::string m_pattern;
280  int m_flags;
281  regex_t m_regex_buf;
282  std::string m_errmsg;
283 
284  void free_buf();
285  void copy(const regular_expression & x);
286  bool compile();
287 };
288 
289 #ifdef _WIN32
290 // Get exe directory
291 //(implemented in os_win32.cpp)
292 std::string get_exe_dir();
293 #endif
294 
295 
296 #ifdef OLD_INTERFACE
297 // remaining controller types in old interface modules
298 #define CONTROLLER_UNKNOWN 0x00
299 #define CONTROLLER_ATA 0x01
300 #define CONTROLLER_SCSI 0x02
301 #endif
302 
303 #endif
304 
regex_t m_regex_buf
Definition: utility.h:281
bool isbigendian()
Definition: utility.h:104
bool nonempty(const void *data, int size)
Definition: utility.cpp:633
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:667
stdio_file(const char *name, const char *mode)
Definition: utility.h:179
u32 size
Definition: megaraid.h:79
bool m_owner
Definition: utility.h:224
~stdio_file()
Definition: utility.h:182
void dateandtimezone(char *buffer)
Definition: utility.cpp:349
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:275
unsigned size() const
Definition: utility.h:156
bool empty() const
Definition: utility.h:259
#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:297
Wrapper class for FILE *.
Definition: utility.h:173
void open(FILE *f, bool owner=false)
Definition: utility.h:197
std::string get_exe_dir()
Definition: os_win32.cpp:4467
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:769
const unsigned char * data() const
Definition: utility.h:161
std::string m_errmsg
Definition: utility.h:282
std::string m_pattern
Definition: utility.h:279
int split_selective_arg(char *s, uint64_t *start, uint64_t *stop, int *mode)
Definition: utility.cpp:581
void copy(const regular_expression &x)
Definition: utility.cpp:481
~raw_buffer()
Definition: utility.h:153
ptr_t buffer
Definition: megaraid.h:89
const char * get_errmsg() const
Get error message from last compile().
Definition: utility.h:255
unsigned m_size
Definition: utility.h:166
Wrapper class for regex(3).
Definition: utility.h:232
std::string std::string vstrprintf(const char *fmt, va_list ap)
Definition: utility.cpp:742
stdio_file(FILE *f=0, bool owner=false)
Definition: utility.h:176
raw_buffer(unsigned sz, unsigned char val=0)
Definition: utility.h:148
regular_expression & operator=(const regular_expression &x)
Definition: utility.cpp:466
uint64_t strtoull(const char *p, char **endp, int base)
Definition: utility.cpp:530
void FixGlibcTimeZoneBug()
Definition: utility.cpp:175
std::string format_version_info(const char *prog_name, bool full=false)
Definition: utility.cpp:83
bool operator!() const
Definition: utility.h:219
bool open(const char *name, const char *mode)
Definition: utility.h:188
unsigned char * data()
Definition: utility.h:159
unsigned long long uint64_t
Definition: int64.h:54
const char * packetdevicetype(int type)
Definition: utility.cpp:265
bool match(const char *str, int flags=0) const
Return true if substring matches pattern.
Definition: utility.h:263
void pout(const char *fmt,...) __attribute_format_printf(1
void operator=(const raw_buffer &)
const char * format_capacity(char *str, int strsize, uint64_t val, const char *decimal_point=0)
Definition: utility.cpp:699
unsigned char * m_data
Definition: utility.h:165
bool close()
Definition: utility.h:205
const char * format_char_array(char *str, int strsize, const char *chr, int chrsize)
Definition: utility.cpp:643
void check_config()
Definition: utility.cpp:805
bool full_match(const char *str, int flags=0) const
Return true if full string matches pattern.
Definition: utility.h:267
const char * get_pattern() const
Definition: utility.h:251
void void syserror(const char *message)
Definition: utility.cpp:360
FILE * m_file
Definition: utility.h:223