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

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>
        !             7:  * Copyright (C) 2008-11 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, write to the Free
        !            17:  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            18:  *
        !            19:  * This code was originally developed as a Senior Thesis by Michael Cornwell
        !            20:  * at the Concurrent Systems Laboratory (now part of the Storage Systems
        !            21:  * Research Center), Jack Baskin School of Engineering, University of
        !            22:  * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
        !            23:  *
        !            24:  */
        !            25: 
        !            26: #ifndef UTILITY_H_
        !            27: #define UTILITY_H_
        !            28: 
        !            29: #define UTILITY_H_CVSID "$Id: utility.h 3305 2011-03-30 21:32:05Z chrfranke $"
        !            30: 
        !            31: #include <time.h>
        !            32: #include <sys/types.h> // for regex.h (according to POSIX)
        !            33: #include <regex.h>
        !            34: #include <stdarg.h>
        !            35: #include <stdio.h>
        !            36: #include <string.h>
        !            37: #include <string>
        !            38: 
        !            39: #if !defined(__GNUC__) && !defined(__attribute__)
        !            40: #define __attribute__(x)  /**/
        !            41: #endif
        !            42: 
        !            43: // Make version information string
        !            44: std::string format_version_info(const char * prog_name, bool full = false);
        !            45: 
        !            46: // return (v)sprintf() formated std::string
        !            47: std::string strprintf(const char * fmt, ...)
        !            48:     __attribute__ ((format (printf, 1, 2)));
        !            49: std::string vstrprintf(const char * fmt, va_list ap);
        !            50: 
        !            51: #ifndef HAVE_WORKING_SNPRINTF
        !            52: // Substitute by safe replacement functions
        !            53: int safe_snprintf(char *buf, int size, const char *fmt, ...)
        !            54:     __attribute__ ((format (printf, 3, 4)));
        !            55: int safe_vsnprintf(char *buf, int size, const char *fmt, va_list ap);
        !            56: #define snprintf  safe_snprintf
        !            57: #define vsnprintf safe_vsnprintf
        !            58: #endif
        !            59: 
        !            60: #ifndef HAVE_STRTOULL
        !            61: // Replacement for missing strtoull() (Linux with libc < 6, MSVC)
        !            62: uint64_t strtoull(const char * p, char * * endp, int base);
        !            63: #endif
        !            64: 
        !            65: // Utility function prints current date and time and timezone into a
        !            66: // character buffer of length>=64.  All the fuss is needed to get the
        !            67: // right timezone info (sigh).
        !            68: #define DATEANDEPOCHLEN 64
        !            69: void dateandtimezone(char *buffer);
        !            70: // Same, but for time defined by epoch tval
        !            71: void dateandtimezoneepoch(char *buffer, time_t tval);
        !            72: 
        !            73: // like printf() except that we can control it better. Note --
        !            74: // although the prototype is given here in utility.h, the function
        !            75: // itself is defined differently in smartctl and smartd.  So the
        !            76: // function definition(s) are in smartd.c and in smartctl.c.
        !            77: void pout(const char *fmt, ...)  
        !            78:      __attribute__ ((format (printf, 1, 2)));
        !            79: 
        !            80: // replacement for perror() with redirected output.
        !            81: void syserror(const char *message);
        !            82: 
        !            83: // Function for processing -r option in smartctl and smartd
        !            84: int split_report_arg(char *s, int *i);
        !            85: // Function for processing -c option in smartctl and smartd
        !            86: int split_report_arg2(char *s, int *i);
        !            87: 
        !            88: // Function for processing -t selective... option in smartctl
        !            89: int split_selective_arg(char *s, uint64_t *start, uint64_t *stop, int *mode);
        !            90: 
        !            91: 
        !            92: // Guess device type (ata or scsi) based on device name 
        !            93: // Guessing will now use Controller Type defines below
        !            94: 
        !            95: // Moved to C++ interface
        !            96: //int guess_device_type(const char * dev_name);
        !            97: 
        !            98: // Create and return the list of devices to probe automatically
        !            99: // if the DEVICESCAN option is in the smartd config file
        !           100: // Moved to C++ interface
        !           101: //int make_device_names (char ***devlist, const char* name);
        !           102: 
        !           103: // Replacement for exit(status)
        !           104: // (exit is not compatible with C++ destructors)
        !           105: #define EXIT(status) { throw (int)(status); }
        !           106: 
        !           107: 
        !           108: #ifdef OLD_INTERFACE
        !           109: 
        !           110: // replacement for calloc() that tracks memory usage
        !           111: void *Calloc(size_t nmemb, size_t size);
        !           112: 
        !           113: // Utility function to free memory
        !           114: void *FreeNonZero1(void* address, int size, int whatline, const char* file);
        !           115: 
        !           116: // Typesafe version of above
        !           117: template <class T>
        !           118: inline T * FreeNonZero(T * address, int size, int whatline, const char* file)
        !           119:   { return (T *)FreeNonZero1((void *)address, size, whatline, file); }
        !           120: 
        !           121: // A custom version of strdup() that keeps track of how much memory is
        !           122: // being allocated. If mustexist is set, it also throws an error if we
        !           123: // try to duplicate a NULL string.
        !           124: char *CustomStrDup(const char *ptr, int mustexist, int whatline, const char* file);
        !           125: 
        !           126: // To help with memory checking.  Use when it is known that address is
        !           127: // NOT null.
        !           128: void *CheckFree1(void *address, int whatline, const char* file);
        !           129: 
        !           130: // Typesafe version of above
        !           131: template <class T>
        !           132: inline T * CheckFree(T * address, int whatline, const char* file)
        !           133:   { return (T *)CheckFree1((void *)address, whatline, file); }
        !           134: 
        !           135: #endif // OLD_INTERFACE
        !           136: 
        !           137: // Compile time check of byte ordering
        !           138: // (inline const function allows compiler to remove dead code)
        !           139: inline bool isbigendian()
        !           140: {
        !           141: #ifdef WORDS_BIGENDIAN
        !           142:   return true;
        !           143: #else
        !           144:   return false;
        !           145: #endif
        !           146: }
        !           147: 
        !           148: // Runtime check of byte ordering, throws if different from isbigendian().
        !           149: void check_endianness();
        !           150: 
        !           151: // This value follows the peripheral device type value as defined in
        !           152: // SCSI Primary Commands, ANSI INCITS 301:1997.  It is also used in
        !           153: // the ATA standard for packet devices to define the device type.
        !           154: const char *packetdevicetype(int type);
        !           155: 
        !           156: // Moved to C++ interface
        !           157: //int deviceopen(const char *pathname, char *type);
        !           158: 
        !           159: //int deviceclose(int fd);
        !           160: 
        !           161: // Optional functions of os_*.c
        !           162: #ifdef HAVE_GET_OS_VERSION_STR
        !           163: // Return build host and OS version as static string
        !           164: //const char * get_os_version_str(void);
        !           165: #endif
        !           166: 
        !           167: // returns true if any of the n bytes are nonzero, else zero.
        !           168: bool nonempty(const void * data, int size);
        !           169: 
        !           170: // needed to fix glibc bug
        !           171: void FixGlibcTimeZoneBug();
        !           172: 
        !           173: // convert time in msec to a text string
        !           174: void MsecToText(unsigned int msec, char *txt);
        !           175: 
        !           176: // Format integer with thousands separator
        !           177: const char * format_with_thousands_sep(char * str, int strsize, uint64_t val,
        !           178:                                        const char * thousands_sep = 0);
        !           179: 
        !           180: // Format capacity with SI prefixes
        !           181: const char * format_capacity(char * str, int strsize, uint64_t val,
        !           182:                              const char * decimal_point = 0);
        !           183: 
        !           184: // Wrapper class for a raw data buffer
        !           185: class raw_buffer
        !           186: {
        !           187: public:
        !           188:   explicit raw_buffer(unsigned sz, unsigned char val = 0)
        !           189:     : m_data(new unsigned char[sz]),
        !           190:       m_size(sz)
        !           191:     { memset(m_data, val, m_size); }
        !           192: 
        !           193:   ~raw_buffer()
        !           194:     { delete [] m_data; }
        !           195: 
        !           196:   unsigned size() const
        !           197:     { return m_size; }
        !           198: 
        !           199:   unsigned char * data()
        !           200:     { return m_data; }
        !           201:   const unsigned char * data() const
        !           202:     { return m_data; }
        !           203: 
        !           204: private:
        !           205:   unsigned char * m_data;
        !           206:   unsigned m_size;
        !           207: 
        !           208:   raw_buffer(const raw_buffer &);
        !           209:   void operator=(const raw_buffer &);
        !           210: };
        !           211: 
        !           212: /// Wrapper class for FILE *.
        !           213: class stdio_file
        !           214: {
        !           215: public:
        !           216:   explicit stdio_file(FILE * f = 0, bool owner = false)
        !           217:     : m_file(f), m_owner(owner) { }
        !           218: 
        !           219:   stdio_file(const char * name, const char * mode)
        !           220:     : m_file(fopen(name, mode)), m_owner(true) { }
        !           221: 
        !           222:   ~stdio_file()
        !           223:     {
        !           224:       if (m_file && m_owner)
        !           225:         fclose(m_file);
        !           226:     }
        !           227: 
        !           228:   bool open(const char * name, const char * mode)
        !           229:     {
        !           230:       m_file = fopen(name, mode);
        !           231:       m_owner = true;
        !           232:       return !!m_file;
        !           233:     }
        !           234: 
        !           235:   void open(FILE * f, bool owner = false)
        !           236:     {
        !           237:       m_file = f;
        !           238:       m_owner = owner;
        !           239:     }
        !           240: 
        !           241:   bool close()
        !           242:     {
        !           243:       if (!m_file)
        !           244:         return true;
        !           245:       bool ok = !ferror(m_file);
        !           246:       if (fclose(m_file))
        !           247:         ok = false;
        !           248:       m_file = 0;
        !           249:       return ok;
        !           250:     }
        !           251: 
        !           252:   operator FILE * ()
        !           253:     { return m_file; }
        !           254: 
        !           255:   bool operator!() const
        !           256:     { return !m_file; }
        !           257: 
        !           258: private:
        !           259:   FILE * m_file;
        !           260:   bool m_owner;
        !           261: 
        !           262:   stdio_file(const stdio_file &);
        !           263:   void operator=(const stdio_file &);
        !           264: };
        !           265: 
        !           266: /// Wrapper class for regex(3).
        !           267: /// Supports copy & assignment and is compatible with STL containers.
        !           268: class regular_expression
        !           269: {
        !           270: public:
        !           271:   // Construction & assignment
        !           272:   regular_expression();
        !           273: 
        !           274:   regular_expression(const char * pattern, int flags,
        !           275:                      bool throw_on_error = true);
        !           276: 
        !           277:   ~regular_expression();
        !           278: 
        !           279:   regular_expression(const regular_expression & x);
        !           280: 
        !           281:   regular_expression & operator=(const regular_expression & x);
        !           282: 
        !           283:   /// Set and compile new pattern, return false on error.
        !           284:   bool compile(const char * pattern, int flags);
        !           285: 
        !           286:   // Get pattern from last compile().
        !           287:   const char * get_pattern() const
        !           288:     { return m_pattern.c_str(); }
        !           289: 
        !           290:   /// Get error message from last compile().
        !           291:   const char * get_errmsg() const
        !           292:     { return m_errmsg.c_str(); }
        !           293: 
        !           294:   // Return true if pattern is not set or bad.
        !           295:   bool empty() const
        !           296:     { return (m_pattern.empty() || !m_errmsg.empty()); }
        !           297: 
        !           298:   /// Return true if substring matches pattern
        !           299:   bool match(const char * str, int flags = 0) const
        !           300:     { return !regexec(&m_regex_buf, str, 0, (regmatch_t*)0, flags); }
        !           301: 
        !           302:   /// Return true if full string matches pattern
        !           303:   bool full_match(const char * str, int flags = 0) const
        !           304:     {
        !           305:       regmatch_t range;
        !           306:       return (   !regexec(&m_regex_buf, str, 1, &range, flags)
        !           307:               && range.rm_so == 0 && range.rm_eo == (int)strlen(str));
        !           308:     }
        !           309: 
        !           310:   /// Return true if substring matches pattern, fill regmatch_t array.
        !           311:   bool execute(const char * str, unsigned nmatch, regmatch_t * pmatch, int flags = 0) const
        !           312:     { return !regexec(&m_regex_buf, str, nmatch, pmatch, flags); }
        !           313: 
        !           314: private:
        !           315:   std::string m_pattern;
        !           316:   int m_flags;
        !           317:   regex_t m_regex_buf;
        !           318:   std::string m_errmsg;
        !           319: 
        !           320:   void free_buf();
        !           321:   void copy(const regular_expression & x);
        !           322:   bool compile();
        !           323: };
        !           324: 
        !           325: #ifdef _WIN32
        !           326: // Get exe directory
        !           327: //(implemented in os_win32.cpp)
        !           328: std::string get_exe_dir();
        !           329: #endif
        !           330: 
        !           331: 
        !           332: #ifdef OLD_INTERFACE
        !           333: // remaining controller types in old interface modules
        !           334: #define CONTROLLER_UNKNOWN              0x00
        !           335: #define CONTROLLER_ATA                  0x01
        !           336: #define CONTROLLER_SCSI                 0x02
        !           337: #endif
        !           338: 
        !           339: #endif
        !           340: 

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