1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
|
/**
\file util.h
\brief Header file for util.c. Contains all-purpose macros, types and function protos.
This header file contains all general macros, types/enums/structs declaration and functions
prototypes that are used as general tools.
*/
#ifndef _util_h_
#define _util_h_
#include <stdio.h>
#include <stdarg.h>
#include "config.h"
#define MIN(X,Y) ((X)>(Y)?(Y):(X))
#define MAX(X,Y) ((X)>(Y)?(X):(Y))
#ifndef ssize_t
#ifndef _GNU_SOURCE
#define ssize_t long int
#define _SSIZE_T
#endif
#endif
/* Mac OS X specific defines */
#ifdef OS_DARWIN
#include "gnu-getline.h"
#include "gnu-strndup.h"
#endif
/* QNX specific defines */
#ifdef OS_QNX
#include "gnu-getline.h"
#include "gnu-strndup.h"
#endif
/* BeOS specific defines */
#ifdef OS_BEOS
#include "gnu-strndup.h"
#endif
/* Sun Solaris (SunOS) specific defines */
#ifdef OS_SUNOS
#include "gnu-getline.h"
#include "gnu-strndup.h"
#endif
/* HP-UX specific defines */
#ifdef OS_HPUX
#include "gnu-getline.h"
#include "gnu-strndup.h"
#endif
/* IBM Aix specific defines */
#ifdef OS_AIX
#include "gnu-getline.h"
#include "gnu-strndup.h"
#endif
/* FreeBSD specific defines */
#ifdef OS_FREEBSD
#ifdef __GNUC__
#if __GNUC__ >= 4
#define _SSIZE_T_DECLARED
#endif
#endif
#include "gnu-getline.h"
#include "gnu-strndup.h"
#endif
/* Microsoft Windows specific defines */
#ifdef OS_WIN32
#ifndef lstat
#define lstat(x, y) stat(x, y)
#endif
#ifndef S_ISLNK
#define S_ISLNK(m) (0)
#endif
#ifndef S_ISREG
#define S_ISREG(m) ((m&_S_IFREG)==_S_IFREG)
#endif
#ifndef S_ISDIR
#define S_ISDIR(m) (((m)&_S_IFDIR)==_S_IFDIR)
#endif
#ifndef O_CREAT
#define O_CREAT _O_CREAT
#endif
#ifndef O_BINARY
#define O_BINARY _O_BINARY
#endif
#ifndef O_EXCL
#define O_EXCL _O_EXCL
#endif
#include "gnu-getline.h"
#include "gnu-mkstemp.h"
#include "gnu-strcasecmp.h"
#include "gnu-strndup.h"
#endif
/* define per-system PATH separator (char/string used to separate
sublevels of directories in a path
*/
#ifdef OS_WIN32
/** \def DIR_SEPARATOR_STRING
\brief Defines what's the path separator string for WIN32 platform.
*/
#define DIR_SEPARATOR_STRING "\\"
/** \def DIR_SEPARATOR_CHAR
\brief Defines what's the path separator character for WIN32 platform.
*/
#define DIR_SEPARATOR_CHAR '\\'
#else
/** \def DIR_SEPARATOR_STRING
\brief Defines what's the path separator string for POSIX systems.
*/
#define DIR_SEPARATOR_STRING "/"
/** \def DIR_SEPARATOR_CHAR
\brief Defines what's the path separator character for POSIX systems.
*/
#define DIR_SEPARATOR_CHAR '/'
#endif
/* define some picture formats markers and tags
note: markers and tags that belongs to supported formats and data
structures are defined in the relevant .h files (Adobe, Exiv, IPTC, JFIF)
*/
#define GIF87_MARKER_STRING "GIF87"
#define GIF89_MARKER_STRING "GIF89"
#define BMP_MARKER_STRING "BM"
#define PNG_MARKER_STRING 0x89504e47UL
#define TIFF_LITTLE_ENDIAN_MARKER_STRING 0x49492a00UL
#define TIFF_BIG_ENDIAN_MARKER_STRING 0x4d4d002aUL
#define DJVU_MARKER_STRING "DJvu"
/** \typedef flag
\brief Invent the boolean type.
*/
typedef short int flag;
#define faux 0
#define vrai 1
/** \enum OP
\brief Possible operation types.
Define OPeration types.
*/
enum OP
{
OP_CHECK, /**< check mode (only check known data structures) */
OP_DUMP, /**< dump mode: check and dump data structures */
OP_DUMP_FULL, /**< full dump mode: check, dump data structures and relevant values */
OP_DUMP_VALUE, /**< dump value mode: check and dump requested value only */
OP_FILTER, /**< filter mode: check and filter datasets (filter is excluding (remove), including (keep),
or editing (add/replace). if no filter pattern is set, nothing will be done) */
/* reserved */
OP_EOT /**< reserved */
};
/* define minimum and maximum log level */
#define MIN_LOG_LEVEL 0
#define MAX_LOG_LEVEL 4
/* define some default, minimum and maximum values for dump wrapping of
metadata
*/
#define DEFAULT_WRAP_DUMP 0
#define MIN_WRAP_DUMP 8
#define MAX_WRAP_DUMP 1024
/** \enum LOG_LEVEL
\brief Possible log levels.
Define log levels (from quiet to debug).
*/
enum LOG_LEVEL
{
LOG_LEVEL_QUIET, /**< */
LOG_LEVEL_ERRORS, /**< */
LOG_LEVEL_WARNINGS, /**< */
LOG_LEVEL_INFO, /**< */
LOG_LEVEL_DEBUG, /**< */
/* reserved */
LOG_LEVEL_EOT /**< reserved */
};
/** \enum SEVERITY
\brief Possible messages severities.
Define all messages severities (from fatal error to debug).
*/
enum SEVERITY
{
SEV_FATAL_ERROR, /**< */
SEV_ERROR, /**< */
SEV_WARNING, /**< */
SEV_INFO, /**< */
SEV_DEBUG /**< reserved */
};
/** \enum FILTER_MODE
\brief Possible filter modes.
Define all possible filter modes.
*/
enum FILTER_MODE
{
FILTER_NONE=0, /**< */
FILTER_INCLUDE=1, /**< */
FILTER_EXCLUDE=2, /**< */
FILTER_EDIT=4 /**< */
};
/** \enum FILTER_EDIT_VALUE_TYPE
\brief Possible filter edit value types.
Define all possible types for filter edits values.
*/
enum FILTER_EDIT_VALUE_TYPE
{
FEV_NONE, /**< */
FEV_HEX, /**< */
FEV_TEXT /**< */
};
/** \struct op_label
\brief OP label data structure.
Defines a structure so that labels and descriptions can be associated to
enum OP values.
*/
struct op_label
{
enum OP op; /**< operation type ID */
char* label; /**< operation label (short, to be used in command-line invocation) */
char* description; /**< operation description (long, shown in usage help) */
};
/** \struct log_level_descr
\brief Log level data structure.
Defines a data structure so that descriptions can be associated to enum
LOG_LEVEL values.
*/
struct log_level_descr
{
enum LOG_LEVEL level; /**< log level ID */
char* description; /**< log level description (long, shown in usage help) */
};
/** \struct prefs_struct
\brief Preferences structure.
Defines a data structure of the preferences (aimed to be globally used).
*/
struct prefs_struct
{
enum LOG_LEVEL log_level; /**< log level */
flag technical; /**< technical flag: is set, extra checks will be made and severity level of some messages might be increased */
enum OP op; /**< operation type */
char* context_text; /**< current context descriptive text */
unsigned long int context_warnings; /**< number of encountered warnings in current context */
unsigned long int context_errors; /**< number of encountered errors in current context */
unsigned long int context_fixes; /**< number of fixes done in current context */
unsigned long int warnings; /**< total number of encountered warnings */
unsigned long int errors; /**< total number of encountered errors */
unsigned long int fixes; /**< total number of fixed done */
unsigned short int wrap_dump; /**< wrap dump of dataset value flag: is set, long data dump will be wrapped */
flag rewrite; /**< rewrite mode flag: set according to the operation type and some other settings */
flag rewrite_create_backup; /**< create backup of written files flag: if set, backup will be created for each file open in write mode */
flag fix; /**< fix flag: is set, fixes will be done (if possible) when a broken structure is encountered */
int filter_mode; /**< filter mode flag: used when the operation type is filter */
flag rewrite_cached; /**< cached write mode flag: if set, written bytes will pass thru a cache in memory */
flag extract_iptc; /**< IPTC extraction flag: is set, IPTC datasets will be written to a file */
flag extract_extension_append; /**< extraction: filename extension append flag: is set, extension will be appended to the input filename (when writing datasets) */
flag test_rewrite; /**< test write flag: mostly provided for debug purposes: if set, files opened in write mode will not override any existing file but the temporary write file will be kept */
/* flag edit_overwrite; */ /**< allow overwriting existing field values when adding (edit) */
};
/** \struct parser_result
\brief Parser result structure.
Define a data structure that is returned/modified by a parser, and which
will contain a sum up of the parsing results.
*/
struct parser_result
{
unsigned long int parsed_bytes; /**< (parsed bytes) bytes eaten by the parser */
unsigned long int written_bytes; /**< (written bytes) bytes rewritten by the parser (following the OP mode and some other conditions) */
flag ret; /**< (parser return code) faux if any critical parsing error has been found */
};
/** \enum EXIT_CODE
\brief Possible program exit codes.
\todo Make this portable (BSD, VMS, etc.), regarding to EXIT_SUCCESS/EXIT_FAILURE (man 3 exit).
Defines the possible exit code returned by the program (from normal
termination to fatal error).
*/
enum EXIT_CODE
{
EXIT_CODE_NORMAL=0, /**< indicates a normal termination of the program */
EXIT_CODE_USAGE_ERROR, /**< indicates a usage error (commonly command-line parser error) */
EXIT_CODE_ASYNCHRONOUS_SIGNAL, /**< indicates that the program stopped due to a signal trap */
EXIT_CODE_NORMAL_WITH_WARNINGS, /**< indicates that some non critical warning(s) have been encountered */
EXIT_CODE_NORMAL_WITH_ERRORS, /**< indicates that some non critical error(s) have been encountered */
EXIT_CODE_FATAL_ERROR, /**< indicates a fatal error has been encountered */
/* reserved */
EXIT_EOT /**< reserved */
};
/** \struct exit_code_label
\brief Exit code label data structure.
Defines a data structure so that labels can be associated to enum EXIT_CODE
values.
*/
struct exit_code_label
{
enum EXIT_CODE code; /**< exit code (see EXIT_CODE enum) */
char* label; /**< label */
};
/* functions prototypes */
/* low-level file management */
size_t fsize(FILE*);
flag fexist(const char*);
int frename(const char*, const char*);
int fremove(const char*, const char*);
flag fisfile(const char*);
flag fislink(const char*);
flag fisdir(const char*);
char* fextension(const char*);
char* fbasename(const char*);
char* ffilename(const char*);
char* fdirname(const char*);
char* fcleanpath(const char*);
/* high-level file management */
void backup_file(const char*);
/* memory random access */
unsigned char getbyte(unsigned char*, unsigned long int);
unsigned short int getword(unsigned char*, unsigned long int);
unsigned short int getrawword(unsigned char*, unsigned long int);
unsigned long int getlong(unsigned char*, unsigned long int);
unsigned long int getrawlong(unsigned char*, unsigned long int);
unsigned char* getstring(unsigned char*, unsigned long int, unsigned char*, const unsigned long int);
unsigned char* getraw(unsigned char*, unsigned long int, unsigned char*, const unsigned long int);
void setbyte(unsigned char*, unsigned long int, unsigned char);
void setword(unsigned char*, unsigned long int, unsigned short int);
void setlong(unsigned char*, unsigned long int, unsigned long int);
/* verbosity (output), error management */
void message_fatal_error(char*, va_list);
void message_error(char*, va_list);
void message_warning(char*, va_list);
void message_info(char*, va_list);
void message_debug(char*, va_list);
void fatal_error(char*, ...);
void error(char*, ...);
void warning(char*, ...);
void info(char*, ...);
void debug(char*, ...);
void message(enum SEVERITY, char*, ...);
/* context management (mostly for verbosity purposes) */
void context_set_text(char*);
void context_print_text(void);
void context_print_info(void);
void context_reset(void);
/* internal tables access */
struct op_label* op_match_label(char*);
/* write mode */
void init_rewrite();
size_t dump_rewrite(unsigned char*, unsigned long int);
void post_rewrite(unsigned char*, struct parser_result*);
/* type convertion */
flag get_unsigned_value(const char*, unsigned long int*);
flag get_hexa_value(const char*, unsigned long int*);
/* string manipulation */
size_t strpos(const char*, const char);
size_t strrpos(const char*, const char);
/* filter exclude/include pattern loading/decoding */
flag filter_parse_line(char*, size_t, unsigned long int);
void filter_load_line(char*);
void filter_load_file(FILE*);
/* filter edit pattern loading/decoding */
flag edit_parse_line(const char*, size_t, unsigned long int);
void edit_load_line(const char*);
void edit_load_file(FILE*);
/* dumping dataset values */
void dump_hexa(unsigned char*, unsigned long int);
/* @<file> files list loading (into a vector) */
void filenames_list_load(char***, int*, FILE*);
#endif
|