X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=utility.h;h=bd56a24933aae4efd55ca2bdf522714d0dbcd874;hb=413ace18d106fef69fa96d53831eebd600c9f157;hp=3ad6912f6da85549d88ed54cd61886cc7c8ded81;hpb=14d338df5c9f4d5b53258ad87b3c9159820a9a64;p=mirror_smartmontools-debian.git diff --git a/utility.h b/utility.h index 3ad6912..bd56a24 100644 --- a/utility.h +++ b/utility.h @@ -1,10 +1,10 @@ /* * utility.h * - * Home page of code is: http://smartmontools.sourceforge.net + * Home page of code is: http://www.smartmontools.org * - * Copyright (C) 2002-10 Bruce Allen - * Copyright (C) 2008-10 Christian Franke + * Copyright (C) 2002-11 Bruce Allen + * Copyright (C) 2008-16 Christian Franke * Copyright (C) 2000 Michael Cornwell * * This program is free software; you can redistribute it and/or modify @@ -13,8 +13,7 @@ * any later version. * * You should have received a copy of the GNU General Public License - * (for example COPYING); if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * (for example COPYING); If not, see . * * This code was originally developed as a Senior Thesis by Michael Cornwell * at the Concurrent Systems Laboratory (now part of the Storage Systems @@ -26,7 +25,7 @@ #ifndef UTILITY_H_ #define UTILITY_H_ -#define UTILITY_H_CVSID "$Id: utility.h 3093 2010-04-30 09:57:36Z chrfranke $" +#define UTILITY_H_CVSID "$Id: utility.h 4309 2016-04-24 14:59:15Z chrfranke $" #include #include // for regex.h (according to POSIX) @@ -36,8 +35,14 @@ #include #include -#if !defined(__GNUC__) && !defined(__attribute__) -#define __attribute__(x) /**/ +#ifndef __GNUC__ +#define __attribute_format_printf(x, y) /**/ +#elif defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO +// Check format of __mingw_*printf() instead of MSVCRT.DLL:*printf() +#define __attribute_format_printf(x, y) __attribute__((format (gnu_printf, x, y))) +#define HAVE_WORKING_SNPRINTF 1 +#else +#define __attribute_format_printf(x, y) __attribute__((format (printf, x, y))) #endif // Make version information string @@ -45,13 +50,20 @@ std::string format_version_info(const char * prog_name, bool full = false); // return (v)sprintf() formated std::string std::string strprintf(const char * fmt, ...) - __attribute__ ((format (printf, 1, 2))); + __attribute_format_printf(1, 2); std::string vstrprintf(const char * fmt, va_list ap); +// Return true if STR starts with PREFIX +inline bool str_starts_with(const char * str, const char * prefix) + { return !strncmp(str, prefix, strlen(prefix)); } + +inline bool str_starts_with(const std::string & str, const char * prefix) + { return !strncmp(str.c_str(), prefix, strlen(prefix)); } + #ifndef HAVE_WORKING_SNPRINTF // Substitute by safe replacement functions int safe_snprintf(char *buf, int size, const char *fmt, ...) - __attribute__ ((format (printf, 3, 4))); + __attribute_format_printf(3, 4); int safe_vsnprintf(char *buf, int size, const char *fmt, va_list ap); #define snprintf safe_snprintf #define vsnprintf safe_vsnprintf @@ -75,75 +87,18 @@ void dateandtimezoneepoch(char *buffer, time_t tval); // itself is defined differently in smartctl and smartd. So the // function definition(s) are in smartd.c and in smartctl.c. void pout(const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); + __attribute_format_printf(1, 2); // replacement for perror() with redirected output. void syserror(const char *message); -// Function for processing -r option in smartctl and smartd -int split_report_arg(char *s, int *i); -// Function for processing -c option in smartctl and smartd -int split_report_arg2(char *s, int *i); - // Function for processing -t selective... option in smartctl int split_selective_arg(char *s, uint64_t *start, uint64_t *stop, int *mode); - -// Guess device type (ata or scsi) based on device name -// Guessing will now use Controller Type defines below - -// Moved to C++ interface -//int guess_device_type(const char * dev_name); - -// Create and return the list of devices to probe automatically -// if the DEVICESCAN option is in the smartd config file -// Moved to C++ interface -//int make_device_names (char ***devlist, const char* name); - // Replacement for exit(status) // (exit is not compatible with C++ destructors) #define EXIT(status) { throw (int)(status); } - -#ifdef OLD_INTERFACE - -// replacement for calloc() that tracks memory usage -void *Calloc(size_t nmemb, size_t size); - -// Utility function to free memory -void *FreeNonZero1(void* address, int size, int whatline, const char* file); - -// Typesafe version of above -template -inline T * FreeNonZero(T * address, int size, int whatline, const char* file) - { return (T *)FreeNonZero1((void *)address, size, whatline, file); } - -// A custom version of strdup() that keeps track of how much memory is -// being allocated. If mustexist is set, it also throws an error if we -// try to duplicate a NULL string. -char *CustomStrDup(const char *ptr, int mustexist, int whatline, const char* file); - -// To help with memory checking. Use when it is known that address is -// NOT null. -void *CheckFree1(void *address, int whatline, const char* file); - -// Typesafe version of above -template -inline T * CheckFree(T * address, int whatline, const char* file) - { return (T *)CheckFree1((void *)address, whatline, file); } - -#endif // OLD_INTERFACE - -// This function prints either to stdout or to the syslog as needed - -// [From GLIBC Manual: Since the prototype doesn't specify types for -// optional arguments, in a call to a variadic function the default -// argument promotions are performed on the optional argument -// values. This means the objects of type char or short int (whether -// signed or not) are promoted to either int or unsigned int, as -// appropriate.] -void PrintOut(int priority, const char *fmt, ...) __attribute__ ((format(printf, 2, 3))); - // Compile time check of byte ordering // (inline const function allows compiler to remove dead code) inline bool isbigendian() @@ -155,33 +110,36 @@ inline bool isbigendian() #endif } -// Runtime check of byte ordering, throws if different from isbigendian(). -void check_endianness(); +// Runtime check of ./configure result, throws on error. +void check_config(); // This value follows the peripheral device type value as defined in // SCSI Primary Commands, ANSI INCITS 301:1997. It is also used in // the ATA standard for packet devices to define the device type. const char *packetdevicetype(int type); -// Moved to C++ interface -//int deviceopen(const char *pathname, char *type); - -//int deviceclose(int fd); - -// Optional functions of os_*.c -#ifdef HAVE_GET_OS_VERSION_STR -// Return build host and OS version as static string -//const char * get_os_version_str(void); -#endif - // returns true if any of the n bytes are nonzero, else zero. bool nonempty(const void * data, int size); // needed to fix glibc bug void FixGlibcTimeZoneBug(); -// convert time in msec to a text string -void MsecToText(unsigned int msec, char *txt); +// Copy not null terminated char array to null terminated string. +// Replace non-ascii characters. Remove leading and trailing blanks. +const char * format_char_array(char * str, int strsize, const char * chr, int chrsize); + +// Version for fixed size buffers. +template +inline const char * format_char_array(char (& str)[STRSIZE], const char (& chr)[CHRSIZE]) + { return format_char_array(str, (int)STRSIZE, chr, (int)CHRSIZE); } + +// Format integer with thousands separator +const char * format_with_thousands_sep(char * str, int strsize, uint64_t val, + const char * thousands_sep = 0); + +// Format capacity with SI prefixes +const char * format_capacity(char * str, int strsize, uint64_t val, + const char * decimal_point = 0); // Wrapper class for a raw data buffer class raw_buffer @@ -229,6 +187,8 @@ public: bool open(const char * name, const char * mode) { + if (m_file && m_owner) + fclose(m_file); m_file = fopen(name, mode); m_owner = true; return !!m_file; @@ -236,6 +196,8 @@ public: void open(FILE * f, bool owner = false) { + if (m_file && m_owner) + fclose(m_file); m_file = f; m_owner = owner; } @@ -273,7 +235,8 @@ public: // Construction & assignment regular_expression(); - regular_expression(const char * pattern, int flags); + regular_expression(const char * pattern, int flags, + bool throw_on_error = true); ~regular_expression(); @@ -323,10 +286,6 @@ private: bool compile(); }; -// macros to control printing -#define PRINT_ON(control) {if (control->printing_switchable) control->dont_print=false;} -#define PRINT_OFF(control) {if (control->printing_switchable) control->dont_print=true;} - #ifdef _WIN32 // Get exe directory //(implemented in os_win32.cpp) @@ -335,21 +294,10 @@ std::string get_exe_dir(); #ifdef OLD_INTERFACE -// possible values for controller_type in extern.h +// remaining controller types in old interface modules #define CONTROLLER_UNKNOWN 0x00 #define CONTROLLER_ATA 0x01 #define CONTROLLER_SCSI 0x02 -#define CONTROLLER_3WARE 0x03 // set by -d option, but converted to one of three types below -#define CONTROLLER_3WARE_678K 0x04 // NOT set by guess_device_type() -#define CONTROLLER_3WARE_9000_CHAR 0x05 // set by guess_device_type() -#define CONTROLLER_3WARE_678K_CHAR 0x06 // set by guess_device_type() -#define CONTROLLER_MARVELL_SATA 0x07 // SATA drives behind Marvell controllers -#define CONTROLLER_SAT 0x08 // SATA device behind a SCSI ATA Translation (SAT) layer -#define CONTROLLER_HPT 0x09 // SATA drives behind HighPoint Raid controllers -#define CONTROLLER_CCISS 0x10 // CCISS controller -#define CONTROLLER_PARSEDEV 0x11 // "smartctl -r ataioctl,2 ..." output parser pseudo-device -#define CONTROLLER_USBCYPRESS 0x12 // ATA device behind Cypress USB bridge -#define CONTROLLER_ARECA 0x13 // Areca controller #endif #endif