Annotation of embedaddon/smartmontools/utility.h, revision 1.1.1.3

1.1       misho       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>
1.1.1.2   misho       7:  * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
1.1       misho       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
1.1.1.3 ! misho      16:  * (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
1.1       misho      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: 
1.1.1.3 ! misho      28: #define UTILITY_H_CVSID "$Id: utility.h 3719 2012-12-03 21:19:33Z chrfranke $"
1.1       misho      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: 
1.1.1.2   misho      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)))
1.1       misho      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, ...)
1.1.1.2   misho      53:     __attribute_format_printf(1, 2);
1.1       misho      54: std::string vstrprintf(const char * fmt, va_list ap);
                     55: 
1.1.1.2   misho      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: 
1.1       misho      63: #ifndef HAVE_WORKING_SNPRINTF
                     64: // Substitute by safe replacement functions
                     65: int safe_snprintf(char *buf, int size, const char *fmt, ...)
1.1.1.2   misho      66:     __attribute_format_printf(3, 4);
1.1       misho      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, ...)  
1.1.1.2   misho      90:     __attribute_format_printf(1, 2);
1.1       misho      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: 
                    102: // Guess device type (ata or scsi) based on device name 
                    103: // Guessing will now use Controller Type defines below
                    104: 
                    105: // Moved to C++ interface
                    106: //int guess_device_type(const char * dev_name);
                    107: 
                    108: // Create and return the list of devices to probe automatically
                    109: // if the DEVICESCAN option is in the smartd config file
                    110: // Moved to C++ interface
                    111: //int make_device_names (char ***devlist, const char* name);
                    112: 
                    113: // Replacement for exit(status)
                    114: // (exit is not compatible with C++ destructors)
                    115: #define EXIT(status) { throw (int)(status); }
                    116: 
                    117: 
                    118: #ifdef OLD_INTERFACE
                    119: 
                    120: // replacement for calloc() that tracks memory usage
                    121: void *Calloc(size_t nmemb, size_t size);
                    122: 
                    123: // Utility function to free memory
                    124: void *FreeNonZero1(void* address, int size, int whatline, const char* file);
                    125: 
                    126: // Typesafe version of above
                    127: template <class T>
                    128: inline T * FreeNonZero(T * address, int size, int whatline, const char* file)
                    129:   { return (T *)FreeNonZero1((void *)address, size, whatline, file); }
                    130: 
                    131: // A custom version of strdup() that keeps track of how much memory is
                    132: // being allocated. If mustexist is set, it also throws an error if we
                    133: // try to duplicate a NULL string.
                    134: char *CustomStrDup(const char *ptr, int mustexist, int whatline, const char* file);
                    135: 
                    136: // To help with memory checking.  Use when it is known that address is
                    137: // NOT null.
                    138: void *CheckFree1(void *address, int whatline, const char* file);
                    139: 
                    140: // Typesafe version of above
                    141: template <class T>
                    142: inline T * CheckFree(T * address, int whatline, const char* file)
                    143:   { return (T *)CheckFree1((void *)address, whatline, file); }
                    144: 
                    145: #endif // OLD_INTERFACE
                    146: 
                    147: // Compile time check of byte ordering
                    148: // (inline const function allows compiler to remove dead code)
                    149: inline bool isbigendian()
                    150: {
                    151: #ifdef WORDS_BIGENDIAN
                    152:   return true;
                    153: #else
                    154:   return false;
                    155: #endif
                    156: }
                    157: 
                    158: // Runtime check of byte ordering, throws if different from isbigendian().
                    159: void check_endianness();
                    160: 
                    161: // This value follows the peripheral device type value as defined in
                    162: // SCSI Primary Commands, ANSI INCITS 301:1997.  It is also used in
                    163: // the ATA standard for packet devices to define the device type.
                    164: const char *packetdevicetype(int type);
                    165: 
                    166: // Moved to C++ interface
                    167: //int deviceopen(const char *pathname, char *type);
                    168: 
                    169: //int deviceclose(int fd);
                    170: 
                    171: // Optional functions of os_*.c
                    172: #ifdef HAVE_GET_OS_VERSION_STR
                    173: // Return build host and OS version as static string
                    174: //const char * get_os_version_str(void);
                    175: #endif
                    176: 
                    177: // returns true if any of the n bytes are nonzero, else zero.
                    178: bool nonempty(const void * data, int size);
                    179: 
                    180: // needed to fix glibc bug
                    181: void FixGlibcTimeZoneBug();
                    182: 
                    183: // Format integer with thousands separator
                    184: const char * format_with_thousands_sep(char * str, int strsize, uint64_t val,
                    185:                                        const char * thousands_sep = 0);
                    186: 
                    187: // Format capacity with SI prefixes
                    188: const char * format_capacity(char * str, int strsize, uint64_t val,
                    189:                              const char * decimal_point = 0);
                    190: 
                    191: // Wrapper class for a raw data buffer
                    192: class raw_buffer
                    193: {
                    194: public:
                    195:   explicit raw_buffer(unsigned sz, unsigned char val = 0)
                    196:     : m_data(new unsigned char[sz]),
                    197:       m_size(sz)
                    198:     { memset(m_data, val, m_size); }
                    199: 
                    200:   ~raw_buffer()
                    201:     { delete [] m_data; }
                    202: 
                    203:   unsigned size() const
                    204:     { return m_size; }
                    205: 
                    206:   unsigned char * data()
                    207:     { return m_data; }
                    208:   const unsigned char * data() const
                    209:     { return m_data; }
                    210: 
                    211: private:
                    212:   unsigned char * m_data;
                    213:   unsigned m_size;
                    214: 
                    215:   raw_buffer(const raw_buffer &);
                    216:   void operator=(const raw_buffer &);
                    217: };
                    218: 
                    219: /// Wrapper class for FILE *.
                    220: class stdio_file
                    221: {
                    222: public:
                    223:   explicit stdio_file(FILE * f = 0, bool owner = false)
                    224:     : m_file(f), m_owner(owner) { }
                    225: 
                    226:   stdio_file(const char * name, const char * mode)
                    227:     : m_file(fopen(name, mode)), m_owner(true) { }
                    228: 
                    229:   ~stdio_file()
                    230:     {
                    231:       if (m_file && m_owner)
                    232:         fclose(m_file);
                    233:     }
                    234: 
                    235:   bool open(const char * name, const char * mode)
                    236:     {
                    237:       m_file = fopen(name, mode);
                    238:       m_owner = true;
                    239:       return !!m_file;
                    240:     }
                    241: 
                    242:   void open(FILE * f, bool owner = false)
                    243:     {
                    244:       m_file = f;
                    245:       m_owner = owner;
                    246:     }
                    247: 
                    248:   bool close()
                    249:     {
                    250:       if (!m_file)
                    251:         return true;
                    252:       bool ok = !ferror(m_file);
                    253:       if (fclose(m_file))
                    254:         ok = false;
                    255:       m_file = 0;
                    256:       return ok;
                    257:     }
                    258: 
                    259:   operator FILE * ()
                    260:     { return m_file; }
                    261: 
                    262:   bool operator!() const
                    263:     { return !m_file; }
                    264: 
                    265: private:
                    266:   FILE * m_file;
                    267:   bool m_owner;
                    268: 
                    269:   stdio_file(const stdio_file &);
                    270:   void operator=(const stdio_file &);
                    271: };
                    272: 
                    273: /// Wrapper class for regex(3).
                    274: /// Supports copy & assignment and is compatible with STL containers.
                    275: class regular_expression
                    276: {
                    277: public:
                    278:   // Construction & assignment
                    279:   regular_expression();
                    280: 
                    281:   regular_expression(const char * pattern, int flags,
                    282:                      bool throw_on_error = true);
                    283: 
                    284:   ~regular_expression();
                    285: 
                    286:   regular_expression(const regular_expression & x);
                    287: 
                    288:   regular_expression & operator=(const regular_expression & x);
                    289: 
                    290:   /// Set and compile new pattern, return false on error.
                    291:   bool compile(const char * pattern, int flags);
                    292: 
                    293:   // Get pattern from last compile().
                    294:   const char * get_pattern() const
                    295:     { return m_pattern.c_str(); }
                    296: 
                    297:   /// Get error message from last compile().
                    298:   const char * get_errmsg() const
                    299:     { return m_errmsg.c_str(); }
                    300: 
                    301:   // Return true if pattern is not set or bad.
                    302:   bool empty() const
                    303:     { return (m_pattern.empty() || !m_errmsg.empty()); }
                    304: 
                    305:   /// Return true if substring matches pattern
                    306:   bool match(const char * str, int flags = 0) const
                    307:     { return !regexec(&m_regex_buf, str, 0, (regmatch_t*)0, flags); }
                    308: 
                    309:   /// Return true if full string matches pattern
                    310:   bool full_match(const char * str, int flags = 0) const
                    311:     {
                    312:       regmatch_t range;
                    313:       return (   !regexec(&m_regex_buf, str, 1, &range, flags)
                    314:               && range.rm_so == 0 && range.rm_eo == (int)strlen(str));
                    315:     }
                    316: 
                    317:   /// Return true if substring matches pattern, fill regmatch_t array.
                    318:   bool execute(const char * str, unsigned nmatch, regmatch_t * pmatch, int flags = 0) const
                    319:     { return !regexec(&m_regex_buf, str, nmatch, pmatch, flags); }
                    320: 
                    321: private:
                    322:   std::string m_pattern;
                    323:   int m_flags;
                    324:   regex_t m_regex_buf;
                    325:   std::string m_errmsg;
                    326: 
                    327:   void free_buf();
                    328:   void copy(const regular_expression & x);
                    329:   bool compile();
                    330: };
                    331: 
                    332: #ifdef _WIN32
                    333: // Get exe directory
                    334: //(implemented in os_win32.cpp)
                    335: std::string get_exe_dir();
                    336: #endif
                    337: 
                    338: 
                    339: #ifdef OLD_INTERFACE
                    340: // remaining controller types in old interface modules
                    341: #define CONTROLLER_UNKNOWN              0x00
                    342: #define CONTROLLER_ATA                  0x01
                    343: #define CONTROLLER_SCSI                 0x02
                    344: #endif
                    345: 
                    346: #endif
                    347: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>