#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "filesync.h"
#include "database.h"
#include "debug.h"
static struct flaglist dbgflags[] =
{ DBG_BASE, "BASE: base include building",
DBG_RULE, "RULE: rule tree building",
DBG_STAT, "STAT: file stats",
DBG_ANAL, "ANAL: difference analysis",
DBG_RECON, "RECO: reconciliation list processing",
DBG_VARS, "VARS: qualification and expansion",
DBG_FILES, "FILE: rule and baseline files",
DBG_LIST, "LIST: tree building",
DBG_EVAL, "EVAL: tree walking",
DBG_IGNORE, "IGNO: ignore list",
DBG_MISC, "MISC: everything else",
0, 0
};
struct flaglist dbgmap[] =
{ DBG_BASE, "BASE",
DBG_RULE, "RULE",
DBG_STAT, "STAT",
DBG_ANAL, "ANAL",
DBG_RECON, "RECO",
DBG_VARS, "VARS",
DBG_FILES, "FILE",
DBG_LIST, "LIST",
DBG_EVAL, "EVAL",
DBG_IGNORE, "IGNO",
DBG_MISC, "MISC",
0, 0
};
struct flaglist rflags[] =
{ R_IGNORE, "IGNORE",
R_PROGRAM, "PROGRAM",
R_WILD, "WILD",
R_NEW, "NEW",
R_BOGUS, "BOGUS",
R_RESTRICT, "RESTRICT",
0, 0
};
struct flaglist fileflags[] =
{ F_NEW, "new",
F_IN_BASELINE, "base",
F_IN_SOURCE, "srce",
F_IN_DEST, "dest",
F_EVALUATE, "eval",
F_SPARSE, "sparse",
F_REMOVE, "remove",
F_CONFLICT, "conflict",
F_LISTED, "listed",
F_STAT_ERROR, "statfail",
0, 0
};
struct flaglist diffmap[] = {
D_CREATE, "create",
D_DELETE, "delete",
D_MTIME, "modtime",
D_SIZE, "size",
D_UID, "uid",
D_GID, "gid",
D_PROT, "modes",
D_LINKS, "links",
D_TYPE, "type",
D_FACLS, "facls",
D_RENAME_TO, "rename2",
D_RENAME_FROM, "renamed",
0, 0
};
struct flaglist errmap[] = {
ERR_RESOLVABLE, "resolvable",
ERR_UNRESOLVED, "unresolvable",
ERR_MISSING, "missing files",
ERR_PERM, "permissions",
ERR_FILES, "rule/base errors",
ERR_INVAL, "invalid arguments",
ERR_NOBASE, "bad base dir",
ERR_OTHER, "other",
0, 0
};
char *
showflags(struct flaglist *map, long mask)
{ int i;
static char outbuf[MAX_NAME];
outbuf[0] = 0;
for (i = 0; map[i].fl_mask; i++)
if (mask & map[i].fl_mask) {
if (outbuf[0])
strcat(outbuf, "|");
strcat(outbuf, map[i].fl_name);
}
return (outbuf);
}
void
dbg_usage(void)
{ int i;
fprintf(stderr, "Usage:\tfilesync -Dmask ...\n");
for (i = 0; dbgflags[i].fl_mask; i++)
fprintf(stderr, "\t0x%04lx .... %s\n",
dbgflags[i].fl_mask, dbgflags[i].fl_name);
fprintf(stderr, "\n");
}
#ifdef DBG_ERRORS
void
err_usage(void)
{
fprintf(stderr, "Usage:\tfilesync -E<errno>,<code>,<filename>\n");
fprintf(stderr, "\ts ... eval stat source\n");
fprintf(stderr, "\tS ... eval stat destination\n");
fprintf(stderr, "\tn ... eval nftw source\n");
fprintf(stderr, "\tN ... eval nftw destination\n");
fprintf(stderr, "\tc ... reconcile copy create\n");
fprintf(stderr, "\to ... reconcile copy open\n");
fprintf(stderr, "\tr ... reconcile copy read/readlink\n");
fprintf(stderr, "\tw ... reconcile copy write\n");
fprintf(stderr, "\tl ... reconcile link/symlink\n");
fprintf(stderr, "\tu ... reconcile unlink\n");
fprintf(stderr, "\td ... reconcile mkdir/mknod\n");
fprintf(stderr, "\tD ... reconcile rmdir\n");
fprintf(stderr, "\tm ... reconcile rename\n");
fprintf(stderr, "\tR ... reconcile restat\n");
fprintf(stderr, "\tp ... reconcile protection (chmod)");
fprintf(stderr, "\ta ... reconcile access control (setfacl)");
fprintf(stderr, "\tO ... reconcile ownership (chown)");
fprintf(stderr, "\tZ ... out of space on target\n");
fprintf(stderr, "\n");
}
static struct errsim {
int Errno;
char code;
char *file;
} errsim[ DBG_MAX_ERR ];
static int num_errs;
int
dbg_set_error(char *arg)
{ char *s;
char error_type;
int error_no;
if (num_errs >= DBG_MAX_ERR) {
fprintf(stderr, "ERROR: only %d -E specifications allowed\n",
DBG_MAX_ERR);
return (ERR_INVAL);
}
if (!isdigit(arg[0]))
return (ERR_INVAL);
error_no = strtol(arg, &s, 0);
if (*s++ != ',' || !isalpha(*s))
return (ERR_INVAL);
error_type = *s;
while (*s && *s != ',') s++;
if (*s++ != ',' || *s == 0)
return (ERR_INVAL);
errsim[num_errs].Errno = error_no;
errsim[num_errs].code = error_type;
errsim[num_errs].file = s;
if (opt_debug & DBG_MISC)
fprintf(stderr, "MISC: errsim[%d] %c(%s) -> %d\n",
num_errs, error_type, s, error_no);
num_errs++;
return (0);
}
int
dbg_chk_error(const char *name, char code)
{ int i;
for (i = 0; i < num_errs; i++) {
if (code != errsim[i].code)
continue;
if (!suffix(name, errsim[i].file))
continue;
if (opt_debug & DBG_MISC)
fprintf(stderr, "MISC: trigger %d for file %c(%s)\n",
errsim[i].Errno, code, name);
return (errsim[i].Errno);
}
return (0);
}
#else
void
err_usage(void)
{
fprintf(stderr, "ERROR: this filesync does not support -E\n");
}
int
dbg_set_error(char *arg)
{
return (ERR_INVAL);
}
int
dbg_chk_error(const char *name, char code)
{
return (0);
}
#endif