/*
* Amanda, The Advanced Maryland Automatic Network Disk Archiver
* Copyright (c) 1991-2000 University of Maryland at College Park
* Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved.
* Copyright (c) 2013-2016 Carbonite, Inc. All Rights Reserved.
* All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of U.M. not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. U.M. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "amanda.h"
#include "amutil.h"
#include "conffile.h"
#include "ammessage.h"
#include "amjson.h"
#define MAX_ERRCODE 500
char *errcode[MAX_ERRCODE];
void init_errcode(void);
void
init_errcode(void)
{
static int initialize = 0;
int i =0;
if (initialize)
return;
initialize = 1;
for(i=0; i < MAX_ERRCODE; i++) {
errcode[i] = "UNKNOWN";
}
#if defined E2BIG && E2BIG<MAX_ERRCODE
errcode[E2BIG] = "E2BIG";
#endif
#if defined EACCES && EACCES<MAX_ERRCODE
errcode[EACCES] = "EACCES";
#endif
#if defined EADDRINUSE && EADDRINUSE<MAX_ERRCODE
errcode[EADDRINUSE] = "EADDRINUSE";
#endif
#if defined EADDRNOTAVAIL && EADDRNOTAVAIL<MAX_ERRCODE
errcode[EADDRNOTAVAIL] = "EADDRNOTAVAIL";
#endif
#if defined EAFNOSUPPORT && EADDRNOTAVAIL<MAX_ERRCODE
errcode[EAFNOSUPPORT] = "EAFNOSUPPORT";
#endif
#if defined EAGAIN && EAGAIN<MAX_ERRCODE
errcode[EAGAIN] = "EAGAIN";
#endif
#if defined EALREADY && EALREADY<MAX_ERRCODE
errcode[EALREADY] = "EALREADY";
#endif
#if defined EBADE && EBADE<MAX_ERRCODE
errcode[EBADE] = "EBADE";
#endif
#if defined EBADF && EBADF<MAX_ERRCODE
errcode[EBADF] = "EBADF";
#endif
#if defined EBADFD && EBADFD<MAX_ERRCODE
errcode[EBADFD] = "EBADFD";
#endif
#if defined EBADMSG && EBADMSG<MAX_ERRCODE
errcode[EBADMSG] = "EBADMSG";
#endif
#if defined EBADR && EBADR<MAX_ERRCODE
errcode[EBADR] = "EBADR";
#endif
#if defined EBADRQC && EBADRQC<MAX_ERRCODE
errcode[EBADRQC] = "EBADRQC";
#endif
#if defined EBADSLT && EBADSLT<MAX_ERRCODE
errcode[EBADSLT] = "EBADSLT";
#endif
#if defined EBUSY && EBUSY<MAX_ERRCODE
errcode[EBUSY] = "EBUSY";
#endif
#if defined ECANCELED && ECANCELED<MAX_ERRCODE
errcode[ECANCELED] = "ECANCELED";
#endif
#if defined ECHILD && ECHILD<MAX_ERRCODE
errcode[ECHILD] = "ECHILD";
#endif
#if defined ECHRNG && ECHRNG<MAX_ERRCODE
errcode[ECHRNG] = "ECHRNG";
#endif
#if defined ECOMM && ECOMM<MAX_ERRCODE
errcode[ECOMM] = "ECOMM";
#endif
#if defined ECONNABORTED && ECONNABORTED<MAX_ERRCODE
errcode[ECONNABORTED] = "ECONNABORTED";
#endif
#if defined ECONNREFUSED && ECONNREFUSED<MAX_ERRCODE
errcode[ECONNREFUSED] = "ECONNREFUSED";
#endif
#if defined ECONNRESET && ECONNRESET<MAX_ERRCODE
errcode[ECONNRESET] = "ECONNRESET";
#endif
#if defined EDEADLK && EDEADLK<MAX_ERRCODE
errcode[EDEADLK] = "EDEADLK";
#endif
#if defined EDEADLOCK && EDEADLOCK<MAX_ERRCODE
#if !defined EDEADLK || EDEADLK != EDEADLOCK
errcode[EDEADLOCK] = "EDEADLOCK";
#endif
#endif
#if defined EDESTADDRREQ && EDESTADDRREQ<MAX_ERRCODE
errcode[EDESTADDRREQ] = "EDESTADDRREQ";
#endif
#if defined EDOM && EDOM<MAX_ERRCODE
errcode[EDOM] = "EDOM";
#endif
#if defined EDQUOT && EDQUOT<MAX_ERRCODE
errcode[EDQUOT] = "EDQUOT";
#endif
#if defined EEXIST && EEXIST<MAX_ERRCODE
errcode[EEXIST] = "EEXIST";
#endif
#if defined EFAULT && EFAULT<MAX_ERRCODE
errcode[EFAULT] = "EFAULT";
#endif
#if defined EFBIG && EFBIG<MAX_ERRCODE
errcode[EFBIG] = "EFBIG";
#endif
#if defined EHOSTDOWN && EHOSTDOWN<MAX_ERRCODE
errcode[EHOSTDOWN] = "EHOSTDOWN";
#endif
#if defined EHOSTUNREACH && EHOSTUNREACH<MAX_ERRCODE
errcode[EHOSTUNREACH] = "EHOSTUNREACH";
#endif
#if defined EIDRM && EIDRM<MAX_ERRCODE
errcode[EIDRM] = "EIDRM";
#endif
#if defined EILSEQ && EILSEQ<MAX_ERRCODE
errcode[EILSEQ] = "EILSEQ";
#endif
#if defined EINPROGRESS && EINPROGRESS<MAX_ERRCODE
errcode[EINPROGRESS] = "EINPROGRESS";
#endif
#if defined EINTR && EINTR<MAX_ERRCODE
errcode[EINTR] = "EINTR";
#endif
#if defined EINVAL && EINVAL<MAX_ERRCODE
errcode[EINVAL] = "EINVAL";
#endif
#if defined EIO && EIO<MAX_ERRCODE
errcode[EIO] = "EIO";
#endif
#if defined EISCONN && EISCONN<MAX_ERRCODE
errcode[EISCONN] = "EISCONN";
#endif
#if defined EISDIR && EISDIR<MAX_ERRCODE
errcode[EISDIR] = "EISDIR";
#endif
#if defined EISNAM && EISNAM<MAX_ERRCODE
errcode[EISNAM] = "EISNAM";
#endif
#if defined EKEYEXPIRED && EKEYEXPIRED<MAX_ERRCODE
errcode[EKEYEXPIRED] = "EKEYEXPIRED";
#endif
#if defined EKEYREJECTED && EKEYREJECTED<MAX_ERRCODE
errcode[EKEYREJECTED] = "EKEYREJECTED";
#endif
#if defined EKEYREVOKED && EKEYREVOKED<MAX_ERRCODE
errcode[EKEYREVOKED] = "EKEYREVOKED";
#endif
#if defined EL2HLT && EL2HLT<MAX_ERRCODE
errcode[EL2HLT] = "EL2HLT";
#endif
#if defined EL2NSYNC && EL2NSYNC<MAX_ERRCODE
errcode[EL2NSYNC] = "EL2NSYNC";
#endif
#if defined EL3HLT && EL3HLT<MAX_ERRCODE
errcode[EL3HLT] = "EL3HLT";
#endif
#if defined EL3RST && EL3RST<MAX_ERRCODE
errcode[EL3RST] = "EL3RST";
#endif
#if defined ELIBACC && ELIBACC<MAX_ERRCODE
errcode[ELIBACC] = "ELIBACC";
#endif
#if defined ELIBBAD && ELIBBAD<MAX_ERRCODE
errcode[ELIBBAD] = "ELIBBAD";
#endif
#if defined ELIBMAX && ELIBMAX<MAX_ERRCODE
errcode[ELIBMAX] = "ELIBMAX";
#endif
#if defined ELIBSCN && ELIBSCN<MAX_ERRCODE
errcode[ELIBSCN] = "ELIBSCN";
#endif
#if defined ELIBEXEC && ELIBEXEC<MAX_ERRCODE
errcode[ELIBEXEC] = "ELIBEXEC";
#endif
#if defined ELOOP && ELOOP<MAX_ERRCODE
errcode[ELOOP] = "ELOOP";
#endif
#if defined EMEDIUMTYPE && EMEDIUMTYPE<MAX_ERRCODE
errcode[EMEDIUMTYPE] = "EMEDIUMTYPE";
#endif
#if defined EMFILE && EMFILE<MAX_ERRCODE
errcode[EMFILE] = "EMFILE";
#endif
#if defined EMLINK && EMLINK<MAX_ERRCODE
errcode[EMLINK] = "EMLINK";
#endif
#if defined EMSGSIZE && EMSGSIZE<MAX_ERRCODE
errcode[EMSGSIZE] = "EMSGSIZE";
#endif
#if defined EMULTIHOP && EMULTIHOP<MAX_ERRCODE
errcode[EMULTIHOP] = "EMULTIHOP";
#endif
#if defined ENAMETOOLONG && ENAMETOOLONG<MAX_ERRCODE
errcode[ENAMETOOLONG] = "ENAMETOOLONG";
#endif
#if defined ENETDOWN && ENETDOWN<MAX_ERRCODE
errcode[ENETDOWN] = "ENETDOWN";
#endif
#if defined ENETRESET && ENETRESET<MAX_ERRCODE
errcode[ENETRESET] = "ENETRESET";
#endif
#if defined ENETUNREACH && ENETUNREACH<MAX_ERRCODE
errcode[ENETUNREACH] = "ENETUNREACH";
#endif
#if defined ENFILE && ENFILE<MAX_ERRCODE
errcode[ENFILE] = "ENFILE";
#endif
#if defined ENOBUFS && ENOBUFS<MAX_ERRCODE
errcode[ENOBUFS] = "ENOBUFS";
#endif
#if defined ENODATA && ENODATA<MAX_ERRCODE
errcode[ENODATA] = "ENODATA";
#endif
#if defined ENODEV && ENODEV<MAX_ERRCODE
errcode[ENODEV] = "ENODEV";
#endif
#if defined ENOENT && ENOENT<MAX_ERRCODE
errcode[ENOENT] = "ENOENT";
#endif
#if defined ENOEXEC && ENOEXEC<MAX_ERRCODE
errcode[ENOEXEC] = "ENOEXEC";
#endif
#if defined ENOKEY && ENOKEY<MAX_ERRCODE
errcode[ENOKEY] = "ENOKEY";
#endif
#if defined ENOLCK && ENOLCK<MAX_ERRCODE
errcode[ENOLCK] = "ENOLCK";
#endif
#if defined ENOLINK && ENOLINK<MAX_ERRCODE
errcode[ENOLINK] = "ENOLINK";
#endif
#if defined ENOMEDIUM && ENOMEDIUM<MAX_ERRCODE
errcode[ENOMEDIUM] = "ENOMEDIUM";
#endif
#if defined ENOMEM && ENOMEM<MAX_ERRCODE
errcode[ENOMEM] = "ENOMEM";
#endif
#if defined ENOMSG && ENOMSG<MAX_ERRCODE
errcode[ENOMSG] = "ENOMSG";
#endif
#if defined ENONET && ENONET<MAX_ERRCODE
errcode[ENONET] = "ENONET";
#endif
#if defined ENOPKG && ENOPKG<MAX_ERRCODE
errcode[ENOPKG] = "ENOPKG";
#endif
#if defined ENOPROTOOPT && ENOPROTOOPT<MAX_ERRCODE
errcode[ENOPROTOOPT] = "ENOPROTOOPT";
#endif
#if defined ENOSPC && ENOSPC<MAX_ERRCODE
errcode[ENOSPC] = "ENOSPC";
#endif
#if defined ENOSR && ENOSR<MAX_ERRCODE
errcode[ENOSR] = "ENOSR";
#endif
#if defined ENOSTR && ENOSTR<MAX_ERRCODE
errcode[ENOSTR] = "ENOSTR";
#endif
#if defined ENOSYS && ENOSYS<MAX_ERRCODE
errcode[ENOSYS] = "ENOSYS";
#endif
#if defined ENOTBLK && ENOTBLK<MAX_ERRCODE
errcode[ENOTBLK] = "ENOTBLK";
#endif
#if defined ENOTCONN && ENOTCONN<MAX_ERRCODE
errcode[ENOTCONN] = "ENOTCONN";
#endif
#if defined ENOTDIR && ENOTDIR<MAX_ERRCODE
errcode[ENOTDIR] = "ENOTDIR";
#endif
#if defined ENOTEMPTY && ENOTEMPTY<MAX_ERRCODE
errcode[ENOTEMPTY] = "ENOTEMPTY";
#endif
#if defined ENOTSOCK && ENOTSOCK<MAX_ERRCODE
errcode[ENOTSOCK] = "ENOTSOCK";
#endif
#if defined ENOTSUP && ENOTSUP<MAX_ERRCODE
errcode[ENOTSUP] = "ENOTSUP";
#endif
#if defined ENOTTY && ENOTTY<MAX_ERRCODE
errcode[ENOTTY] = "ENOTTY";
#endif
#if defined ENOTUNIQ && ENOTUNIQ<MAX_ERRCODE
errcode[ENOTUNIQ] = "ENOTUNIQ";
#endif
#if defined ENXIO && ENXIO<MAX_ERRCODE
errcode[ENXIO] = "ENXIO";
#endif
#if defined EOPNOTSUPP && EOPNOTSUPP<MAX_ERRCODE
errcode[EOPNOTSUPP] = "EOPNOTSUPP";
#endif
#if defined EOVERFLOW && EOVERFLOW<MAX_ERRCODE
errcode[EOVERFLOW] = "EOVERFLOW";
#endif
#if defined EPERM && EPERM<MAX_ERRCODE
errcode[EPERM] = "EPERM";
#endif
#if defined EPFNOSUPPORT && EPFNOSUPPORT<MAX_ERRCODE
errcode[EPFNOSUPPORT] = "EPFNOSUPPORT";
#endif
#if defined EPIPE && EPIPE<MAX_ERRCODE
errcode[EPIPE] = "EPIPE";
#endif
#if defined EPROTO && EPROTO<MAX_ERRCODE
errcode[EPROTO] = "EPROTO";
#endif
#if defined EPROTONOSUPPORT && EPROTONOSUPPORT<MAX_ERRCODE
errcode[EPROTONOSUPPORT] = "EPROTONOSUPPORT";
#endif
#if defined EPROTOTYPE && EPROTOTYPE<MAX_ERRCODE
errcode[EPROTOTYPE] = "EPROTOTYPE";
#endif
#if defined ERANGE && ERANGE<MAX_ERRCODE
errcode[ERANGE] = "ERANGE";
#endif
#if defined EREMCHG && EREMCHG<MAX_ERRCODE
errcode[EREMCHG] = "EREMCHG";
#endif
#if defined EREMOTE && EREMOTE<MAX_ERRCODE
errcode[EREMOTE] = "EREMOTE";
#endif
#if defined EREMOTEIO && EREMOTEIO<MAX_ERRCODE
errcode[EREMOTEIO] = "EREMOTEIO";
#endif
#if defined ERESTART && ERESTART<MAX_ERRCODE
errcode[ERESTART] = "ERESTART";
#endif
#if defined EROFS && EROFS<MAX_ERRCODE
errcode[EROFS] = "EROFS";
#endif
#if defined ESHUTDOWN && ESHUTDOWN<MAX_ERRCODE
errcode[ESHUTDOWN] = "ESHUTDOWN";
#endif
#if defined ESPIPE && ESPIPE<MAX_ERRCODE
errcode[ESPIPE] = "ESPIPE";
#endif
#if defined ESOCKTNOSUPPORT && ESOCKTNOSUPPORT<MAX_ERRCODE
errcode[ESOCKTNOSUPPORT] = "ESOCKTNOSUPPORT";
#endif
#if defined ESRCH && ESRCH<MAX_ERRCODE
errcode[ESRCH] = "ESRCH";
#endif
#if defined ESTALE && ESTALE<MAX_ERRCODE
errcode[ESTALE] = "ESTALE";
#endif
#if defined ESTRPIPE && ESTRPIPE<MAX_ERRCODE
errcode[ESTRPIPE] = "ESTRPIPE";
#endif
#if defined ETIME && ETIME<MAX_ERRCODE
errcode[ETIME] = "ETIME";
#endif
#if defined ETIMEDOUT && ETIMEDOUT<MAX_ERRCODE
errcode[ETIMEDOUT] = "ETIMEDOUT";
#endif
#if defined ETXTBSY && ETXTBSY<MAX_ERRCODE
errcode[ETXTBSY] = "ETXTBSY";
#endif
#if defined EUCLEAN && EUCLEAN<MAX_ERRCODE
errcode[EUCLEAN] = "EUCLEAN";
#endif
#if defined EUNATCH && EUNATCH<MAX_ERRCODE
errcode[EUNATCH] = "EUNATCH";
#endif
#if defined EUSERS && EUSERS<MAX_ERRCODE
errcode[EUSERS] = "EUSERS";
#endif
#if defined EWOULDBLOCK && EWOULDBLOCK<MAX_ERRCODE
errcode[EWOULDBLOCK] = "EWOULDBLOCK";
#endif
#if defined EXDEV && EXDEV<MAX_ERRCODE
errcode[EXDEV] = "EXDEV";
#endif
#if defined EXFULL && EXFULL<MAX_ERRCODE
errcode[EXFULL] = "EXFULL";
#endif
#if defined EOWNERDEAD && EOWNERDEAD<MAX_ERRCODE
errcode[EOWNERDEAD] = "EOWNERDEAD";
#endif
#if defined ENOTRECOVERABLE && ENOTRECOVERABLE<MAX_ERRCODE
errcode[ENOTRECOVERABLE] = "ENOTRECOVERABLE";
#endif
#if defined ERFKILL && ERFKILL<MAX_ERRCODE
errcode[ERFKILL] = "ERFKILL";
#endif
#if defined EHWPOISON && EHWPOISON<MAX_ERRCODE
errcode[EHWPOISON] = "EHWPOISON";
#endif
#if defined ETOOMANYREFS && ETOOMANYREFS<MAX_ERRCODE
errcode[ETOOMANYREFS] = "ETOOMANYREFS";
#endif
#if defined ENOTNAM && ENOTNAM<MAX_ERRCODE
errcode[ENOTNAM] = "ENOTNAM";
#endif
#if defined ENAVAIL && ENAVAIL<MAX_ERRCODE
errcode[ENAVAIL] = "ENAVAIL";
#endif
#if defined EDOTDOT && EDOTDOT<MAX_ERRCODE
errcode[EDOTDOT] = "EDOTDOT";
#endif
#if defined ESRMNT && ESRMNT<MAX_ERRCODE
errcode[ESRMNT] = "ESRMNT";
#endif
#if defined EADV && EADV<MAX_ERRCODE
errcode[EADV] = "EADV";
#endif
#if defined EBFONT && EBFONT<MAX_ERRCODE
errcode[EBFONT] = "EBFONT";
#endif
#if defined ENOANO && ENOANO<MAX_ERRCODE
errcode[ENOANO] = "ENOANO";
#endif
#if defined ENOCSI && ENOCSI<MAX_ERRCODE
errcode[ENOCSI] = "ENOCSI";
#endif
#if defined ELNRNG && ELNRNG<MAX_ERRCODE
errcode[ELNRNG] = "ELNRNG";
#endif
}
typedef struct message_arg_array_s {
char *key;
amjson_t value;
} message_arg_array_t;
struct message_s {
char *file;
int line;
char *process;
char *running_on;
char *component;
char *module;
int code;
int severity;
char *msg;
char *quoted_msg;
char *hint;
int merrno;
char *errnocode;
char *errnostr;
int argument_allocated;
message_arg_array_t *arg_array;
};
static char *ammessage_encode_json(char *str);
static void set_message(message_t *message, int want_quoted);
static char *severity_name(int severity);
static GString *fix_message_string(message_t *message, gboolean want_quoted, char *msg);
static char *
severity_name(
int severity)
{
if (severity == 1)
return "success";
else if (severity == 2)
return "info";
else if (severity == 4)
return "message";
else if (severity == 8)
return "warning";
else if (severity == 16)
return "error";
else if (severity == 32)
return "critical";
else
return "unknown";
}
static char *
ammessage_encode_json(
char *str)
{
int i = 0;
int len;
unsigned char *s;
char *encoded;
char *e;
if (!str) {
return g_strdup("null");
}
len = strlen(str)*2;
s = (unsigned char *)str;
encoded = g_malloc(len+1);
e = encoded;
while(*s != '\0') {
if (i++ >= len) {
error("ammessage_encode_json: str is too long: %s", str);
}
if (*s == '\\' || *s == '"') {
*e++ = '\\';
*e++ = *s++;
} else if (*s == '\b') {
*e++ = '\\';
*e++ = 'b';
s++;
} else if (*s == '\f') {
*e++ = '\\';
*e++ = 'f';
s++;
} else if (*s == '\n') {
*e++ = '\\';
*e++ = 'n';
s++;
} else if (*s == '\r') {
*e++ = '\\';
*e++ = 'r';
s++;
} else if (*s == '\t') {
*e++ = '\\';
*e++ = 't';
s++;
} else if (*s == '\v') {
*e++ = '\\';
*e++ = 'v';
s++;
} else if (*s < 32) {
*e++ = '\\';
*e++ = 'u';
*e++ = '0';
*e++ = '0';
if ((*s>>4) <= 9)
*e++ = '0' + (*s>>4);
else
*e++ = 'A' + (*s>4) - 10;
if ((*s & 0x0F) <= 9)
*e++ = '0' + (*s & 0x0F);
else
*e++ = 'A' + (*s & 0x0F) - 10;
s++;
} else {
*e++ = *s++;
}
}
*e = '\0';
return encoded;
}
char *
message_get_argument(
message_t *message,
char *key)
{
int i = 0;
char *m_message;
while (message->arg_array[i].key != NULL) {
if (strcmp(key, message->arg_array[i].key) == 0) {
assert(message->arg_array[i].value.type == JSON_STRING);
return message->arg_array[i].value.string;
}
i++;
}
m_message = sprint_message(message);
g_debug("Not value for key '%s' in message %s", key, m_message);
g_free(m_message);
return "";
}
void
message_add_argument(
message_t *message,
char *key,
char *value)
{
int i = 0;
while (message->arg_array[i].key != NULL) {
if (strcmp(key, message->arg_array[i].key) == 0) {
assert(message->arg_array[i].value.type == JSON_STRING);
g_free(message->arg_array[i].value.string);
message->arg_array[i].value.string = g_strdup(value);
}
i++;
}
if (i > message->argument_allocated) {
message->argument_allocated *= 2;
message->arg_array = g_realloc(message->arg_array, (message->argument_allocated+1) * sizeof(message_arg_array_t));
}
message->arg_array[i].key = g_strdup(key);
message->arg_array[i].value.type = JSON_STRING;
message->arg_array[i].value.string = g_strdup(value);
i++;
message->arg_array[i].key = NULL;
message->arg_array[i].value.type = JSON_NULL;
message->arg_array[i].value.string = NULL;
}
static void
set_message(
message_t *message,
int want_quoted)
{
char *msg = NULL;
char *hint = NULL;
GString *result;
gboolean free_msg = FALSE;
init_errcode();
if (message == NULL)
return;
if (message->code == 123) {
msg = "%{errstr}";
} else if (message->code == 2800000) {
msg = "Usage: amcheck [--version] [-am] [-w] [-sclt] [-M <address>] [--client-verbose] [--exact_match] [-o configoption]* <conf> [host [disk]* ]*";
} else if (message->code == 2800001) {
msg = "amcheck-%{version}";
} else if (message->code == 2800002) {
msg = "Multiple -M options";
} else if (message->code == 2800003) {
msg = "Invalid characters in mail address";
} else if (message->code == 2800004) {
msg = "You can't use -a because a mailer is not defined";
} else if (message->code == 2800005) {
msg = "You can't use -m because a mailer is not defined";
} else if (message->code == 2800006) {
msg = "No mail address configured in amanda.conf";
hint = "To receive dump results by email configure the "
"\"mailto\" parameter in amanda.conf";
} else if (message->code == 2800007) {
msg = "To receive dump results by email configure the "
"\"mailto\" parameter in amanda.conf";
} else if (message->code == 2800008) {
msg = "When using -a option please specify -Maddress also";
} else if (message->code == 2800009) {
msg = "Use -Maddress instead of -m";
} else if (message->code == 2800010) {
msg = "Mail address '%{mailto}' in amanda.conf has invalid characters";
} else if (message->code == 2800011) {
msg = "No email will be sent";
} else if (message->code == 2800012) {
msg = "No mail address configured in amanda.conf";
} else if (message->code == 2800013) {
msg = "When using -a option please specify -Maddress also";
} else if (message->code == 2800014) {
msg = "Use -Maddress instead of -m";
} else if (message->code == 2800015) {
msg = "%{errstr}";
} else if (message->code == 2800016) {
msg = "(brought to you by Amanda %{version})";
} else if (message->code == 2800017) {
msg = "Invalid mailto address '%{mailto}'";
} else if (message->code == 2800018) {
msg = "tapelist '%{tapelist}': should be a regular file";
} else if (message->code == 2800019) {
msg = "can't access tapelist '%{tapelist}': %{errnostr}";
} else if (message->code == 2800020) {
msg = "tapelist '%{tapelist}': not writable: %{errnostr}";
} else if (message->code == 2800021) {
msg = "parent: reaped bogus pid %{pid}";
} else if (message->code == 2800022) {
msg = "program %{program}: does not exist";
} else if (message->code == 2800023) {
msg = "program %{program}: not a file";
} else if (message->code == 2800024) {
msg = "program %{program}: not executable";
} else if (message->code == 2800025) {
msg = "program %{program}: not setuid-root";
} else if (message->code == 2800026) {
msg = "amcheck-device terminated with signal %{signal}";
} else if (message->code == 2800027) {
msg = "Amanda Tape Server Host Check";
} else if (message->code == 2800028) {
msg = "-----------------------------";
} else if (message->code == 2800029) {
msg = "storage '%{storage}': cannot read label template (lbl-templ) file %{filename}: %{errnostr}";
hint = "check permissions";
} else if (message->code == 2800030) {
msg = "storage '%{storage}': lbl-templ set but no LPR command defined";
hint = "you should reconfigure amanda and make sure it finds a lpr or lp command";
} else if (message->code == 2800031) {
msg = "storage '%{storage}': flush-threshold-dumped (%{flush_threshold_dumped}) must be less than or equal to flush-threshold-scheduled (%{flush_threshold_scheduled})";
} else if (message->code == 2800032) {
msg = "storage '%{storage}': taperflush (%{taperflush}) must be less than or equal to flush-threshold-scheduled (%{flush_threshold_scheduled})";
} else if (message->code == 2800033) {
msg = "WARNING: storage '%{storage}': autoflush must be set to 'yes' or 'all' if taperflush (%{taperflush}) is greater that 0";
} else if (message->code == 2800034) {
msg = "storage '%{storage}': no tapetype specified; you must give a value for the 'tapetype' parameter of the storage";
} else if (message->code == 2800035) {
msg = "storage '%{storage}': runtapes is larger or equal to policy '%{policy}' retention-tapes";
} else if (message->code == 2800036) {
msg = "system has %{kb_avail} memory, but device-output-buffer-size needs %{kb_needed}";
} else if (message->code == 2800037) {
msg = "Cannot resolve `localhost': %{gai_strerror}";
} else if (message->code == 2800038) {
msg = "directory '%{dir}' containing Amanda tools is not accessible: %{errnostr}";
hint = "check permissions";
} else if (message->code == 2800039) {
msg = "Check permissions";
} else if (message->code == 2800040) {
msg = "directory '%{dir}' containing Amanda tools is not accessible: %{errnostr}";
hint = "check permissions";
} else if (message->code == 2800041) {
msg = "Check permissions";
} else if (message->code == 2800042) {
msg = "WARNING: '%{program}' is not executable: %{errnostr}, server-compression and indexing will not work";
hint = "check permissions";
} else if (message->code == 2800043) {
msg = "Check permissions";
} else if (message->code == 2800044) {
msg = "tapelist dir '%{tape_dir}': not writable: %{errnostr}";
hint = "check permissions";
} else if (message->code == 2800045) {
msg = "tapelist '%{tapefile}' (%{errnostr}), you must create an empty file";
} else if (message->code == 2800046) {
msg = "tapelist file does not exists";
hint = "it will be created on the next run";
} else if (message->code == 2800047) {
msg = "tapelist '%{tapefile}': parse error";
} else if (message->code == 2800048) {
msg = "hold file '%{holdfile}' exists. Amdump will sleep as long as this file exists";
hint = "You might want to delete the existing hold file";
} else if (message->code == 2800049) {
msg = "Amdump will sleep as long as this file exists";
} else if (message->code == 2800050) {
msg = "You might want to delete the existing hold file";
} else if (message->code == 2800051) {
msg = "WARNING:Parameter \"tapedev\", \"tpchanger\" or storage not specified in amanda.conf";
} else if (message->code == 2800052) {
msg = "part-cache-type specified, but no part-size";
} else if (message->code == 2800053) {
msg = "part-cache-dir specified, but no part-size";
} else if (message->code == 2800054) {
msg = "part-cache-max-size specified, but no part-size";
} else if (message->code == 2800055) {
msg = "part-cache-type is DISK, but no part-cache-dir specified";
} else if (message->code == 2800056) {
msg = "part-cache-dir '%{part-cache-dir}': %{errnostr}";
} else if (message->code == 2800057) {
msg = "part-cache-dir has %{size:kb_avail} available, but needs %{size:kb_needed}";
} else if (message->code == 2800058) {
msg = "system has %{size:kb_avail} memory, but part cache needs %{size:kb_needed}";
} else if (message->code == 2800059) {
msg = "part-cache-dir specified, but part-cache-type is not DISK";
} else if (message->code == 2800060) {
msg = "part_size is zero, but part-cache-type is not 'none'";
} else if (message->code == 2800061) {
msg = "part-cache-max-size is specified but no part cache is in use";
} else if (message->code == 2800062) {
msg = "WARNING: part-cache-max-size is greater than part-size";
} else if (message->code == 2800063) {
msg = "WARNING: part-size of %{size:part_size} < 0.1%% of tape length";
} else if (message->code == 2800064) {
msg = "This may create > 1000 parts, severely degrading backup/restore performance."
" See http://wiki.zmanda.com/index.php/Splitsize_too_small for more information.";
} else if (message->code == 2800065) {
msg = "part-cache-max-size of %{size:part_size_max_size} < 0.1%% of tape length";
} else if (message->code == 2800066) {
msg = "holding dir '%{holding_dir}' (%{errnostr})";
hint = "you must create a directory";
} else if (message->code == 2800067) {
msg = "holding disk '%{holding_dir}': not writable: %{errnostr}";
hint = "check permissions";
} else if (message->code == 2800068) {
msg = "Check permissions";
} else if (message->code == 2800069) {
msg = "holding disk '%{holding_dir}': not searcheable: %{errnostr}";
hint = "check permissions of ancestors";
} else if (message->code == 2800070) {
msg = "Check permissions of ancestors of";
} else if (message->code == 2800071) {
msg = "WARNING: holding disk '%{holding_dir}': no space available (%{size:size} requested)";
} else if (message->code == 2800072) {
msg = "WARNING: holding disk '%{holding_dir}': only %{size:avail} available (%{size:requested} requested)";
} else if (message->code == 2800073) {
msg = "Holding disk '%{holding_dir}': %{size:avail} disk space available, using %{size:requested} as requested";
} else if (message->code == 2800074) {
msg = "holding disk '%{holding_dir}': only %{size:avail} free, using nothing";
} else if (message->code == 2800075) {
msg = "Not enough free space specified in amanda.conf";
} else if (message->code == 2800076) {
msg = "Holding disk '%{holding_dir}': %{size:avail} disk space available, using %{size:using}";
} else if (message->code == 2800077) {
msg = "logdir '%{logdir}' (%{errnostr})";
hint = "you must create directory";
} else if (message->code == 2800078) {
msg = "log dir '%{logdir}' (%{errnostr}): not writable";
} else if (message->code == 2800079) {
msg = "oldlog directory '%{olddir}' is not a directory";
hint = "remove the entry and create a new directory";
} else if (message->code == 2800080) {
msg = "Remove the entry and create a new directory";
} else if (message->code == 2800081) {
msg = "oldlog dir '%{oldlogdir}' (%{errnostr}): not writable";
hint = "check permissions";
} else if (message->code == 2800082) {
msg = "Check permissions";
} else if (message->code == 2800083) {
msg = "oldlog directory '%{oldlogdir}' (%{errnostr}) is not a directory";
hint = "remove the entry and create a new directory";
} else if (message->code == 2800084) {
msg = "Remove the entry and create a new directory";
} else if (message->code == 2800085) {
msg = "skipping tape test because amdump or amflush seem to be running";
hint = "if they are not, you must run amcleanup";
} else if (message->code == 2800086) {
msg = "if they are not, you must run amcleanup";
} else if (message->code == 2800087) {
msg = "amdump or amflush seem to be running";
hint = "if they are not, you must run amcleanup";
} else if (message->code == 2800088) {
msg = "if they are not, you must run amcleanup";
} else if (message->code == 2800089) {
msg = "skipping tape checks";
} else if (message->code == 2800090) {
msg = "storage '%{storage}': retentions-tapes (%{retention_tapes}) <= runspercycle (%{runspercycle})";
} else if (message->code == 2800091) {
msg = "storage '%{storage}': retentions-tapes (%{retention_tapes}) <= runtapes (%{runtapes})";
} else if (message->code == 2800092) {
msg = "conf info dir '%{infodir}' does not exist";
hint = "it will be created on the next run";
} else if (message->code == 2800093) {
msg = "it will be created on the next run.";
} else if (message->code == 2800094) {
msg = "conf info dir '%{infodir}' (%{errnostr})";
} else if (message->code == 2800095) {
msg = "info dir '%{infodir}': not a directory";
hint = "remove the entry and create a new directory";
} else if (message->code == 2800096) {
msg = "Remove the entry and create a new directory";
} else if (message->code == 2800097) {
msg = "info dir '{infodir}' (%{errnostr}): not writable";
hint = "check permissions";
} else if (message->code == 2800098) {
msg = "Check permissions";
} else if (message->code == 2800099) {
msg = "Can't copy infofile: %{errmsg}";
} else if (message->code == 2800100) {
msg = "host info dir '%{hostinfodir}' does not exist";
hint = "It will be created on the next run";
} else if (message->code == 2800101) {
msg = "it will be created on the next run";
} else if (message->code == 2800102) {
msg = "host info dir '%{hostinfodir}' (%{errnostr})";
} else if (message->code == 2800103) {
msg = "info dir '%{hostinfodir}': not a directory";
hint = "Remove the entry and create a new directory";
} else if (message->code == 2800104) {
msg = "Remove the entry and create a new directory";
} else if (message->code == 2800105) {
msg = "info dir '%{hostinfodir}': not writable";
hint = "Check permissions";
} else if (message->code == 2800106) {
msg = "Check permissions";
} else if (message->code == 2800107) {
msg = "info dir '%{diskdir}' does not exist";
hint = "it will be created on the next run";
} else if (message->code == 2800108) {
msg = "it will be created on the next run.";
} else if (message->code == 2800109) {
msg = "info dir '%{diskdir}' (%{errnostr})";
} else if (message->code == 2800110) {
msg = "info dir '%{diskdir}': not a directory";
hint = "Remove the entry and create a new directory";
} else if (message->code == 2800111) {
msg = "Remove the entry and create a new directory";
} else if (message->code == 2800112) {
msg = "info dir '%{diskdir}': not writable";
hint = "Check permissions";
} else if (message->code == 2800113) {
msg = "Check permissions";
} else if (message->code == 2800114) {
msg = "info file '%{infofile}' does not exist";
hint = "it will be created on the next run";
} else if (message->code == 2800115) {
msg = "it will be created on the next run";
} else if (message->code == 2800116) {
msg = "info dir '%{diskdir}' (%{errnostr})";
} else if (message->code == 2800117) {
msg = "info file '%{infofile}': not a file";
hint = "remove the entry and create a new file";
} else if (message->code == 2800118) {
msg = "Remove the entry and create a new file";
} else if (message->code == 2800119) {
msg = "info file '%{infofile}': not readable";
hint = "Check permissions";
} else if (message->code == 2800120) {
msg = "index dir '%{indexdir}' does not exist";
hint = "it will be created on the next run";
} else if (message->code == 2800121) {
msg = "it will be created on the next run.";
} else if (message->code == 2800122) {
msg = "index dir '%{indexdir}' (%{errnostr})";
} else if (message->code == 2800123) {
msg = "index dir '%{indexdir}': not a directory";
hint = "remove the entry and create a new directory";
} else if (message->code == 2800124) {
msg = "Remove the entry and create a new directory";
} else if (message->code == 2800125) {
msg = "index dir '%{indexdir}': not writable";
} else if (message->code == 2800126) {
msg = "index dir '%{hostindexdir}' does not exist";
hint = "it will be created on the next run";
} else if (message->code == 2800127) {
msg = "it will be created on the next run.";
} else if (message->code == 2800128) {
msg = "index dir '%{hostindexdir}' (%{errnostr})";
} else if (message->code == 2800129) {
msg = "index dir '%{hostindexdir}': not a directory";
hint = "remove the entry and create a new directory";
} else if (message->code == 2800130) {
msg = "Remove the entry and create a new directory";
} else if (message->code == 2800131) {
msg = "index dir '%{hostindexdir}': not writable";
hint = "check permissions";
} else if (message->code == 2800132) {
msg = "index dir '%{diskindexdir}' does not exist";
hint = "it will be created on the next run";
} else if (message->code == 2800133) {
msg = "it will be created on the next run.";
} else if (message->code == 2800134) {
msg = "index dir '%{diskindexdir}' (%{errnostr})";
hint = "check permissions";
} else if (message->code == 2800135) {
msg = "index dir '%{diskindexdir}': not a directory";
hint = "remove the entry and create a new directory";
} else if (message->code == 2800136) {
msg = "Remove the entry and create a new directory";
} else if (message->code == 2800137) {
msg = "index dir '%{diskindexdir}': is not writable";
hint = "check permissions";
} else if (message->code == 2800138) {
msg = "server encryption program not specified";
hint = "Specify \"server-custom-encrypt\" in the dumptype";
} else if (message->code == 2800139) {
msg = "Specify \"server-custom-encrypt\" in the dumptype";
} else if (message->code == 2800140) {
msg = "'%{program}' is not executable, server encryption will not work";
hint = "check file type";
} else if (message->code == 2800141) {
msg = "Check file type";
} else if (message->code == 2800142) {
msg = "server custom compression program not specified";
hint = "Specify \"server-custom-compress\" in the dumptype";
} else if (message->code == 2800143) {
msg = "Specify \"server-custom-compress\" in the dumptype";
} else if (message->code == 2800144) {
msg = "'%{program}' is not executable, server custom compression will not work";
hint = "check file type";
} else if (message->code == 2800145) {
msg = "Check file type";
} else if (message->code == 2800146) {
msg = "%{hostname} %{diskname}: tape-splitsize > tape size";
} else if (message->code == 2800147) {
msg = "%{hostname} %{diskname}: fallback-splitsize > total available memory";
} else if (message->code == 2800148) {
msg = "%{hostname} %{diskname}: fallback-splitsize > tape size";
} else if (message->code == 2800149) {
msg = "%{hostname} %{diskname}: tape-splitsize of %{size:tape_splitsize} < 0.1%% of tape length";
} else if (message->code == 2800151) {
msg = "%{hostname} %{diskname}: fallback-splitsize of %{size:fallback_splitsize} < 0.1%% of tape length";
} else if (message->code == 2800153) {
msg = "%{hostname} %{diskname}: Can't compress directtcp data-path";
} else if (message->code == 2800154) {
msg = "%{hostname} %{diskname}: Can't encrypt directtcp data-path";
} else if (message->code == 2800155) {
msg = "%{hostname} %{diskname}: Holding disk can't be use for directtcp data-path";
} else if (message->code == 2800156) {
msg = "%{hostname} %{diskname}: data-path is DIRECTTCP but device do not support it";
} else if (message->code == 2800157) {
msg = "%{hostname} %{diskname}: data-path is AMANDA but device do not support it";
} else if (message->code == 2800158) {
msg = "%{hostname} %{diskname}: Can't run pre-host-backup script on client";
} else if (message->code == 2800159) {
msg = "%{hostname} %{diskname}: Can't run post-host-backup script on client";
} else if (message->code == 2800160) {
msg = "Server check took %{seconds} seconds";
} else if (message->code == 2800161) {
msg = "Client %{hostname} does not support selfcheck REQ packet";
hint = "Client might be of a very old version";
} else if (message->code == 2800162) {
msg = "Client might be of a very old version";
} else if (message->code == 2800163) {
msg = "Client %{hostname} does not support selfcheck REP packet";
hint = "Client might be of a very old version";
} else if (message->code == 2800164) {
msg = "Client might be of a very old version";
} else if (message->code == 2800165) {
msg = "Client %{hostname} does not support sendsize REQ packet";
hint = "Client might be of a very old version";
} else if (message->code == 2800166) {
msg = "Client might be of a very old version";
} else if (message->code == 2800167) {
msg = "Client %{hostname} does not support sendsize REP packet";
hint = "Client might be of a very old version";
} else if (message->code == 2800168) {
msg = "Client might be of a very old version";
} else if (message->code == 2800169) {
msg = "Client %{hostname} does not support sendbackup REQ packet";
hint = "Client might be of a very old version";
} else if (message->code == 2800170) {
msg = "Client might be of a very old version";
} else if (message->code == 2800171) {
msg = "Client %{hostname} does not support sendbackup REP packet";
hint = "Client might be of a very old version";
} else if (message->code == 2800172) {
msg = "Client might be of a very old version";
} else if (message->code == 2800173) {
msg = "%{hostname}:%{diskname} %{errstr}";
} else if (message->code == 2800174) {
msg = "%{hostname}:%{diskname} (%{device}) host does not support quoted text";
hint = "You must upgrade amanda on the client to "
"specify a quoted text/device in the disklist, "
"or don't use quoted text for the device";
} else if (message->code == 2800175) {
msg = "You must upgrade amanda on the client to "
"specify a quoted text/device in the disklist, "
"or don't use quoted text for the device";
} else if (message->code == 2800176) {
msg = "%{hostname}:%{diskname} (%{device}): selfcheck does not support device";
hint = "You must upgrade amanda on the client to "
"specify a diskdevice in the disklist "
"or don't specify a diskdevice in the disklist";
} else if (message->code == 2800177) {
msg = "You must upgrade amanda on the client to "
"specify a diskdevice in the disklist "
"or don't specify a diskdevice in the disklist";
} else if (message->code == 2800178) {
msg = "%{hostname}:%{diskname} (%{device}): sendsize does not support device";
hint = "You must upgrade amanda on the client to "
"specify a diskdevice in the disklist"
"or don't specify a diskdevice in the disklist";
} else if (message->code == 2800179) {
msg = "You must upgrade amanda on the client to "
"specify a diskdevice in the disklist"
"or don't specify a diskdevice in the disklist";
} else if (message->code == 2800180) {
msg = "%{hostname}:%{diskname} (%{device}): sendbackup does not support device";
hint = "You must upgrade amanda on the client to "
"specify a diskdevice in the disklist"
"or don't specify a diskdevice in the disklist";
} else if (message->code == 2800181) {
msg = "You must upgrade amanda on the client to "
"specify a diskdevice in the disklist"
"or don't specify a diskdevice in the disklist";
} else if (message->code == 2800182) {
msg = "Client %{hostname} does not support %{data-path} data-path";
} else if (message->code == 2800183) {
msg = "Client %{hostname} does not support directtcp data-path";
} else if (message->code == 2800184) {
msg = "%{hostname}:%{diskname} does not support DUMP";
hint = "You must upgrade amanda on the client to use DUMP "
"or you can use another program";
} else if (message->code == 2800185) {
msg = "You must upgrade amanda on the client to use DUMP "
"or you can use another program";
} else if (message->code == 2800186) {
msg = "%{hostname}:%{diskname} does not support GNUTAR";
hint = "You must upgrade amanda on the client to use GNUTAR "
"or you can use another program";
} else if (message->code == 2800187) {
msg = "You must upgrade amanda on the client to use GNUTAR "
"or you can use another program";
} else if (message->code == 2800188) {
msg = "%{hostname}:%{diskname} does not support CALCSIZE for estimate, using CLIENT";
hint = "You must upgrade amanda on the client to use "
"CALCSIZE for estimate or don't use CALCSIZE for estimate";
} else if (message->code == 2800189) {
msg = "You must upgrade amanda on the client to use "
"CALCSIZE for estimate or don't use CALCSIZE for estimate";
} else if (message->code == 2800180) {
msg = "Client %{hostname} does not support custom compression";
hint = "You must upgrade amanda on the client to use custom compression\n"
"Otherwise you can use the default client compression program";
} else if (message->code == 2800191) {
msg = "You must upgrade amanda on the client to use custom compression";
} else if (message->code == 2800192) {
msg = "Otherwise you can use the default client compression program";
} else if (message->code == 2800193) {
msg = "Client %{hostname} does not support data encryption";
hint = "You must upgrade amanda on the client to use encryption program";
} else if (message->code == 2800194) {
msg = "You must upgrade amanda on the client to use encryption program";
} else if (message->code == 2800195) {
msg = "%{hostname}: Client encryption with server compression is not supported";
hint = "See amanda.conf(5) for detail";
} else if (message->code == 2800196) {
msg = "%{hostname}:%{diskname} does not support APPLICATION-API";
hint = "Dumptype configuration is not GNUTAR or DUMP. It is case sensitive";
} else if (message->code == 2800197) {
msg = "Dumptype configuration is not GNUTAR or DUMP. It is case sensitive";
} else if (message->code == 2800198) {
msg = "application '%{application}' not found";
} else if (message->code == 2800199) {
msg = "%{hostname}:%{diskname} does not support client-name in application";
} else if (message->code == 2800200) {
msg = "%{hostname}:%{diskname} does not support SCRIPT-API";
} else if (message->code == 2800201) {
msg = "WARNING: %{hostname}:%{diskname} does not support client-name in script";
} else if (message->code == 2800202) {
msg = "Amanda Backup Client Hosts Check";
} else if (message->code == 2800203) {
msg = "--------------------------------";
} else if (message->code == 2800204) {
int hostcount = atoi(message_get_argument(message, "hostcount"));
int remote_errors = atoi(message_get_argument(message, "remote_errors"));
char *a = plural("Client check: %{hostcount} host checked in %{seconds} seconds.",
"Client check: %{hostcount} hosts checked in %{seconds} seconds.",
hostcount);
char *b = plural(" %{remote_errors} problem found.",
" %{remote_errors} problems found.",
remote_errors);
msg = g_strdup_printf("%s%s", a, b);
free_msg = TRUE;
} else if (message->code == 2800206) {
msg = "%{hostname}: selfcheck request failed: %{errstr}";
} else if (message->code == 2800207) {
msg = "%{hostname}: bad features value: '%{features}'";
hint = "The amfeature in the reply packet is invalid";
} else if (message->code == 2800208) {
msg = "The amfeature in the reply packet is invalid";
} else if (message->code == 2800209) {
msg = "%{dle_hostname}";
} else if (message->code == 2800210) {
msg = "%{ok_line}";
} else if (message->code == 2800211) {
msg = "%{type}%{hostname}: %{errstr}";
} else if (message->code == 2800212) {
msg = "%{hostname}: unknown response: %{errstr}";
} else if (message->code == 2800213) {
msg = "Could not find security driver '%{auth}' for host '%{hostname}'. auth for this dle is invalid";
} else if (message->code == 2800214) {
} else if (message->code == 2800215) {
msg = "amanda.conf has dump user configured to '%{dumpuser}', but that user does not exist";
} else if (message->code == 2800216) {
msg = "cannot get username for running user, uid %{uid} is not in your user database";
} else if (message->code == 2800217) {
msg = "must be executed as the '%{expected_user}' user instead of the '%{running_user}' user";
hint = "Change user to '%{expected_user}' or change dumpuser to '%{running_user}' in amanda.conf";
} else if (message->code == 2800218) {
msg = "could not open temporary amcheck output file %{filename}: %{errnostr}";
hint = "Check permissions";
} else if (message->code == 2800219) {
msg = "could not open amcheck output file %{filename}: %{errnostr}";
hint = "Check permissions";
} else if (message->code == 2800220) {
msg = "seek temp file: %{errnostr}";
} else if (message->code == 2800221) {
msg = "fseek main file: %{errnostr}";
} else if (message->code == 2800222) {
msg = "mailfd write: %{errnostr}";
} else if (message->code == 2800223) {
msg = "mailfd write: wrote %{size:write_size} instead of %{size:expected_size}";
} else if (message->code == 2800224) {
msg = "Can't fdopen: %{errnostr}";
} else if (message->code == 2800225) {
msg = "error running mailer %{mailer}: %{errmsg}";
} else if (message->code == 2800226) {
msg = "could not spawn a process for checking the server: %{errnostr}";
} else if (message->code == 2800227) {
msg = "nullfd: /dev/null: %{errnostr}";
} else if (message->code == 2800228) {
msg = "errors processing config file";
} else if (message->code == 2800229) {
msg = "Invalid mailto address '%{mailto}'";
} else if (message->code == 2800230) {
msg = "Can't open '%{filename}' for reading: %{errnostr}";
} else if (message->code == 2800231) {
msg = "Multiple DLE's for host '%{hostname}' use different auth methods";
hint = "Please ensure that all DLE's for the host use the same auth method, including skipped ones";
} else if (message->code == 2800232) {
msg = "Multiple DLE's for host '%{hostname}' use different maxdumps values";
hint = "Please ensure that all DLE's for the host use the same maxdumps value, including skipped ones";
} else if (message->code == 2800233) {
msg = "%{hostname} %{diskname}: The tag '%{tag}' match none of the storage dump_selection";
} else if (message->code == 2800234) {
msg = "%{hostname} %{diskname}: holdingdisk NEVER with tags matching more than one storage, will be dumped to only one storage";
} else if (message->code == 2800235) {
msg = "program %{program}: wrong permission, must be 'rwsr-x---'";
} else if (message->code == 2900000) {
msg = "The Application '%{application}' failed: %{errmsg}";
} else if (message->code == 2900001) {
msg = "Can't execute application '%{application}'";
} else if (message->code == 2900002) {
msg = "The application '%{application}' does not support the '%{method}' method";
} else if (message->code == 2900003) {
msg = "%{service} only works with application";
} else if (message->code == 2900004) {
msg = "Missing OPTIONS line in %{service} request";
} else if (message->code == 2900005) {
msg = "Application '%{application}': can't create pipe";
} else if (message->code == 2900006) {
msg = "Can't dup2: %{errno} %{errnocode} %{errnostr}";
} else if (message->code == 2900007) {
msg = "%{service} require fe_req_xml";
} else if (message->code == 2900008) {
msg = "no valid %{service} request";
} else if (message->code == 2900009) {
msg = "no valid %{service} request";
} else if (message->code == 2900010) {
msg = "fork of '%{application} failed: %{errno} %{errnocode} %{errnostr}";
} else if (message->code == 2900011) {
msg = "Can't fdopen: %{errno} %{errnocode} %{errnostr}";
} else if (message->code == 2900012) {
msg = "%{application} failed: %{errmsg}";
} else if (message->code == 2900013) {
msg = "REQ XML error: %{errmsg}";
} else if (message->code == 2900014) {
msg = "One DLE required in XML REQ packet";
} else if (message->code == 2900015) {
msg = "Only one DLE allowed in XML REQ packet";
} else if (message->code == 2900016) {
msg = "Application '%{application}' (pid %{pid}) got signal %{signal}";
} else if (message->code == 2900017) {
msg = "Application '%{application}' (pid %{pid}) returned %{return_code}";
} else if (message->code == 2900018) {
msg = "%{name}: %{errmsg}";
} else if (message->code == 3100005) {
msg = "senddiscover result";
} else if (message->code == 3100006) {
msg = "no senddiscover result to list";
} else if (message->code == 3600000) {
msg = "version '%{version}";
} else if (message->code == 3600001) {
msg = "distro %{distro}";
} else if (message->code == 3600002) {
msg = "platform %{platform}";
} else if (message->code == 3600003) {
msg = "Multiple OPTIONS line in selfcheck input";
} else if (message->code == 3600004) {
msg = "OPTIONS features=%{features};hostname=%{hostname};";
} else if (message->code == 3600005) {
msg = "%{errstr}";
} else if (message->code == 3600006) {
msg = "Missing OPTIONS line in selfcheck input";
} else if (message->code == 3600007) {
msg = "FORMAT ERROR IN REQUEST PACKET %{err_extra}";
} else if (message->code == 3600008) {
msg = "FORMAT ERROR IN REQUEST PACKET";
} else if (message->code == 3600009) {
msg = "samba support only one exclude file";
} else if (message->code == 3600010) {
msg = "samba does not support exclude list";
} else if (message->code == 3600011) {
msg = "samba does not support include file";
} else if (message->code == 3600012) {
msg = "samba does not support include list";
} else if (message->code == 3600013) {
msg = "DUMP does not support exclude file";
} else if (message->code == 3600014) {
msg = "DUMP does not support exclude list";
} else if (message->code == 3600015) {
msg = "DUMP does not support include file";
} else if (message->code == 3600016) {
msg = "DUMP does not support include list";
} else if (message->code == 3600017) {
msg = "client configured for auth=%{auth} while server requested '%{auth-requested}'";
} else if (message->code == 3600018) {
msg = "The auth in ~/.ssh/authorized_keys should be \"--auth=ssh\", or use another auth for the DLE";
} else if (message->code == 3600019) {
msg = "The auth in the inetd/xinetd configuration must be the same as the DLE";
} else if (message->code == 3600020) {
msg = "%{device}: Can't use CALCSIZE for samba estimate, use CLIENT";
} else if (message->code == 3600021) {
msg = "%{device}: cannot parse for share/subdir disk entry";
} else if (message->code == 3600022) {
msg = "%{device}: subdirectory specified but samba is not v2 or better";
} else if (message->code == 3600023) {
msg = "%{device}: cannot find password";
} else if (message->code == 3600024) {
msg = "%{device}: password field not 'user%%pass'";
} else if (message->code == 3600025) {
msg = "%{device}: cannot make share name";
} else if (message->code == 3600026) {
msg = "%{device}: Cannot access /dev/null: %{errnostr}";
} else if (message->code == 3600027) {
msg = "%{device}: password write failed: %{errnostr}";
} else if (message->code == 3600028) {
msg = "%{device}: Can't fdopen ferr: %{errnostr}";
} else if (message->code == 3600029) {
msg = "%{device}: samba access error:";
} else if (message->code == 3600030) {
msg = "%{device}: This client is not configured for samba";
} else if (message->code == 3600031) {
msg = "%{device}: The DUMP program cannot handle samba shares, use the amsamba application";
} else if (message->code == 3600032) {
msg = "%{device}: Application '%{application}': %{errstr}";
} else if (message->code == 3600033) {
msg = "%{device}: Application '%{application}': can't run 'support' command";
} else if (message->code == 3600034) {
msg = "%{device}: Application '%{application}': doesn't support amanda data-path";
} else if (message->code == 3600035) {
msg = "%{device}: Application '%{application}': doesn't support directtcp data-path";
} else if (message->code == 3600036) {
msg = "%{device}: Application '%{application}': doesn't support calcsize estimate";
} else if (message->code == 3600037) {
msg = "%{device}: Application '%{application}': doesn't support include-file";
} else if (message->code == 3600038) {
msg = "%{device}: Application '%{application}': doesn't support include-list";
} else if (message->code == 3600039) {
msg = "%{device}: Application '%{application}': doesn't support optional include";
} else if (message->code == 3600040) {
msg = "%{device}: Application '%{application}': doesn't support exclude-file";
} else if (message->code == 3600041) {
msg = "%{device}: Application '%{application}': doesn't support exclude-list";
} else if (message->code == 3600042) {
msg = "%{device}: Application '%{application}': doesn't support optional exclude";
} else if (message->code == 3600043) {
msg = "%{device}: Application '%{application}': can't create pipe: %{errnostr}";
} else if (message->code == 3600044) {
msg = "%{device}: Application '%{application}': fork failed: %{errnostr}";
} else if (message->code == 3600045) {
msg = "%{device}: Can't execute '%{cmd}': %{errnostr}";
} else if (message->code == 3600046) {
msg = "%{device}: Can't fdopen app_stderr: %{errnostr}";
} else if (message->code == 3600047) {
msg = "%{device}: Application '%{application}': %{errstr}";
} else if (message->code == 3600048) {
msg = "%{device}: waitpid failed: %{errnostr}";
} else if (message->code == 3600049) {
msg = "%{device}: Application '%{application}': exited with signal %{signal}";
} else if (message->code == 3600050) {
msg = "%{device}: Application '%{application}': exited with status %{exit_status}";
} else if (message->code == 3600051) {
msg = "%{hostname}: Could not %{type} %{disk} (%{device}): %{errnostr}";
} else if (message->code == 3600052) {
msg = "%{disk}";
} else if (message->code == 3600053) {
msg = "%{amdevice}";
} else if (message->code == 3600054) {
msg = "%{device}";
} else if (message->code == 3600055) {
msg = "%{device}: Can't fdopen app_stdout: %{errnostr}";
} else if (message->code == 3600056) {
msg = "%{ok_line}";
} else if (message->code == 3600057) {
msg = "%{error_line}";
} else if (message->code == 3600058) {
msg = "%{errstr}";
} else if (message->code == 3600059) {
msg = "%{filename} is not a file";
} else if (message->code == 3600060) {
msg = "can not stat '%{filename}': %{errnostr}";
} else if (message->code == 3600061) {
msg = "%{dirname} is not a directory";
} else if (message->code == 3600062) {
msg = "can not stat '%{dirname}': %{errnostr}";
} else if (message->code == 3600063) {
msg = "can not %{noun} '%{filename}': %{errnostr} (ruid:%{ruid} euid:%{euid})";
} else if (message->code == 3600064) {
msg = "%{filename} %{adjective} (ruid:%{ruid} euid:%{euid})";
} else if (message->code == 3600065) {
msg = "%{filename} is not owned by root";
} else if (message->code == 3600066) {
msg = "%{filename} is not SUID root";
} else if (message->code == 3600067) {
msg = "can not stat '%{filename}': %{errnostr}";
} else if (message->code == 3600068) {
msg = "cannot get filesystem usage for '%{dirname}: %{errnostr}";
} else if (message->code == 3600069) {
msg = "dir '%{dirname}' needs %{size:required}, has nothing available";
} else if (message->code == 3600070) {
msg = "dir '%{dirname}' needs %{size:required}, only has %{size:avail} available";
} else if (message->code == 3600071) {
msg = "dir '%{dirname}' has more than %{size:avail} available";
} else if (message->code == 3600072) {
msg = "DUMP program not available";
} else if (message->code == 3600073) {
msg = "RESTORE program not available";
} else if (message->code == 3600074) {
msg = "VDUMP program not available";
} else if (message->code == 3600075) {
msg = "VRESTORE program not available";
} else if (message->code == 3600076) {
msg = "XFSDUMP program not available";
} else if (message->code == 3600077) {
msg = "XFSRESTORE program not available";
} else if (message->code == 3600078) {
msg = "VXDUMP program not available";
} else if (message->code == 3600079) {
msg = "VXRESTORE program not available";
} else if (message->code == 3600080) {
msg = "GNUTAR program not available";
} else if (message->code == 3600081) {
msg = "SMBCLIENT program not available";
} else if (message->code == 3600082) {
msg = "/etc/amandapass is world readable!";
} else if (message->code == 3600083) {
msg = "/etc/amandapass is readable, but not by all";
} else if (message->code == 3600084) {
msg = "unable to stat /etc/amandapass: %{errnostr}";
} else if (message->code == 3600085) {
msg = "unable to open /etc/amandapass: %{errnostr}";
} else if (message->code == 3600086) {
msg = "dump will not be able to create the /etc/dumpdates file: %{errnostr}";
} else if (message->code == 3600087) {
msg = "%{device}: samba access error: %{errmsg}";
} else if (message->code == 3600088) {
msg = "file/dir '%{filename}' (%{security_orig}) is not owned by root";
} else if (message->code == 3600089) {
msg = "file/dir '%{filename}' (%{security_orig}) is writable by everyone";
} else if (message->code == 3600090) {
msg = "file/dir '%{filename}' (%{security_orig}) is writable by the group";
} else if (message->code == 3600091) {
msg = "Can't find real path for '%{filename}': %{errnostr}";
} else if (message->code == 3600092) {
msg = "security file '%{security_file}' do not allow to run '%{filename}' as root for %{pname}:%{type}";
} else if (message->code == 3600093) {
msg = "security_file_check_path: prefix is not set";
} else if (message->code == 3600094) {
msg = "security_file_check_path: path is not set";
} else if (message->code == 3600095) {
msg = "Can't open security_file (%{security_file}): %{errnostr}";
} else if (message->code == 3600096) {
msg = "security file '%{security_file}' do not allow to run '%{path}' as root for '%{prefix}'";
} else if (message->code == 3600097) {
msg = "Can't get realpath of the security file '%{security_file}': %{errnostr}";
} else if (message->code == 3600098) {
msg = "can not stat '%{filename}' (%{security_orig}): %{errnostr}";
} else if (message->code == 3700000) {
msg = "%{disk}";
} else if (message->code == 3700001) {
msg = "amgtar version %{version}";
} else if (message->code == 3700002) {
msg = "amgtar gtar-version %{gtar-version}";
} else if (message->code == 3700003) {
msg = "Can't get %{gtar-path} version";
} else if (message->code == 3700004) {
msg = "amgtar";
} else if (message->code == 3700005) {
msg = "GNUTAR program not available";
} else if (message->code == 3700006) {
msg = "No GNUTAR-LISTDIR";
} else if (message->code == 3700007) {
msg = "bad ONE-FILE-SYSTEM property value '%{value}'";
} else if (message->code == 3700008) {
msg = "bad SPARSE property value '%{value}'";
} else if (message->code == 3700009) {
msg = "bad ATIME-PRESERVE property value '%{value}'";
} else if (message->code == 3700010) {
msg = "bad CHECK-DEVICE property value '%{value}'";
} else if (message->code == 3700011) {
msg = "bad NO-UNQUOTE property value '%{value}'";
} else if (message->code == 3700012) {
msg = "Can't open disk '%{diskname}': %{errnostr}";
} else if (message->code == 3700013) {
msg = "Cannot stat the disk '%{diskname}': %{errnostr}";
} else if (message->code == 3700014) {
msg = "Invalid '%{command-options}' COMMAND-OPTIONS";
} else if (message->code == 3700015) {
msg = "bad DAR property value '%{property_value}'";
} else if (message->code == 3701000) {
msg = "%{disk}";
} else if (message->code == 3701001) {
msg = "amstar version %{version}";
} else if (message->code == 3701002) {
msg = "amstar star-version %{star-version}";
} else if (message->code == 3701003) {
msg = "Can't get %{star-path} version";
} else if (message->code == 3701004) {
msg = "amstar";
} else if (message->code == 3701005) {
msg = "STAR program not available";
} else if (message->code == 3701008) {
msg = "bad SPARSE property value '%{value}'";
} else if (message->code == 3701014) {
msg = "Invalid '%{command-options}' COMMAND-OPTIONS";
} else if (message->code == 3701016) {
msg = "bad ACL property value '%{value}'";
} else if (message->code == 3701017) {
msg = "Can't use include and exclude simultaneously";
} else if (message->code == 3701018) {
msg = "%{directory}";
} else if (message->code == 3701019) {
msg = "%{device}";
} else if (message->code == 3702000) {
msg = "%{disk}";
} else if (message->code == 3702001) {
msg = "ambsdtar version %{version}";
} else if (message->code == 3702002) {
msg = "ambsdtar bsdtar-version %{bsdtar-version}";
} else if (message->code == 3702003) {
msg = "Can't get %{bsdtar-path} version";
} else if (message->code == 3702004) {
msg = "ambsdtar";
} else if (message->code == 3702005) {
msg = "BSDTAR program not available";
} else if (message->code == 3702007) {
msg = "bad ONE-FILE-SYSTEM property value '%{value}'";
} else if (message->code == 3702014) {
msg = "Invalid '%{command-options}' COMMAND-OPTIONS";
} else if (message->code == 3702020) {
msg = "No STATE-DIR";
} else if (message->code == 4600000) {
msg = "%{errmsg}";
} else if (message->code == 4600001) {
msg = "ERROR %{errmsg}";
} else if (message->code == 4600002) {
msg = "Can't open exclude file '%{exclude}': %{errnostr}";
} else if (message->code == 4600003) {
msg = "Can't create exclude file '%{exclude}': %{errnostr}";
} else if (message->code == 4600004) {
msg = "Can't create '%{filename}': %{errnostr}";
} else if (message->code == 4600005) {
msg = "include must start with './' (%{include})";
} else if (message->code == 4600006) {
msg = "Can't open include file '%{include}': %{errnostr}";
} else if (message->code == 4600007) {
msg = "Can't create include file '%{include}': %{errnostr}";
} else if (message->code == 4600008) {
msg = "Nothing found to include for disk '%{disk}'";
} else {
msg = "no message for code '%{code}'";
}
result = fix_message_string(message, want_quoted, msg);
if (want_quoted) {
if (result) {
message->quoted_msg = g_string_free(result, FALSE);
}
} else {
if (result) {
message->msg = g_string_free(result, FALSE);
}
result = fix_message_string(message, FALSE, hint);
if (result) {
message->hint = g_string_free(result, FALSE);
}
}
if (free_msg)
g_free(msg);
}
static GString *
fix_message_string(
message_t *message,
gboolean want_quoted,
char *msg)
{
char *m;
char num[NUM_STR_SIZE];
char code[100];
char *c;
int i;
char *quoted;
GString *result;
if (!msg)
return NULL;
result = g_string_sized_new(strlen(msg)*2);
for (m = msg; *m != '\0'; m++) {
c = code;
if (*m == '%' && *(m+1) == '%') {
g_string_append_c(result, *m);
m++;
} else if (*m == '%' && *(m+1) == '{') {
m += 2;
while (*m != '}') {
*c++ = *m++;
}
*c = '\0';
if (strcmp(code, "file") == 0) {
if (want_quoted) {
quoted = quote_string(message->file);
g_string_append(result, quoted);
g_free(quoted);
} else {
g_string_append(result, message->file);
}
} else if (strcmp(code, "line") == 0) {
g_snprintf(num, sizeof(num),
"%d", message->line);
g_string_append(result, num);
} else if (strcmp(code, "code") == 0) {
g_snprintf(num, sizeof(num),
"%d", message->code);
g_string_append(result, num);
} else if (strcmp(code, "severity") == 0) {
g_string_append(result, severity_name(message->severity));
} else if (strcmp(code, "errnostr") == 0) {
g_string_append(result, message->errnostr);
} else if (strcmp(code, "errnocode") == 0) {
g_string_append(result, message->errnocode);
} else {
char *c = strchr(code, ':');
char *format = NULL;
char *ccode = code;
if (c) {
*c = '\0';
format = code;
ccode = c+1;
}
i = 0;
while (message->arg_array[i].key != NULL &&
strcmp(message->arg_array[i].key, ccode) != 0) {
i++;
}
if (message->arg_array[i].key != NULL) {
if (format) {
assert(message->arg_array[i].value.type == JSON_STRING);
if (strcmp(format,"size") == 0) {
long long llvalue = atoll(message->arg_array[i].value.string);
g_string_append_printf(result, "%lld %sB", llvalue/getconf_unit_divisor(),
getconf_str(CNF_DISPLAYUNIT));
} else {
g_string_append(result, "BAD-FORMAT");
}
} else {
if (message->arg_array[i].value.type == JSON_NULL) {
} else if (message->arg_array[i].value.type == JSON_STRING) {
if (message->arg_array[i].value.string == NULL) {
g_string_append(result, "null");
} else if (want_quoted) {
quoted = quote_string(message->arg_array[i].value.string);
g_string_append(result, quoted);
g_free(quoted);
} else {
g_string_append(result, message->arg_array[i].value.string);
}
}
}
} else {
g_string_append(result, "NONE");
}
}
} else {
g_string_append_c(result, *m);
}
}
return result;
}
char *
get_message(
message_t *message)
{
return message->msg;
}
char *
get_quoted_message(
message_t *message)
{
if (!message->quoted_msg)
set_message(message, 1);
return message->quoted_msg;
}
char *
message_get_hint(
message_t *message)
{
return message->hint;
}
int
message_get_code(
message_t *message)
{
return message->code;
}
int
message_get_severity(
message_t *message)
{
return message->severity;
}
static void free_message_value_full(gpointer);
static void free_message_value(gpointer);
static void
free_message_value(
gpointer pointer)
{
amjson_t *value = pointer;
if (value->type == JSON_STRING) {
g_free(value->string);
value->string = NULL;
} else if (value->type == JSON_ARRAY) {
guint i;
for (i = 0; i < value->array->len; i++) {
free_message_value_full(g_ptr_array_index(value->array, i));
}
g_ptr_array_free(value->array, TRUE);
value->array = NULL;
} else if (value->type == JSON_HASH) {
g_hash_table_destroy(value->hash);
value->hash = NULL;
}
value->type = JSON_NULL;
}
static void
free_message_value_full(
gpointer pointer)
{
amjson_t *value = pointer;
free_message_value(pointer);
g_free(value);
}
void
delete_message(
message_t *message)
{
int i;
if (message == NULL)
return;
g_free(message->file);
g_free(message->msg);
g_free(message->quoted_msg);
g_free(message->errnostr);
for (i = 0; message->arg_array[i].key != NULL; i++) {
g_free(message->arg_array[i].key);
free_message_value(&(message->arg_array[i].value));
}
g_free(message->process);
g_free(message->running_on);
g_free(message->component);
g_free(message->module);
g_free(message->arg_array);
g_free(message);
}
void
delete_message_gpointer(
gpointer data)
{
delete_message((message_t *)data);
}
message_t *
build_message(
char *file,
int line,
int code,
int severity,
int nb,
...)
{
message_t *message = g_new0(message_t, 1);
va_list marker;
int i, j;
init_errcode();
message->file = g_strdup(file);
message->line = line;
message->process = g_strdup(get_pname());
message->running_on = g_strdup(get_running_on());
message->component = g_strdup(get_pcomponent());
message->module = g_strdup(get_pmodule());
message->code = code;
message->severity = severity;
message->argument_allocated = nb+1,
message->arg_array = g_new0(message_arg_array_t, nb+2);
va_start(marker, nb); /* Initialize variable arguments. */
for (i = 0,j = 0; i < nb; i++) {
char *key = va_arg(marker, char *);
if (strcmp(key,"errno") == 0) {
int m_errno = va_arg(marker, int);
message->merrno = m_errno;
if (m_errno < MAX_ERRCODE) {
message->errnocode = errcode[m_errno];
} else {
message->errnocode = "UNKNOWN";
}
message->errnostr = g_strdup(strerror(m_errno));
} else {
message->arg_array[j].key = g_strdup(key);
message->arg_array[j].value.type = JSON_STRING;
message->arg_array[j].value.string = g_strdup(va_arg(marker, char *));
j++;
}
}
message->arg_array[j].key = NULL;
message->arg_array[j].value.type = JSON_NULL;
message->arg_array[j].value.string = NULL;
va_end( marker );
set_message(message, 0);
g_debug("new message: %s:%d:%d:%d %s", message->file, message->line, message->severity, message->code, message->msg);
return message;
}
static int message_indent = 4;
typedef struct message_hash_s {
GString *r;
int first;
} message_hash_t;
static void sprint_message_hash(gpointer key, gpointer value, gpointer user_data);
static char *sprint_message_value(amjson_t *value);
static void
sprint_message_hash(
gpointer gkey,
gpointer gvalue,
gpointer user_data)
{
char *key = gkey;
amjson_t *value = gvalue;
message_hash_t *mh = user_data;
char *result_value = sprint_message_value((amjson_t *)value);
if (!mh->first) {
g_string_append(mh->r, ",\n");
} else {
mh->first = 0;
}
g_string_append_printf(mh->r,"%*c\"%s\" : %s", message_indent, ' ', (char *)key, result_value);
g_free(result_value);
}
static char *
sprint_message_value(
amjson_t *value)
{
char *result = NULL;
switch (value->type) {
case JSON_TRUE :
result = g_strdup("true");
break;
case JSON_FALSE :
result = g_strdup("false");
break;
case JSON_NULL :
result = g_strdup("null");
break;
case JSON_NUMBER :
result = g_strdup_printf("%lld", (long long)value->number);
break;
case JSON_STRING :
{
char *encoded = ammessage_encode_json(value->string);
result = g_strdup_printf("\"%s\"", encoded);
g_free(encoded);
}
break;
case JSON_HASH :
if (g_hash_table_size(value->hash) == 0) {
result = g_strdup("{ }");
} else {
GString *r = g_string_sized_new(512);
message_hash_t mh = {r, 1};
g_string_append(r, "{\n");
message_indent += 2;
g_hash_table_foreach(value->hash, sprint_message_hash, &mh);
message_indent -= 2;
g_string_append_printf(r, "\n%*c}", message_indent, ' ');
result = g_string_free(r, FALSE);
}
break;
case JSON_ARRAY :
if (value->array->len == 0) {
result = g_strdup("[ ]");
} else {
GString *r = g_string_sized_new(512);
guint i;
g_string_append(r, "[\n");
message_indent += 2;
for (i = 0; i < value->array->len; i++) {
char *result_value = sprint_message_value(g_ptr_array_index(value->array, i));
if (i>0) {
g_string_append(r, ",\n");
}
g_string_append_printf(r, "%*c", message_indent, ' ');
g_string_append(r, result_value);
g_free(result_value);
}
message_indent -= 2;
g_string_append_printf(r, "\n%*c]", message_indent, ' ');
result = g_string_free(r, FALSE);
}
break;
case JSON_BAD:
assert(0);
break;
}
return result;
}
char *
sprint_message(
message_t *message)
{
int i;
static int first_message = 1;
GString *result;
char *json_file;
char *json_process;
char *json_running_on;
char *json_component;
char *json_module;
char *json_msg;
if (message == NULL)
return NULL;
message_indent = 4;
json_file = ammessage_encode_json(message->file);
json_process = ammessage_encode_json(message->process);
json_running_on = ammessage_encode_json(message->running_on);
json_component = ammessage_encode_json(message->component);
json_module = ammessage_encode_json(message->module);
result = g_string_sized_new(512);
if (first_message) {
first_message = 0;
} else {
g_string_append_printf(result, ",\n");
}
g_string_append_printf(result,
" {\n" \
" \"source_filename\" : \"%s\",\n" \
" \"source_line\" : \"%d\",\n" \
" \"severity\" : \"%s\",\n" \
" \"process\" : \"%s\",\n" \
" \"running_on\" : \"%s\",\n" \
" \"component\" : \"%s\",\n" \
" \"module\" : \"%s\",\n" \
" \"code\" : \"%d\",\n" \
, json_file, message->line, severity_name(message->severity), json_process, json_running_on, json_component, json_module, message->code);
if (message->merrno) {
g_string_append_printf(result,
" \"merrno\" : \"%d\",\n", message->merrno);
}
if (message->errnocode) {
g_string_append_printf(result,
" \"errnocode\" : \"%s\",\n", message->errnocode);
}
if (message->errnostr) {
char *result_value = ammessage_encode_json(message->errnostr);
g_string_append_printf(result,
" \"errnostr\" : \"%s\",\n", result_value);
g_free(result_value);
}
for (i = 0; message->arg_array[i].key != NULL; i++) {
char *json_key = ammessage_encode_json(message->arg_array[i].key);
char *result_value = sprint_message_value(&message->arg_array[i].value);
g_string_append_printf(result,
" \"%s\" : %s,\n", json_key, result_value);
g_free(json_key);
g_free(result_value);
}
if (!message->msg) {
set_message(message, 0);
}
json_msg = ammessage_encode_json(message->msg);
g_string_append_printf(result,
" \"message\" : \"%s\"" \
, json_msg);
if (message->hint) {
char *json_hint = ammessage_encode_json(message->hint);
g_string_append_printf(result,
",\n \"hint\" : \"%s\"" \
, message->hint);
g_free(json_hint);
}
g_string_append_printf(result,
"\n }");
g_free(json_file);
g_free(json_process);
g_free(json_running_on);
g_free(json_component);
g_free(json_module);
g_free(json_msg);
return g_string_free(result, FALSE);
}
message_t *
print_message(
message_t *message)
{
char *msg;
if (message == NULL)
return NULL;
msg = sprint_message(message);
g_printf("%s", msg);
g_free(msg);
return message;
}
message_t *
fprint_message(
FILE *stream,
message_t *message)
{
char *msg;
if (message == NULL)
return NULL;
msg = sprint_message(message);
g_fprintf(stream, "%s", msg);
g_free(msg);
return message;
}
message_t *
fdprint_message(
int fd,
message_t *message)
{
char *msg;
if (message == NULL)
return NULL;
msg = sprint_message(message);
full_write(fd, msg, strlen(msg));
g_free(msg);
return message;
}
static void parse_json_hash(char *s, int *i, GHashTable *hash);
static void parse_json_array(char *s, int *i, GPtrArray *array);
static void
parse_json_array(
char *s,
int *i,
GPtrArray *array)
{
int len = strlen(s);
char *token;
amjson_type_t message_token;
(*i)++;
for (; *i < len && s[*i] != '\0'; (*i)++) {
char c = s[*i];
switch (c) {
case '[':
{
amjson_t *value = g_new(amjson_t, 1);
value->type = JSON_HASH;
value->array = g_ptr_array_sized_new(10);
g_ptr_array_add(array, value);
parse_json_hash(s, i, value->hash);
}
break;
case ']':
return;
break;
case '{':
{
amjson_t *value = g_new(amjson_t, 1);
value->type = JSON_HASH;
value->hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_message_value_full);
g_ptr_array_add(array, value);
parse_json_hash(s, i, value->hash);
}
break;
case '}':
assert(array);
return;
case '"':
token = json_parse_string(s, i, len);
assert(token);
{
amjson_t *value = g_new(amjson_t, 1);
value->type = JSON_STRING;
value->string = token;
g_ptr_array_add(array, value);
}
token = NULL;
break;
case '\t':
case '\r':
case '\n':
case ':':
case ',':
case ' ':
break;
default:
message_token = parse_json_primitive(s, i, len);
if (message_token != JSON_BAD) {
amjson_t *value = g_new(amjson_t, 1);
value->type = message_token;
value->string = NULL;
g_ptr_array_add(array, value);
}
token = NULL;
break;
}
}
return;
}
static void
parse_json_hash(
char *s,
int *i,
GHashTable *hash)
{
int len = strlen(s);
char *token;
amjson_type_t message_token;
gboolean expect_key = TRUE;
char *key = NULL;
(*i)++;
for (; *i < len && s[*i] != '\0'; (*i)++) {
char c = s[*i];
switch (c) {
case '[':
if (key) {
amjson_t *value = g_new(amjson_t, 1);
value->type = JSON_ARRAY;
value->array = g_ptr_array_sized_new(10);
g_hash_table_insert(hash, key, value);
parse_json_array(s, i, value->array);
key = NULL;
expect_key = TRUE;
}
break;
case ']':
break;
case '{':
if (key) {
amjson_t *value = g_new(amjson_t, 1);
value->type = JSON_HASH;
value->hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_message_value_full);
g_hash_table_insert(hash, key, value);
parse_json_hash(s, i, value->hash);
key = NULL;
expect_key = TRUE;
} else {
}
break;
case '}':
assert(hash);
return;
case '"':
token = json_parse_string(s, i, len);
assert(token);
if (expect_key) {
expect_key = FALSE;
key = token;
} else {
amjson_t *value = g_new(amjson_t, 1);
expect_key = TRUE;
value->type = JSON_STRING;
value->string = token;
g_hash_table_insert(hash, key, value);
key = NULL;
expect_key = TRUE;
}
token = NULL;
break;
case '\t':
case '\r':
case '\n':
case ':':
case ',':
case ' ':
break;
default:
message_token = parse_json_primitive(s, i, len);
if (expect_key) {
assert(0);
expect_key = FALSE;
key = token;
} else if (message_token != JSON_BAD) {
amjson_t *value = g_new(amjson_t, 1);
expect_key = TRUE;
value->type = message_token;
value->string = NULL;
g_hash_table_insert(hash, key, value);
expect_key = TRUE;
} else {
g_critical("JSON_BAD");
}
token = NULL;
break;
}
}
return;
}
GPtrArray *
parse_json_message(
char *s)
{
int i;
int len = strlen(s);
GPtrArray *message_array = g_ptr_array_sized_new(100);
char *token;
amjson_type_t message_token;
message_t *message = NULL;
gboolean expect_key = TRUE;
char *key = NULL;
int nb_arg = 0;
for (i = 0; i < len && s[i] != '\0'; i++) {
char c = s[i];
switch (c) {
case '[':
if (message && key) {
message->arg_array[nb_arg].key = key;
message->arg_array[nb_arg].value.type = JSON_ARRAY;
message->arg_array[nb_arg].value.array = g_ptr_array_sized_new(10);
nb_arg++;
if (nb_arg >= message->argument_allocated) {
message->argument_allocated *=2;
message->arg_array = g_realloc(message->arg_array, (message->argument_allocated+1) * sizeof(message_arg_array_t));
}
message->arg_array[nb_arg].key = NULL;
message->arg_array[nb_arg].value.type = JSON_NULL;
message->arg_array[nb_arg].value.string = NULL;
parse_json_array(s, &i, message->arg_array[nb_arg-1].value.array);
key = NULL;
expect_key = TRUE;
}
break;
case ']':
break;
case '{':
if (message && key) {
message->arg_array[nb_arg].key = key;
message->arg_array[nb_arg].value.type = JSON_HASH;
message->arg_array[nb_arg].value.hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_message_value_full);
nb_arg++;
if (nb_arg >= message->argument_allocated) {
message->argument_allocated *=2;
message->arg_array = g_realloc(message->arg_array, (message->argument_allocated+1) * sizeof(message_arg_array_t));
}
message->arg_array[nb_arg].key = NULL;
message->arg_array[nb_arg].value.type = JSON_NULL;
message->arg_array[nb_arg].value.string = NULL;
parse_json_hash(s, &i, message->arg_array[nb_arg-1].value.hash);
key = NULL;
expect_key = TRUE;
} else {
message = g_new0(message_t, 1);
nb_arg = 0;
message->argument_allocated = 10;
message->arg_array = g_new0(message_arg_array_t, message->argument_allocated+1);
}
break;
case '}':
assert(message);
if (message->merrno != 0 && message->errnocode == NULL) {
if (message->merrno < MAX_ERRCODE) {
message->errnocode = errcode[message->merrno];
} else {
message->errnocode = "UNKNOWN";
}
}
if (message->merrno != 0 && message->errnostr == NULL) {
message->errnostr = g_strdup(strerror(message->merrno));
}
g_ptr_array_add(message_array, message);
message = NULL;
break;
case '"':
token = json_parse_string(s, &i, len);
assert(token);
assert(message);
if (expect_key) {
expect_key = FALSE;
assert(key == NULL);
key = token;
} else {
assert(key != NULL);
expect_key = TRUE;
if (strcmp(key, "source_filename") == 0) {
g_free(key);
key = NULL;
message->file = token;
} else if (strcmp(key, "source_line") == 0) {
g_free(key);
key = NULL;
message->line = atoi(token);
g_free(token);
} else if (strcmp(key, "severity") == 0) {
g_free(key);
key = NULL;
if (strcmp(token, "success") == 0) {
message->severity = MSG_SUCCESS;
} else if (strcmp(token, "info") == 0) {
message->severity = MSG_INFO;
} else if (strcmp(token, "message") == 0) {
message->severity = MSG_MESSAGE;
} else if (strcmp(token, "warning") == 0) {
message->severity = MSG_WARNING;
} else if (strcmp(token, "error") == 0) {
message->severity = MSG_ERROR;
} else { /* critical or any other value */
message->severity = MSG_CRITICAL;
}
g_free(token);
} else if (strcmp(key, "code") == 0) {
g_free(key);
key = NULL;
message->code = atoi(token);
g_free(token);
} else if (strcmp(key, "message") == 0) {
g_free(key);
key = NULL;
message->msg = token;
} else if (strcmp(key, "hint") == 0) {
g_free(key);
key = NULL;
message->hint = token;
} else if (strcmp(key, "process") == 0) {
g_free(key);
key = NULL;
message->process = token;
} else if (strcmp(key, "running_on") == 0) {
g_free(key);
key = NULL;
message->running_on = token;
} else if (strcmp(key, "component") == 0) {
g_free(key);
key = NULL;
message->component = token;
} else if (strcmp(key, "module") == 0) {
g_free(key);
key = NULL;
message->module = token;
} else if (strcmp(key, "errno") == 0) {
g_free(key);
key = NULL;
message->merrno = atoi(token);
g_free(token);
} else if (strcmp(key, "errnocode") == 0) {
g_free(key);
key = NULL;
message->errnocode = token;
} else if (strcmp(key, "errnostr") == 0) {
g_free(key);
key = NULL;
message->errnostr = token;
} else {
message->arg_array[nb_arg].key = key;
key = NULL;
message->arg_array[nb_arg].value.type = JSON_STRING;
message->arg_array[nb_arg].value.string = token;
nb_arg++;
if (nb_arg >= message->argument_allocated) {
message->argument_allocated *=2;
message->arg_array = g_realloc(message->arg_array, (message->argument_allocated+1) * sizeof(message_arg_array_t));
}
message->arg_array[nb_arg].key = NULL;
message->arg_array[nb_arg].value.type = JSON_NULL;
message->arg_array[nb_arg].value.string = NULL;
}
}
token = NULL;
break;
case '\t':
case '\r':
case '\n':
case ':':
case ',':
case ' ':
break;
default:
message_token = parse_json_primitive(s, &i, len);
if (expect_key) {
assert(0);
expect_key = FALSE;
key = g_strdup(token);
} else if (message_token != JSON_BAD) {
message->arg_array[nb_arg].key = key;
message->arg_array[nb_arg].value.type = message_token;
message->arg_array[nb_arg].value.string = NULL;
nb_arg++;
if (nb_arg >= message->argument_allocated) {
message->argument_allocated *=2;
message->arg_array = g_realloc(message->arg_array, (message->argument_allocated+1) * sizeof(message_arg_array_t));
}
expect_key = TRUE;
}
token = NULL;
break;
}
}
return message_array;
}