TODO: figure out how to autodetect lib vs lib64. These changes were made some time ago (can't remember when) but didn't get committed until now. (Yes, naughty me, but perhaps I was in a rush.)
193 lines
6.1 KiB
C
193 lines
6.1 KiB
C
#ifndef _UTIL_H
|
|
#define _UTIL_H
|
|
|
|
#include <sys/types.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
|
|
/* Various utility functions for the gallery */
|
|
|
|
/* Memory management functions.
|
|
*
|
|
* These wrappers around malloc/calloc, realloc and free internally
|
|
* monitor the usage of memory chunks. It keeps track of all allocated
|
|
* pointers, allowing for garbage collection to occur at the end when
|
|
* all pointers should be unused.
|
|
*
|
|
* For performance, these can be disabled at compile time. Their prime focus is
|
|
* for development... to track where allocations are being made. It shouldn't
|
|
* be necessary in production -- if it is, there's a memory leakage bug.
|
|
*/
|
|
|
|
#ifdef MEMALLOC_TRACK
|
|
/* Memory allocation tracking enabled */
|
|
void* gcmalloc( size_t size );
|
|
void* gccalloc( size_t nmemb, size_t size );
|
|
void* gcrealloc( void* ptr, size_t size );
|
|
void gcfreeall();
|
|
char* gcstrdup( const char* str );
|
|
char* gcreport();
|
|
|
|
/* The pointers are tracked in this linked list */
|
|
struct mem_chunk {
|
|
void* ptr;
|
|
size_t size;
|
|
struct mem_chunk* prev;
|
|
struct mem_chunk* next;
|
|
};
|
|
static struct mem_chunk* gc_head = NULL;
|
|
static struct mem_chunk* gc_tail = NULL;
|
|
static size_t gc_count = 0;
|
|
#else
|
|
/* Memory allocation tracking disabled */
|
|
#define gcmalloc( size ) malloc( size )
|
|
#define gccalloc( size, num ) calloc( size, num )
|
|
#define gcrealloc( ptr, size ) realloc( ptr, size )
|
|
#define gcstrdup( size ) strdup( size )
|
|
#endif
|
|
void gcfree( void* ptr );
|
|
|
|
/* Sanitise a given name. Names may only contain alpha-numeric
|
|
* characters, hyphens, underscores and full stop characters.
|
|
*
|
|
* This function sanitises in-place, invalid characters get replaced with
|
|
* underscores.
|
|
*/
|
|
void sanitise_name( char* name );
|
|
|
|
/* Cross-compatibility hack */
|
|
#ifndef PATHSEP
|
|
# ifdef WIN32
|
|
# define PATHSEP "\\"
|
|
# else
|
|
# define PATHSEP "/"
|
|
# endif
|
|
#endif
|
|
|
|
/* Concatenate one string onto the end of the other.
|
|
*
|
|
* This function does a realloc of the first string to make room for the second,
|
|
* returning the pointer to the concatenated string.
|
|
*
|
|
* This is different to strcat, which does not re-allocate memory or make room
|
|
* in any way.
|
|
*/
|
|
char* str_concat( char* dest, const char* src );
|
|
|
|
/* Like above, but add a single character */
|
|
char* str_concatc( char* dest, const char c );
|
|
|
|
/* Construct a path from given directory names.
|
|
* fmt is a list of types and sizes interpreted as follows:
|
|
* s Insert a string at this point.
|
|
* i Insert a signed integer at this point.
|
|
* u Insert an unsigned integer at this point.
|
|
* x Insert a hexadecimal integer at this point
|
|
* o Insert an octal integer at this point
|
|
* f Insert a floating-point/double at this point.
|
|
* / Insert the path separator string at this point.
|
|
* \ Insert the next character verbatim
|
|
*
|
|
* Whitespace is ignored, so you can add spaces for readability. Digits
|
|
* are interpreted as the width of the field in characters. Anything else
|
|
* is passed through verbatim.
|
|
*
|
|
* Whitespace can be passed through by escaping it however.
|
|
*
|
|
* For float/double fields, a decimal point followed by digits indicates
|
|
* the number of decimal digits to include.
|
|
*
|
|
* Example:
|
|
* "s/s ? s=6.2f & s=u & s=u" might yield
|
|
* "humour/funnypic.jpg?rotation=000.00&width=600&height=400"
|
|
*/
|
|
char* construct_path( const char* format, ...);
|
|
|
|
/* construct_path field widths are limited to the following number of
|
|
* characters...
|
|
*/
|
|
#define CONSTRUCT_PATH_FIELD_WIDTH 64
|
|
|
|
/* Obtain the CGI filesystem directory */
|
|
const char* get_cgidir();
|
|
|
|
/* Obtain the CGI directory URI */
|
|
const char* get_cgiuri();
|
|
|
|
/* Local versions of dirname and basename. These allocate and return copies of
|
|
* the strings passed to them.
|
|
*/
|
|
char* get_basename( const char* path );
|
|
char* get_dirname( const char* path );
|
|
|
|
/* Substitute the extension on a filename.
|
|
*
|
|
* This function does a string substitution on the filename given to it, and
|
|
* returns it. Returns NULL if it can't allocate a buffer.
|
|
*/
|
|
char* substitute_ext( const char* filename, const char* new_ext );
|
|
|
|
/* Parse a text file. The text files in this system have the format:
|
|
* "<some variable>\t<value>\n"
|
|
*
|
|
* Multiple lines with the same variable are concatenated together.
|
|
*
|
|
* The content of these files is stored in a chained struct like the one below.
|
|
*/
|
|
struct txtinfo_chain {
|
|
char* field_name;
|
|
char* field_val;
|
|
struct txtinfo_chain* next;
|
|
};
|
|
|
|
/* Create a txtinfo_chain object */
|
|
struct txtinfo_chain* create_txtinfo_chain( const char* name, const char* val );
|
|
|
|
/* Destroy a txtinfo_chain object. This destroys all linked objects! */
|
|
void destroy_txtinfo_chain( struct txtinfo_chain* chain );
|
|
|
|
/* Locate a field in a field chain. Return NULL if it isn't present. */
|
|
struct txtinfo_chain* find_txtinfo_chain( struct txtinfo_chain* chain, const char* name );
|
|
|
|
/* Return the value for a given field name. This returns a copy of the string. */
|
|
char* get_txtinfo_chain_val( struct txtinfo_chain* chain, const char *name );
|
|
|
|
/* Read a file into a txtinfo_chain object. Returns NULL on failure. */
|
|
struct txtinfo_chain* read_txtinfo_chain( const char* file );
|
|
|
|
/* Write out a txtinfo_chain object. Returns 0 on success, errno on failure. */
|
|
int write_txtinfo_chain( const char* file, struct txtinfo_chain* chain );
|
|
|
|
/* Duplicate a structure in memory.
|
|
* This calls malloc to allocate a region of the specified size,
|
|
* then does a memcpy from the supplied address.
|
|
*
|
|
* Returns the copy on success, or NULL on failure.
|
|
*/
|
|
void* memdup( void* ptr, size_t length );
|
|
|
|
/* Sort a generic array
|
|
*
|
|
* This does an in-place sort of the objects contained in the array.
|
|
* Since there's no way of knowing how to sort the objects, a function
|
|
* for doing this must be supplied as a pointer.
|
|
*
|
|
* str_sort_array does the above sort with strings, setting case_insensitive
|
|
* will cause the sorting algorithm to ignore the case.
|
|
*/
|
|
void sort_str_array( char** array, size_t length, int case_insensitive );
|
|
void sort_array( void** array, size_t length,
|
|
int (*compare)( const void*, const void* ) );
|
|
|
|
/*!
|
|
* Pause if the server load is too high.
|
|
* This causes the CGI script to sleep for a second if the load average is
|
|
* above MAX_CPU_LOAD.
|
|
*/
|
|
void wait_cpu_load();
|
|
#ifndef MAX_CPU_LOAD
|
|
#define MAX_CPU_LOAD (2.0)
|
|
#endif
|
|
|
|
#endif
|