File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / smartmontools / utility.h
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 01:17:36 2013 UTC (10 years, 10 months ago) by misho
Branches: smartmontools, elwix, MAIN
CVS tags: v6_2, v6_1p0, v6_1, HEAD
6.1

    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-12 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,v 1.1.1.3 2013/07/22 01:17:36 misho Exp $"
   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, ...)
   53:     __attribute_format_printf(1, 2);
   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, ...)
   66:     __attribute_format_printf(3, 4);
   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, ...)  
   90:     __attribute_format_printf(1, 2);
   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>