Main Page | Data Structures | File List | Globals

include/gu.h

Go to the documentation of this file.
00001 /*
00002 ** mouse:~ppr/src/include/gu.h
00003 ** Copyright 1995--2004, Trinity College Computing Center.
00004 ** Written by David Chappell.
00005 **
00006 ** Redistribution and use in source and binary forms, with or without
00007 ** modification, are permitted provided that the following conditions are met:
00008 **
00009 ** * Redistributions of source code must retain the above copyright notice,
00010 ** this list of conditions and the following disclaimer.
00011 **
00012 ** * Redistributions in binary form must reproduce the above copyright
00013 ** notice, this list of conditions and the following disclaimer in the
00014 ** documentation and/or other materials provided with the distribution.
00015 **
00016 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
00020 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026 ** POSSIBILITY OF SUCH DAMAGE.
00027 **
00028 ** Last modified 11 February 2004.
00029 */
00030 
00039 #ifndef _GU_H
00040 #define _GU_H 1
00041 
00042 #include <stdio.h>
00043 #include <sys/types.h>
00044 #include <sys/stat.h>
00045 #include <stdarg.h>
00046 #include <setjmp.h>
00047 
00048 /*===================================================================
00049 ** Useful macros
00050 ===================================================================*/
00051 
00052 /* Define a portable boolean type. */
00053 typedef int gu_boolean;
00054 
00055 /* define constants for true and false. */
00056 #ifndef FALSE
00057 #define FALSE 0
00058 #endif
00059 #ifndef TRUE
00060 #define TRUE !FALSE
00061 #endif
00062 
00063 /*
00064 ** Define unix permissions 755 and 644.  We do this because just
00065 ** saying 0755 or 644 is at least theoretically non-portable and
00066 ** because these portable expressions are long and unsightly.
00067 */
00068 #define UNIX_755 (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
00069 #define UNIX_644 (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
00070 #define UNIX_660 (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
00071 #define UNIX_640 (S_IRUSR | S_IWUSR | S_IRGRP)
00072 #define UNIX_600 (S_IRUSR | S_IWUSR)
00073 #define UNIX_022 (S_IWGRP | S_IWOTH)
00074 #define UNIX_002 S_IWOTH
00075 #define UNIX_077 (S_IRWXG | S_IRWXO)
00076 
00077 /*
00078 ** Macros for looking for keywords at the start of strings.
00079 */
00080 
00082 #define lmatch(a, b) (!strncmp(a, b, sizeof(b) - 1))
00083 
00085 #define lmatchp(a, b) (!strncmp(a, b, sizeof(b) - 1) ? a + sizeof(b) - 1 + strspn(a + sizeof(b) - 1, " \t") : NULL)
00086 
00088 #define rmatch(a, b) (strlen(a) >= strlen(b) && strcmp(a + strlen(a) - strlen(b), b) == 0)
00089 
00092 #define lmatchsp(a, b) (!strncmp(a, b, sizeof(b) - 1) && isspace(a[sizeof(b) - 1]) ? a + sizeof(b) - 1 + strspn(a + sizeof(b) - 1, " \t") : NULL)
00093 
00095 #define gu_write_string(fd, s) (write(fd, s, sizeof(s) - 1))
00096 
00097 /*===================================================================
00098 ** Memory allocation routines
00099 ===================================================================*/
00100 
00101 /* Actual allocation functions */
00102 void *gu_alloc(size_t number, size_t size);
00103 void *gu_realloc(void *ptr, size_t number, size_t size);
00104 char *gu_strdup(const char *string);
00105 char *gu_strndup(const char *string, size_t len);
00106 char *gu_restrdup(char *ptr, size_t *number, const char *string);
00107 void gu_free(void *ptr);
00108 
00109 /* Debugging functions */
00110 void gu_alloc_checkpoint(void);
00111 int gu_alloc_checkpoint_get(void);
00112 void gu_alloc_checkpoint_put(int n);
00113 void _gu_alloc_assert(const char *file, int line, int assertion);
00114 #define gu_alloc_assert(assertion) _gu_alloc_assert(__FILE__, __LINE__, assertion)
00115 
00116 /*===================================================================
00117 ** The gu_ini_ routines read files in a format inspired by Microsoft
00118 ** Windows .ini files and Samba's smb.conf file.
00119 ===================================================================*/
00120 
00121 struct GU_INI_ENTRY
00122         {
00123         char *name;                     /* left hand side (not const so we can free) */
00124         const char *values; /* list from right hand side (const so we can't free) */
00125         int nvalues;            /* number of members in right hand side list */
00126         } ;
00127 
00128 
00129 enum GU_INI_TYPES {
00130         GU_INI_TYPE_SKIP,
00131         GU_INI_TYPE_NONNEG_INT,
00132         GU_INI_TYPE_STRING,
00133         GU_INI_TYPE_NONEMPTY_STRING,
00134         GU_INI_TYPE_POSITIVE_DOUBLE,
00135         GU_INI_TYPE_NONNEG_DOUBLE,
00136         GU_INI_TYPE_END
00137         } ;
00138 
00139 struct GU_INI_ENTRY *gu_ini_section_load(FILE *file, const char section_name[]);
00140 const struct GU_INI_ENTRY *gu_ini_section_get_value(const struct GU_INI_ENTRY *section, const char key_name[]);
00141 void gu_ini_section_free(struct GU_INI_ENTRY *section);
00142 const char *gu_ini_value_index(const struct GU_INI_ENTRY *array, int array_index, const char *default_value);
00143 int gu_ini_assign(const struct GU_INI_ENTRY *array, ...);
00144 int gu_ini_vassign(const struct GU_INI_ENTRY *array, va_list args);
00145 const char *gu_ini_scan_list(const char file_name[], const char section_name[], const char key_name[], ...);
00146 char *gu_ini_query(const char file_name[], const char section_name[], const char key_name[], int index, const char default_value[]);
00147 int gu_ini_section_from_sample(const char filename[], const char section_name[]);
00148 
00149 /*===================================================================
00150 ** Other stuff
00151 ===================================================================*/
00152 
00153 char *gu_getline(char *line, int *space_available, FILE *fstream);
00154 char *gu_strerror(int n);
00155 int gu_wildmat(const char *text, const char *p);
00156 int compile_string_escapes(char *s);
00157 char *gu_strsep(char **stringp, const char *delim);
00158 char *gu_strsep_quoted(char **stringp, const char *delim, const char *discard);
00159 void gu_set_cloexec(int fd);
00160 void gu_nonblock(int fd, gu_boolean on);
00161 void gu_trim_whitespace_right(char *s);
00162 int gu_strcasecmp(const char *s1, const char *s2);
00163 int gu_strncasecmp(const char *s1, const char *s2, int n);
00164 int gu_lock_exclusive(int filenum, int waitmode);
00165 int gu_torf(const char *s);
00166 int gu_torf_setBOOL(gu_boolean *b, const char *s);
00167 double gu_getdouble(const char *);
00168 const char *gu_dtostr(double);
00169 void ASCIIZ_to_padded(char *padded, const char *asciiz, int len);
00170 void padded_to_ASCIIZ(char *asciiz, const char *padded, int len);
00171 gu_boolean padded_cmp(const char *padded1, const char *padded2, int len);
00172 gu_boolean padded_icmp(const char *padded1, const char *padded2, int len);
00173 int gu_sscanf(const char *input, const char *pattern, ...);
00174 void gu_sscanf_checkpoint(void);
00175 void gu_sscanf_rollback(void);
00176 int gu_fscanf(FILE *input, const char *format, ...);
00177 void gu_daemon(mode_t daemon_umask);
00178 int disk_space(const char *path, unsigned int *free_blocks, unsigned int *free_files);
00179 void gu_wordwrap(char *string, int width);
00180 void (*signal_interupting(int signum, void (*handler)(int sig)))(int);
00181 void (*signal_restarting(int signum, void (*handler)(int sig)))(int);
00182 int gu_vsnprintf (char *str, size_t count, const char *fmt, va_list args);
00183 int gu_snprintf(char *str, size_t count, const char *fmt, ...);
00184 int gu_vasprintf(char **ptr, const char *format, va_list ap);
00185 int gu_asprintf(char **ptr, const char *format, ...);
00186 size_t gu_strlcpy(char *dst, const char *src, size_t siz);
00187 size_t gu_strlcat(char *dst, const char *src, size_t siz);
00188 int gu_mkstemp(char *template);
00189 char *gu_strsignal(int signum);
00190 int gu_snprintfcat(char *buffer, size_t max, const char *format, ...);
00191 int gu_timeval_cmp(const struct timeval *t1, const struct timeval *t2);
00192 void gu_timeval_sub(struct timeval *t1, const struct timeval *t2);
00193 void gu_timeval_add(struct timeval *t1, const struct timeval *t2);
00194 void gu_timeval_cpy(struct timeval *t1, const struct timeval *t2);
00195 void gu_timeval_zero(struct timeval *t);
00196 int gu_runl(const char *myname, FILE *errors, const char *progname, ...);
00197 
00198 /*
00199 ** Values for gu_torf(), a function which examines a string
00200 ** and tries to determine whether it represents a true or
00201 ** a false value.
00202 **
00203 ** These are obsolete.  Change uses of gu_torf() to gu_torf_setBOOL().
00204 */
00205 #define ANSWER int
00206 #define ANSWER_UNKNOWN -1
00207 #define ANSWER_FALSE 0
00208 #define ANSWER_TRUE 1
00209 
00210 /*===================================================================
00211 ** Command line option parsing
00212 ===================================================================*/
00213 
00214 struct gu_getopt_opt
00215                 {
00216                 const char *name;
00217                 int code;
00218                 gu_boolean needsarg;
00219                 } ;
00220 
00221 struct gu_getopt_state
00222                 {
00223                 int argc;                                                                               /* private */
00224                 char **argv;                                                                    /* private */
00225                 const char *opt_chars;                                                  /* private */
00226                 const struct gu_getopt_opt *opt_words;                  /* private */
00227                 int optind;                                                                             /* public */
00228                 char *optarg;                                                                   /* public */
00229                 const char *name;                                                               /* public */
00230                 int x;                                                                                  /* very private */
00231                 int len;                                                                                /* very private */
00232                 char scratch[3];                                                                /* very private */
00233                 char *putback;
00234                 } ;
00235 
00236 void gu_getopt_init(struct gu_getopt_state *state, int argc, char **argv, const char *opt_chars, const struct gu_getopt_opt *opt_words);
00237 int ppr_getopt(struct gu_getopt_state *state);
00238 void gu_getopt_default(const char myname[], int optchar, const struct gu_getopt_state *getopt_state, FILE *errors);
00239 
00240 /*===================================================================
00241 ** Parse space separated name=value pairs
00242 ===================================================================*/
00243 
00244 struct OPTIONS_STATE {
00245         int magic;                                                      /* should be 689 */
00246 
00247         const char *options;                            /* the string we are working on */
00248 
00249         int index;                                                      /* index of where we are working now */
00250         int index_of_name;                                      /* index of start of this name=value pair */
00251         int index_of_prev_name;                         /* index of start of prev pair */
00252 
00253         const char *error;                                      /* an error message */
00254 
00255         int next_time_skip;                                     /* distance from index to start of next name */
00256         };
00257 
00258 void options_start(const char *options_str, struct OPTIONS_STATE *o);
00259 int options_get_one(struct OPTIONS_STATE *o, char *name, int maxnamelen, char *value, int maxvaluelen);
00260 
00261 /*===================================================================
00262 ** Exception handling code
00263 **
00264 ** Here is the pattern:
00265 **
00266 **      char *p = gu_strdup("hello");
00267 **      gu_Try
00268 **              {
00269 **              gu_Throw("error 5");
00270 **              }
00271 **      gu_Final
00272 **              {
00273 **              gu_free(p);
00274 **              }
00275 **      gu_Catch
00276 **              {
00277 **              fprintf(stderr, "I caught error \"%s\", ouch!\n", gu_exception);
00278 **              }
00279 **
00280 ===================================================================*/
00281 
00282 extern char gu_exception[];                                     /* text of exception message */
00283 extern int  gu_exception_code;                          /* machine readable message */
00284 extern int  gu_exception_try_depth;                     /* how deap are we? */
00285 extern int  gu_exception_temp;
00286 extern int  gu_exception_debug;
00287 
00295 #define gu_Try { \
00296         jmp_buf gu_exception_jmp_buf; \
00297         int gu_exception_setjmp_retcode; \
00298         int gu_exception_pop = 1; \
00299         gu_Try_funct(&gu_exception_jmp_buf); \
00300         if((gu_exception_setjmp_retcode = setjmp(gu_exception_jmp_buf)) == 0)
00301         
00302 void gu_Try_funct(jmp_buf *p_jmp_buf);
00303 
00304 /* This function calls longjmp() if there is a gu_Try() context, otherwise
00305    it prints the message on stderr and calls exit(255).
00306    */
00307 void gu_Throw(const char message[], ...)
00308 #ifdef __GNUC__
00309 __attribute__ (( noreturn, format (printf, 1, 2) ))
00310 #endif
00311 ;
00312 void gu_CodeThrow(int code, const char message[], ...)
00313 #ifdef __GNUC__
00314 __attribute__ (( noreturn, format (printf, 2, 3) ))
00315 #endif
00316 ;
00317 
00318 /* This function throws a new exception using the exception message string
00319    stored by the last call to gu_Throw().
00320    */
00321 void gu_ReThrow(void)
00322 #ifdef __GNUC__
00323 __attribute__ (( noreturn ))
00324 #endif
00325 ;
00326 
00341 #define gu_Final \
00342 gu_exception_try_depth--; \
00343 gu_exception_pop = 0; \
00344 if(1)
00345 
00352 #define gu_Catch \
00353         gu_exception_try_depth -= gu_exception_pop; \
00354         gu_exception_temp = gu_exception_setjmp_retcode; \
00355         } \
00356 if(gu_exception_temp != 0)
00357 
00358 /*===================================================================
00359 ** SNMP functions
00360 ===================================================================*/
00361 
00363 struct gu_snmp
00364         {
00365         int socket;
00366         const char *community;
00367         unsigned int request_id;
00368         char result[1024];
00369         int result_len;
00370         };
00371 
00372 struct gu_snmp *gu_snmp_open(unsigned long int ip_address, const char community[]);
00373 void gu_snmp_close(struct gu_snmp *p);
00374 void gu_snmp_get(struct gu_snmp *p, ...);
00375 
00376 #define GU_SNMP_INT 1           
00377 #define GU_SNMP_STR 2           
00378 #define GU_SNMP_BIT 3           
00380 /*===================================================================
00381 ** Perl Compatibility Functions
00382 ===================================================================*/
00383 
00384 /* Perl Compatible String */
00385 void *gu_pcs_new(void);
00386 void *gu_pcs_new_pcs(void **pcs);
00387 void *gu_pcs_new_cstr(const char cstr[]);
00388 void gu_pcs_free(void **pcs);
00389 char *gu_pcs_free_keep_cstr(void **pcs);
00390 void gu_pcs_debug(void **pcs, const char name[]);
00391 void *gu_pcs_snapshot(void **pcs);
00392 void gu_pcs_grow(void **pcs, int size);
00393 void gu_pcs_set_cstr(void **pcs, const char cstr[]);
00394 void gu_pcs_set_pcs(void **pcs, void **pcs2);
00395 const char *gu_pcs_get_cstr(void **pcs);
00396 char *gu_pcs_get_editable_cstr(void **pcs);
00397 int gu_pcs_length(void **pcs);
00398 int gu_pcs_truncate(void **pcs, size_t newlen);
00399 void gu_pcs_append_char(void **pcs, int c);
00400 void gu_pcs_append_cstr(void **pcs, const char cstr[]);
00401 void gu_pcs_append_pcs(void **pcs, void **pcs2);
00402 int gu_pcs_cmp(void **pcs1, void **pcs2);
00403 int gu_pcs_hash(void **pcs_key);
00404 
00405 /*===================================================================
00406 ** Replacements for missing functions
00407 ** Leave this last in the file.
00408 ===================================================================*/
00409 
00410 #ifndef HAVE_STRSIGNAL
00411 #define strsignal(signum) gu_strsignal(signum)
00412 #endif
00413 #ifndef HAVE_SNPRINTF
00414 #define snprintf gu_snprintf
00415 #endif
00416 #ifndef HAVE_VSNPRINTF
00417 #define vsnprintf(s, n, format, ap) gu_vsnprintf(s, n, format, ap)
00418 #endif
00419 #ifndef HAVE_MKSTEMP
00420 #define mkstemp(template) gu_mkstemp(template)
00421 #endif
00422 #ifndef HAVE_STRLCPY
00423 #define strlcpy(a,b,c) gu_strlcpy(a,b,c)
00424 #endif
00425 #ifndef HAVE_STRLCAT
00426 #define strlcat(a,b,c) gu_strlcat(a,b,c)
00427 #endif
00428 #if 1
00429 #define strerror(err) gu_strerror(err)
00430 #endif
00431 
00432 #endif  /* _LIBGU */
00433 
00434 /* end of file */

Generated on Fri Feb 20 15:17:46 2004 for PPR Libraries by doxygen 1.3.5