/*
- * $Id: afp_options.c,v 1.40 2009-03-26 18:21:40 franklahm Exp $
+ * $Id: afp_options.c,v 1.41 2009-03-31 11:40:26 franklahm Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* Copyright (c) 1990,1993 Regents of The University of Michigan.
}
/* -[no]setuplog <logtype> <loglevel> [<filename>]*/
- if ((c = getoption(buf, "-setuplog"))) {
- char *ptr, *logtype, *loglevel, *filename;
- ptr = c;
-
- /* logtype */
- logtype = ptr;
-
- /* get loglevel */
- ptr = strpbrk(ptr, " \t");
- if (ptr) {
- *ptr++ = 0;
- while (*ptr && isspace(*ptr))
- ptr++;
- loglevel = ptr;
-
- /* get filename */
- ptr = strpbrk(ptr, " \t");
- if (ptr) {
- *ptr++ = 0;
- while (*ptr && isspace(*ptr))
- ptr++;
- }
- filename = ptr;
- }
-
- /* finally call setuplog, filename can be NULL */
- setuplog(logtype, loglevel, filename);
- }
-
- if ((c = getoption(buf, "-unsetuplog"))) {
- char *ptr, *logtype, *loglevel, *filename;
-
- /* logtype */
- logtype = c;
+ if ((c = getoption(buf, "-setuplog")))
+ setuplog(c);
- /* get filename, can be NULL */
- strtok(c, " \t");
- filename = strtok(NULL, " \t");
-
- /* finally call setuplog, filename can be NULL */
- setuplog(logtype, NULL, filename);
- }
+ if ((c = getoption(buf, "-unsetuplog")))
+ unsetuplog(c);
#ifdef ADMIN_GRP
if ((c = getoption(buf, "-admingroup"))) {
/*
- * $Id: cnid_metad.c,v 1.5 2009-03-06 13:05:52 didg Exp $
+ * $Id: cnid_metad.c,v 1.6 2009-03-31 11:40:26 franklahm Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYING.
static struct server srv[MAXSRV +1];
+/* Default logging config: log to syslog with level log_debug */
+static char *logconfig = "default log_debug";
+
static struct server *test_usockfn(char *dir, char *fn _U_)
{
int i;
* it will run recover, delete the db whatever
*/
LOG(log_error, logtype_cnid, "try with -d %s", up->name);
- ret = execlp(dbdpn, dbdpn, "-d", dbdir, buf1, buf2, NULL);
+ ret = execlp(dbdpn, dbdpn, "-d", dbdir, buf1, buf2, logconfig, NULL);
}
else {
- ret = execlp(dbdpn, dbdpn, dbdir, buf1, buf2, NULL);
+ ret = execlp(dbdpn, dbdpn, dbdir, buf1, buf2, logconfig, NULL);
}
if (ret < 0) {
LOG(log_error, logtype_cnid, "Fatal error in exec: %s", strerror(errno));
set_processname("cnid_metad");
- while (( cc = getopt( argc, argv, "ds:p:h:u:g:")) != -1 ) {
+ while (( cc = getopt( argc, argv, "ds:p:h:u:g:l:")) != -1 ) {
switch (cc) {
case 'd':
debug = 1;
case 's':
dbdpn = strdup(optarg);
break;
+ case 'l':
+ logconfig = strdup(optarg);
+ break;
default:
err++;
break;
}
}
-
+
+ setuplog(logconfig);
+
if (err) {
LOG(log_error, logtype_cnid, "main: bad arguments");
exit(1);
/*
- * $Id: main.c,v 1.2 2005-04-28 20:49:48 bfernhomberg Exp $
+ * $Id: main.c,v 1.3 2009-03-31 11:40:26 franklahm Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYING.
static void block_sigs_onoff(int block)
{
sigset_t set;
-
+
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGTERM);
return;
}
-/*
- The dbd_XXX and comm_XXX functions all obey the same protocol for return values:
-
- 1: Success, if transactions are used commit.
- 0: Failure, but we continue to serve requests. If transactions are used abort/rollback.
- -1: Fatal error, either from the database or from the socket. Abort the transaction if applicable
- (which might fail as well) and then exit.
+/*
+ The dbd_XXX and comm_XXX functions all obey the same protocol for return values:
+
+ 1: Success, if transactions are used commit.
+ 0: Failure, but we continue to serve requests. If transactions are used abort/rollback.
+ -1: Fatal error, either from the database or from the socket. Abort the transaction if applicable
+ (which might fail as well) and then exit.
We always try to notify the client process about the outcome, the result field
of the cnid_dbd_rply structure contains further details.
- */
+*/
static int loop(struct db_param *dbp)
{
time_last_rqst = now;
if (dbp->nosync)
checkp_flags = DB_FORCE;
- else
+ else
checkp_flags = 0;
-
+
rqst.name = namebuf;
while (1) {
return -1;
now = time(NULL);
-
+
if (count > dbp->flush_frequency || now > time_next_flush) {
#ifdef CNID_BACKEND_DBD_TXN
if (dbif_txn_checkpoint(0, 0, checkp_flags) < 0)
block_sigs_onoff(1);
if (exit_sig)
return 0;
- if (dbp->idle_timeout && comm_nbe() <= 0 && (now - time_last_rqst) > dbp->idle_timeout)
- return 0;
- continue;
+ if (dbp->idle_timeout && comm_nbe() <= 0 && (now - time_last_rqst) > dbp->idle_timeout)
+ return 0;
+ continue;
}
/* We got a request */
- time_last_rqst = now;
+ time_last_rqst = now;
count++;
-
+
#ifdef CNID_BACKEND_DBD_TXN
- if (dbif_txn_begin() < 0)
+ if (dbif_txn_begin() < 0)
return -1;
#endif /* CNID_BACKEND_DBD_TXN */
- memset(&rply, 0, sizeof(rply));
+ memset(&rply, 0, sizeof(rply));
switch(rqst.op) {
/* ret gets set here */
case CNID_DBD_OP_OPEN:
case CNID_DBD_OP_CLOSE:
/* open/close are noops for now. */
- rply.namelen = 0;
+ rply.namelen = 0;
ret = 1;
break;
case CNID_DBD_OP_ADD:
LOG(log_error, logtype_cnid, "loop: unknown op %d", rqst.op);
ret = -1;
break;
- }
+ }
if ((cret = comm_snd(&rply)) < 0 || ret < 0) {
#ifdef CNID_BACKEND_DBD_TXN
}
#ifdef CNID_BACKEND_DBD_TXN
if (ret == 0 || cret == 0) {
- if (dbif_txn_abort() < 0)
+ if (dbif_txn_abort() < 0)
return -1;
} else {
- if (dbif_txn_commit() < 0)
+ if (dbif_txn_commit() < 0)
return -1;
}
#endif /* CNID_BACKEND_DBD_TXN */
LOG(log_error, logtype_cnid, "chdir to %s failed: %s", dir, strerror(errno));
exit(1);
}
-
+
if (stat(".", &st) < 0) {
LOG(log_error, logtype_cnid, "error in stat for %s: %s", dir, strerror(errno));
exit(1);
struct flock lock;
if ((lockfd = open(LOCKFILENAME, O_RDWR | O_CREAT, 0644)) < 0) {
- LOG(log_error, logtype_cnid, "main: error opening lockfile: %s", strerror(errno));
- exit(1);
+ LOG(log_error, logtype_cnid, "main: error opening lockfile: %s", strerror(errno));
+ exit(1);
}
-
+
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;
lock.l_type = F_WRLCK;
if (fcntl(lockfd, F_SETLK, &lock) < 0) {
- if (errno == EACCES || errno == EAGAIN) {
- exit(0);
- } else {
- LOG(log_error, logtype_cnid, "main: fcntl F_WRLCK lockfile: %s", strerror(errno));
- exit(1);
- }
+ if (errno == EACCES || errno == EAGAIN) {
+ exit(0);
+ } else {
+ LOG(log_error, logtype_cnid, "main: fcntl F_WRLCK lockfile: %s", strerror(errno));
+ exit(1);
+ }
}
-
+
return lockfd;
}
int err = 0;
int ret;
int lockfd, ctrlfd, clntfd;
- char *dir;
-
+ char *dir, *logconfig;
+
set_processname("cnid_dbd");
- syslog_setup(log_debug, logtype_default, logoption_ndelay | logoption_pid, logfacility_daemon);
-
- if (argc != 4) {
+
+ if (argc != 5) {
LOG(log_error, logtype_cnid, "main: not enough arguments");
exit(1);
}
dir = argv[1];
ctrlfd = atoi(argv[2]);
clntfd = atoi(argv[3]);
+ logconfig = strdup(argv[4]);
+ setuplog(logconfig);
switch_to_user(dir);
-
+
/* Before we do anything else, check if there is an instance of cnid_dbd
running already and silently exit if yes. */
lockfd = get_lock();
-
+
LOG(log_info, logtype_cnid, "Startup, DB dir %s", dir);
-
+
set_signal();
-
+
/* SIGINT and SIGTERM are always off, unless we get a return code of 0 from
comm_rcv (no requests for one second, see above in loop()). That means we
only shut down after one second of inactivity. */
exit(1);
if (dbif_env_init(dbp) < 0)
- exit(2); /* FIXME: same exit code as failure for dbif_open() */
-
+ exit(2); /* FIXME: same exit code as failure for dbif_open() */
+
#ifdef CNID_BACKEND_DBD_TXN
if (dbif_txn_begin() < 0)
- exit(6);
+ exit(6);
#endif
-
+
if (dbif_open(dbp, 0) < 0) {
#ifdef CNID_BACKEND_DBD_TXN
- dbif_txn_abort();
+ dbif_txn_abort();
#endif
dbif_close();
exit(2);
exit(2);
}
dbif_closedb();
- LOG(log_info, logtype_cnid, "main: re-opening, secondaries will be rebuilt. This may take some time");
+ LOG(log_info, logtype_cnid, "main: re-opening, secondaries will be rebuilt. This may take some time");
if (dbif_open(dbp, 1) < 0) {
- LOG(log_info, logtype_cnid, "main: re-opening databases failed");
+ LOG(log_info, logtype_cnid, "main: re-opening databases failed");
dbif_close();
exit(2);
}
- LOG(log_info, logtype_cnid, "main: rebuilt done");
+ LOG(log_info, logtype_cnid, "main: rebuilt done");
}
#endif
if (dbd_stamp() < 0) {
#ifdef CNID_BACKEND_DBD_TXN
- dbif_txn_abort();
+ dbif_txn_abort();
#endif
dbif_close();
exit(5);
}
#ifdef CNID_BACKEND_DBD_TXN
if (dbif_txn_commit() < 0)
- exit(6);
+ exit(6);
#endif
if (comm_init(dbp, ctrlfd, clntfd) < 0) {
if (dbif_close() < 0)
err++;
-
+
free_lock(lockfd);
-
+
if (err)
exit(4);
else if (exit_sig)
- LOG(log_info, logtype_cnid, "main: Exiting on signal %i", exit_sig);
+ LOG(log_info, logtype_cnid, "main: Exiting on signal %i", exit_sig);
else
- LOG(log_info, logtype_cnid, "main: Idle timeout, exiting");
-
+ LOG(log_info, logtype_cnid, "main: Idle timeout, exiting");
+
return 0;
}
#ifndef _ATALK_LOGGER_H
#define _ATALK_LOGGER_H 1
+/*
+ * logger LOG Macro Usage
+ * ======================
+ *
+ * LOG(<logtype>, <loglevel>, "<string>"[, args]);
+ *
+ *
+ * logger API Setup
+ * ================
+ *
+ * Standard interface:
+ * -------------------
+ *
+ * setuplog(char *confstring)
+ * confstring = "<logtype> <loglevel> [<filename>]"
+ *
+ * Calling without <filename> configures basic logging to syslog. Specifying <filename>
+ * configures extended logging to <filename>.
+ *
+ * You can later disable logging by calling
+ *
+ * unsetuplog(char *confstring)
+ * confstring = "<logtype> [<any_string>]"
+ *
+ * Calling without <any_string> disables syslog logging, calling with <any_string>
+ * disables file logging.
+ *
+ * <logtype>:
+ * you can setup a default with "Default". Any other logtype used in LOG will then
+ * use the default if not setup itself. This is probabyl the only thing you may
+ * want to use.
+ *
+ * Example:
+ * setuplog("default log_debug /var/log/debug.log");
+ * See also libatalk/util/test/logger_test.c
+ *
+ * "Legacy" interface:
+ * -------------------
+ *
+ * Some netatalk daemons (31.3.2009.: e.g. atalkd, papd) may not be converted to
+ * use the new API and might still call
+ *
+ * syslog_setup(int loglevel, enum logtypes logtype, int display_options, int facility);
+ *
+ * directly. These daemons are therefore limited to syslog logging. Also their
+ * loglevel can't be changed at runtime.
+ *
+ *
+ * Note:
+ * dont get confused by log_init(). It only gets called if your app
+ * forgets to setup logging before calling LOG.
+ */
+
+
#include <limits.h>
#include <stdio.h>
void syslog_setup(int loglevel, enum logtypes logtype,
int display_options, int facility);
-/* void setuplog(char *logsource, char *logtype, char *loglevel, char *filename); */
-void setuplog(char *logtype, char *loglevel, char *filename);
+/* This gets called e.g. from afpd.conf parsing code with a string like: */
+/* "default log_maxdebug /var/log/afpd.log" */
+void setuplog(const char *logstr);
+
+/* This gets called e.g. from afpd.conf parsing code with a string like: */
+/* "default dummyname" */
+void unsetuplog(const char *logstr);
/* finish up and close the logs */
void log_close();
/* This function sets up the ProcessName */
-void set_processname(char *processname);
+void set_processname(const char *processname);
/*
* How to write a LOG macro:
#include <sys/uio.h>
#include <unistd.h>
#include <time.h>
+#include <ctype.h>
#include <atalk/boolean.h>
Internal function definitions
========================================================================= */
+/*
+ * If filename == NULL its for syslog logging, otherwise its for file-logging.
+ * "unsetuplog" calls with loglevel == NULL.
+ * loglevel == NULL means:
+ * if logtype == default
+ * disable logging
+ * else
+ * set to default logging
+ */
+
+ /* -[un]setuplog <logtype> <loglevel> [<filename>]*/
+static void setuplog_internal(char *logtype, char *loglevel, char *filename)
+{
+ int typenum, levelnum;
+
+ /* Parse logtype */
+ for( typenum=0; typenum < num_logtype_strings; typenum++) {
+ if (strcasecmp(logtype, arr_logtype_strings[typenum]) == 0)
+ break;
+ }
+ if (typenum >= num_logtype_strings) {
+ return;
+ }
+
+ /* Parse loglevel */
+ if (loglevel == NULL) {
+ levelnum = 0;
+ } else {
+ for(levelnum=1; levelnum < num_loglevel_strings; levelnum++) {
+ if (strcasecmp(loglevel, arr_loglevel_strings[levelnum]) == 0)
+ break;
+ }
+ if (levelnum >= num_loglevel_strings) {
+ return;
+ }
+ }
+
+ /* is this a syslog setup or a filelog setup ? */
+ if (filename == NULL) {
+ /* must be syslog */
+ syslog_setup(levelnum, 0,
+ log_config.syslog_display_options,
+ log_config.facility);
+ } else {
+ /* this must be a filelog */
+ log_setup(filename, levelnum, typenum);
+ }
+
+ return;
+}
+
static void generate_message_details(char *message_details_buffer,
int message_details_buffer_length,
int display_options,
file_configs[logtype].set = 0;
return;
}
-
+
+ fcntl(file_configs[logtype].fd, F_SETFD, FD_CLOEXEC);
file_configs[logtype].set = 1;
log_config.filelogging = 1;
log_config.inited = 1;
}
/* This function sets up the processname */
-void set_processname(char *processname)
+void set_processname(const char *processname)
{
strncpy(log_config.processname, processname, 15);
log_config.processname[15] = 0;
fd = file_configs[logtype_default].fd;
/* If default wasnt setup its fd is -1 */
- if (fd > 0) {
+ if (fd >= 0) {
iov[0].iov_base = log_details_buffer;
iov[0].iov_len = strlen(log_details_buffer);
iov[1].iov_base = temp_buffer;
inlog = 0;
}
-/*
- * This is called from the afpd.conf parsing code.
- * If filename == NULL its for syslog logging, otherwise its for file-logging.
- * "unsetuplog" calls with loglevel == NULL.
- * loglevel == NULL means:
- * if logtype == default
- * disable logging
- * else
- * set to default logging
- */
+void setuplog(const char *logstr)
+{
+ char *ptr, *logtype, *loglevel, *filename;
+ ptr = strdup(logstr);
+
+ /* logtype */
+ logtype = ptr;
+
+ /* get loglevel */
+ ptr = strpbrk(ptr, " \t");
+ if (ptr) {
+ *ptr++ = 0;
+ while (*ptr && isspace(*ptr))
+ ptr++;
+ loglevel = ptr;
+
+ /* get filename */
+ ptr = strpbrk(ptr, " \t");
+ if (ptr) {
+ *ptr++ = 0;
+ while (*ptr && isspace(*ptr))
+ ptr++;
+ }
+ filename = ptr;
+ }
- /* -[un]setuplog <logtype> <loglevel> [<filename>]*/
-void setuplog(char *logtype, char *loglevel, char *filename)
+ /* finally call setuplog, filename can be NULL */
+ setuplog_internal(logtype, loglevel, filename);
+
+ free(ptr);
+}
+
+void unsetuplog(const char *logstr)
{
- int typenum, levelnum;
+ char *str, *logtype, *filename;
- /* Parse logtype */
- for( typenum=0; typenum < num_logtype_strings; typenum++) {
- if (strcasecmp(logtype, arr_logtype_strings[typenum]) == 0)
- break;
- }
- if (typenum >= num_logtype_strings) {
- return;
- }
+ str = strdup(logstr);
- /* Parse loglevel */
- if (loglevel == NULL) {
- levelnum = 0;
- } else {
- for(levelnum=1; levelnum < num_loglevel_strings; levelnum++) {
- if (strcasecmp(loglevel, arr_loglevel_strings[levelnum]) == 0)
- break;
- }
- if (levelnum >= num_loglevel_strings) {
- return;
- }
- }
+ /* logtype */
+ logtype = str;
- /* is this a syslog setup or a filelog setup ? */
- if (filename == NULL) {
- /* must be syslog */
- syslog_setup(levelnum, 0,
- log_config.syslog_display_options,
- log_config.facility);
- } else {
- /* this must be a filelog */
- log_setup(filename, levelnum, typenum);
- }
+ /* get filename, can be NULL */
+ strtok(str, " \t");
+ filename = strtok(NULL, " \t");
- return;
+ /* finally call setuplog, filename can be NULL */
+ setuplog_internal(str, NULL, filename);
+
+ free(str);
}
/* syslog testing */
LOG(log_severe, logtype_logger, "Disabling syslog logging.");
- setuplog("Default", NULL, NULL);
+ unsetuplog("Default");
LOG(log_error, logtype_default, "This shouldn't log to syslog: LOG(log_error, logtype_default).");
LOG(log_error, logtype_logger, "This shouldn't log to syslog: LOG(log_error, logtype_logger).");
- setuplog("Default", "LOG_INFO", NULL);
+ setuplog("Default LOG_INFO");
LOG(log_info, logtype_logger, "Set syslog logging to 'log_info', so this should log again. LOG(log_info, logtype_logger).");
LOG(log_error, logtype_logger, "This should log to syslog: LOG(log_error, logtype_logger).");
LOG(log_error, logtype_default, "This should log to syslog. LOG(log_error, logtype_default).");
LOG(log_debug, logtype_logger, "This shouldn't log to syslog. LOG(log_debug, logtype_logger).");
LOG(log_debug, logtype_default, "This shouldn't log to syslog. LOG(log_debug, logtype_default).");
LOG(log_severe, logtype_logger, "Disabling syslog logging.");
- setuplog("Default", NULL, NULL);
+ unsetuplog("Default");
/* filelog testing */
- setuplog("Default", "LOG_INFO", "test.log");
+ setuplog("Default LOG_INFO test.log");
LOG(log_info, logtype_logger, "This should log.");
LOG(log_info, logtype_default, "This should log.");
LOG(log_error, logtype_logger, "This should log.");