Commit 414ec9d0 authored by Marek Vavrusa's avatar Marek Vavrusa

Temporary PID/ZDB file location in $HOME, implemented default zonedb in server.

* Support for zonefile compilation in cutectl

refs #277,#284
parent afa4e6ac
......@@ -22,8 +22,8 @@ typedef unsigned int uint;
#define PROJECT_NAME "CuteDNS" // Project name
#define PROJECT_VER 0x000001 // 0xMMIIRR (MAJOR,MINOR,REVISION)
#define PROJECT_PIDF "/.cutedns.pid" // Default project PID file
#define PROJECT_EXEC "cutedns" // Project executable
#define ZONEPARSER_EXEC "zoneparser" // Zoneparser executable
/* Server. */
#define CPU_ESTIMATE_MAGIC 2 // Extra threads above the number of processors
......@@ -53,8 +53,7 @@ static inline int fread_safe(void *dst, size_t size, size_t n, FILE *fp)
{
int rc = fread(dst, size, n, fp);
if (rc != n) {
log_warning("fread: invalid read %d (expected %zu)\n",
rc, n);
log_warning("fread: invalid read %d (expected %zu)\n", rc, n);
}
return rc == n;
......@@ -65,7 +64,7 @@ static inline int fread_safe(void *dst, size_t size, size_t n, FILE *fp)
*/
#define ERR_ALLOC_FAILED log_error("Allocation failed at %s:%d (%s ver.%x)\n", \
__FILE__, __LINE__, PROJECT_NAME, PROJECT_VER)
__FILE__, __LINE__, PROJECT_NAME, PROJECT_VER)
#define CHECK_ALLOC_LOG(var, ret) \
do { \
......
......@@ -12,7 +12,7 @@ enum Constants {
void help(int argc, char **argv)
{
printf("Usage: %s [parameters] start|stop|restart|reload|running"
printf("Usage: %s [parameters] start|stop|restart|reload|running|compile"
"[zone file]\n",
argv[0]);
printf("Parameters:\n"
......@@ -21,42 +21,40 @@ void help(int argc, char **argv)
" -h\tPrint help and usage.\n",
PROJECT_NAME);
printf("Actions:\n"
" start [zone] Start %s server with given zone (no-op if running).\n"
" stop Stop %s server (no-on if not running).\n"
" restart [zone] Stops and then starts %s server.\n"
" reload [zone] Reload %s configuration and zone files.\n"
" running Check if server is running.\n",
" start [zone] Start %s server with given zone (no-op if running).\n"
" stop Stop %s server (no-on if not running).\n"
" restart [zone] Stops and then starts %s server.\n"
" reload [zone] Reload %s configuration and zone files.\n"
" running Check if server is running.\n"
"\n"
" compile <origin> <zone> Compile zone file.\n",
PROJECT_NAME, PROJECT_NAME, PROJECT_NAME, PROJECT_NAME);
}
int execute(const char *action, const char *zone, pid_t pid, int verbose)
int execute(const char *action, char **argv, int argc, pid_t pid, int verbose)
{
int valid_cmd = 0;
int rc = 0;
char* pidfile = pid_filename();
if (strcmp(action, "start") == 0) {
// Check zone
valid_cmd = 1;
if (!zone) {
log_error("Zone file not specified.\n");
return 1;
}
// Check PID
valid_cmd = 1;
if (pid > 0) {
log_info("Server PID found, already running.\n");
free(pidfile);
return 1;
}
// Prepare command
char* cmd = 0;
const char *cmd_str = "%s -d %s\"%s\"";
const char *cmd_str = "%s -d %s%s";
rc = asprintf(&cmd, cmd_str, PROJECT_EXEC,
verbose ? "-v " : "", zone);
verbose ? "-v " : "", argc > 0 ? argv[0] : "");
// Execute command
if ((rc = system(cmd)) < 0) {
pid_remove(PROJECT_PIDF);
pid_remove(pidfile);
rc = 1;
}
free(cmd);
......@@ -68,26 +66,26 @@ int execute(const char *action, const char *zone, pid_t pid, int verbose)
valid_cmd = 1;
if (pid <= 0) {
log_info("Server PID not found, "
"probably not running.\n");
"probably not running.\n");
rc = 1;
} else {
// Stop
if (kill(pid, SIGTERM) < 0) {
pid_remove(PROJECT_PIDF);
pid_remove(pidfile);
rc = 1;
}
}
}
if (strcmp(action, "restart") == 0) {
valid_cmd = 1;
execute("stop", zone, pid, verbose);
execute("stop", argv, argc, pid, verbose);
int i = 0;
while(pid_read(PROJECT_PIDF) > 0) {
while(pid_read(pidfile) > 0) {
if (i == WAITPID_TIMEOUT) {
log_warning("Timeout while waiting for server "
"to finish...\n");
pid_remove(PROJECT_PIDF);
"to finish...\n");
pid_remove(pidfile);
break;
} else {
sleep(1);
......@@ -95,7 +93,7 @@ int execute(const char *action, const char *zone, pid_t pid, int verbose)
}
}
rc = execute("start", zone, -1, verbose);
rc = execute("start", argv, argc, -1, verbose);
}
if (strcmp(action, "reload") == 0) {
......@@ -103,13 +101,14 @@ int execute(const char *action, const char *zone, pid_t pid, int verbose)
valid_cmd = 1;
if (pid <= 0) {
log_info("Server PID not found, "
"probably not running.\n");
"probably not running.\n");
free(pidfile);
return 1;
}
// Stop
if (kill(pid, SIGHUP) < 0) {
pid_remove(PROJECT_PIDF);
pid_remove(pidfile);
rc = 1;
}
}
......@@ -126,13 +125,37 @@ int execute(const char *action, const char *zone, pid_t pid, int verbose)
rc = 0;
}
}
if (strcmp(action, "compile") == 0) {
// Check zone
valid_cmd = 1;
if (argc < 2) {
log_error("Zone file or origin not specified.\n");
free(pidfile);
return 1;
}
// Prepare command
char* cmd = 0;
const char *cmd_str = "%s %s%s %s";
rc = asprintf(&cmd, cmd_str, ZONEPARSER_EXEC,
verbose ? "-v " : "", argv[0], argv[1]);
// Execute command
if ((rc = system(cmd)) < 0) {
rc = 1;
}
free(cmd);
}
if (!valid_cmd) {
log_error("invalid command: '%s'\n", action);
free(pidfile);
return 1;
}
// Log
log_info("server %s finished (return code %d)\n", action, rc);
free(pidfile);
return rc;
}
......@@ -179,19 +202,18 @@ int main(int argc, char **argv)
log_open(print_mask, log_mask);
// Fetch PID
pid_t pid = pid_read(PROJECT_PIDF);
char* pidfile = pid_filename();
pid_t pid = pid_read(pidfile);
// Actions
const char* action = argv[optind];
const char* zone = 0;
if (argc - optind > 1) {
zone = argv[optind + 1];
}
// Execute action
int rc = execute(action, zone, pid, verbose);
int rc = execute(action, argv + optind + 1, argc - optind - 1,
pid, verbose);
// Finish
free(pidfile);
log_close();
return rc;
}
......@@ -7,11 +7,10 @@
#include "process.h"
#include "log.h"
/*! \todo REMOVE this when configuration allows
* specification of an explicit PID file path.
*/
static char *get_temporary_fn(const char* fn)
char* pid_filename()
{
// Construct filename
const char* fn = "/cutedns.pid";
char* home = getenv("HOME");
int len = strlen(home) + strlen(fn) + 1;
char* ret = malloc(len);
......@@ -26,15 +25,11 @@ pid_t pid_read(const char* fn)
char buf[64];
if (fn) {
char* tmp = get_temporary_fn(fn);
FILE *fp = fopen(tmp, "r");
free(tmp);
FILE *fp = fopen(fn, "r");
if (!fp) {
return PID_NOFILE;
}
int readb = 0;
int rc = fread(buf, 1, 1, fp);
while (rc > 0) {
......@@ -79,9 +74,7 @@ int pid_write(const char* fn)
}
// Write
char* tmp = get_temporary_fn(fn);
FILE *fp = fopen(tmp, "w");
free(tmp);
FILE *fp = fopen(fn, "w");
if (fp) {
int rc = fwrite(buf, wbytes, 1, fp);
......@@ -98,9 +91,6 @@ int pid_write(const char* fn)
int pid_remove(const char* fn)
{
char* tmp = get_temporary_fn(fn);
int rc = unlink(tmp);
free(tmp);
return rc;
return unlink(fn);
}
......@@ -23,6 +23,16 @@ enum {
/* PID handling */
/*!
* \brief Return a filename of the default compiled database file.
*
* \retval Filename of the database file.
* \retval NULL if not exists.
*
* \todo Implement properly using configuration file.
*/
char* pid_filename();
/*!
* \brief Read PID from given file.
*
......
......@@ -40,7 +40,7 @@ void interrupt_handle(int s)
void help(int argc, char **argv)
{
printf("Usage: %s [parameters] <filename1> [<filename2> ...]\n",
printf("Usage: %s [parameters] [<filename1> <filename2> ...]\n",
argv[0]);
printf("Parameters:\n"
" -d\tRun server as a daemon.\n"
......@@ -78,12 +78,6 @@ int main(int argc, char **argv)
}
}
// Check if there's at least one remaining non-option
if (argc - optind < 1) {
help(argc, argv);
return 1;
}
// Now check if we want to daemonize
if (daemonize) {
if (daemon(1, 0) != 0) {
......@@ -106,14 +100,39 @@ int main(int argc, char **argv)
log_open(print_mask, log_mask);
// Save PID
char* pidfile = pid_filename();
if (daemonize) {
int rc = pid_write(PROJECT_PIDF);
int rc = pid_write(pidfile);
if (rc < 0) {
log_warning("Failed to create PID file '%s'.",
PROJECT_PIDF);
pidfile);
} else {
log_info("PID file '%s' created.",
PROJECT_PIDF);
pidfile);
}
}
// Check if there's at least one remaining non-option
int zfs_count = argc - optind;
char **zfs = argv + optind;
char *default_zf = 0;
if (argc - optind < 1) {
// Check file
default_zf = dnslib_zonedb_dbpath();
FILE* fp = fopen(default_zf, "r");
if (fp) {
log_info("Default zone database '%s'.\n",
default_zf);
zfs_count = 1;
zfs = &default_zf;
fclose(fp);
} else {
log_error("No zonefile specified and "
"the default database not exists.\n");
log_info("shutting down...\n");
pid_remove(pidfile);
log_close();
return 1;
}
}
......@@ -122,7 +141,7 @@ int main(int argc, char **argv)
// Run server
int res = 0;
if ((res = cute_start(s_server, argv + optind, argc - optind)) == 0) {
if ((res = cute_start(s_server, zfs, zfs_count)) == 0) {
// Register service and signal handler
struct sigaction sa;
......@@ -143,11 +162,16 @@ int main(int argc, char **argv)
if ((res = cute_wait(s_server)) != 0) {
log_error("There was an error while waiting for server"
" to finish.\n");
" to finish.\n");
}
} else {
log_error("There was an error while starting the server, "
"exiting...\n");
"exiting...\n");
}
// Free default zone database
if (default_zf) {
free(default_zf);
}
// Stop server and close log
......@@ -155,12 +179,13 @@ int main(int argc, char **argv)
// Remove PID file if daemonized
if (daemonize) {
if (pid_remove(PROJECT_PIDF) < 0) {
if (pid_remove(pidfile) < 0) {
log_warning("Failed to remove PID file.\n");
} else {
log_info("PID file safely removed.\n");
}
}
free(pidfile);
log_info("Shutting down...\n");
log_close();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment