[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r4745 - in GNUnet: contrib src/include src/server src/util/
From: |
gnunet |
Subject: |
[GNUnet-SVN] r4745 - in GNUnet: contrib src/include src/server src/util/os |
Date: |
Sun, 15 Apr 2007 15:35:13 -0600 (MDT) |
Author: grothoff
Date: 2007-04-15 15:35:13 -0600 (Sun, 15 Apr 2007)
New Revision: 4745
Modified:
GNUnet/contrib/config-daemon.scm
GNUnet/src/include/gnunet_util_os.h
GNUnet/src/server/gnunetd.c
GNUnet/src/server/startup.c
GNUnet/src/server/startup.h
GNUnet/src/util/os/console.c
GNUnet/src/util/os/user.c
Log:
fixing Mantis bug #1192
Modified: GNUnet/contrib/config-daemon.scm
===================================================================
--- GNUnet/contrib/config-daemon.scm 2007-04-14 22:41:44 UTC (rev 4744)
+++ GNUnet/contrib/config-daemon.scm 2007-04-15 21:35:13 UTC (rev 4745)
@@ -153,7 +153,7 @@
(nohelp)
'()
#t
- "$GNUNET_HOME/data/shared"
+ "$GNUNETD_HOME/data/shared"
'()
'always) )
@@ -291,11 +291,10 @@
"GNUNETD"
"PIDFILE"
(_ "Where should gnunetd write the PID?")
- (_
-"In which file should gnunetd write the process-id of the server? If you run
gnunetd as root, you may want to choose /var/run/gnunetd.pid. It's not the
default since gnunetd may not have write rights at that location." )
+ (_ "The default is no longer /var/run/gnunetd.pid since we could not delete
the file on shutdown at that location." )
'()
#f
- "/var/run/gnunetd.pid"
+ "/var/run/gnunetd/pid"
'()
'rare) )
Modified: GNUnet/src/include/gnunet_util_os.h
===================================================================
--- GNUnet/src/include/gnunet_util_os.h 2007-04-14 22:41:44 UTC (rev 4744)
+++ GNUnet/src/include/gnunet_util_os.h 2007-04-15 21:35:13 UTC (rev 4745)
@@ -244,6 +244,13 @@
const char * user);
/**
+ * @brief Change owner of a file
+ */
+int os_change_owner(struct GE_Context * ectx,
+ const char * filename,
+ const char * user);
+
+/**
* Get the current CPU load.
* @param ectx for error reporting
* @param cfg to determine acceptable load level (LOAD::MAXCPULOAD)
@@ -312,16 +319,35 @@
*/
char * os_get_installation_path(enum InstallPathKind dirkind);
+/**
+ * Write our process ID to the pid file. Use only
+ * if you are not calling os_terminal_detach, since
+ * os_terminal_detach will already write the pid file.
+ *
+ * @return OK on success, SYSERR on error
+ */
+int os_write_pid_file(struct GE_Context * ectx,
+ struct GC_Configuration * cfg,
+ unsigned int pid);
+/**
+ * Delete the PID file (to be called when the daemon
+ * shuts down)
+ */
+int os_delete_pid_file(struct GE_Context * ectx,
+ struct GC_Configuration * cfg);
+
/**
* Fork and start a new session to go into the background
- * in the way a good deamon should.
+ * in the way a good deamon should. Also writes the PID
+ * file.
*
* @param filedes pointer to an array of 2 file descriptors
* to complete the detachment protocol (handshake)
*/
int os_terminal_detach(struct GE_Context * ectx,
+ struct GC_Configuration * cfg,
int * filedes);
/**
Modified: GNUnet/src/server/gnunetd.c
===================================================================
--- GNUnet/src/server/gnunetd.c 2007-04-14 22:41:44 UTC (rev 4744)
+++ GNUnet/src/server/gnunetd.c 2007-04-15 21:35:13 UTC (rev 4745)
@@ -44,6 +44,7 @@
static struct GE_Context * ectx = NULL;
static struct CronManager * cron;
+static struct LoadMonitor * mon;
static char * cfgFilename = DEFAULT_DAEMON_CONFIG_FILE;
@@ -89,38 +90,57 @@
"gnunetd");
}
+
+static int post_detach() {
+ if (OK != changeUser(ectx, cfg))
+ return SYSERR;
+ if (OK != checkPermissions(ectx, cfg))
+ return SYSERR;
+ mon = os_network_monitor_create(ectx,
+ cfg);
+ if (mon == NULL)
+ return SYSERR;
+ return OK;
+}
+
/**
* The main method of gnunetd.
*/
int gnunet_main() {
- struct LoadMonitor * mon;
struct SignalHandlerContext * shc_hup;
int filedes[2]; /* pipe between client and parent */
if ( (NO == debug_flag) &&
(OK != os_terminal_detach(ectx,
+ cfg,
filedes)) )
return SYSERR;
- mon = os_network_monitor_create(ectx,
- cfg);
- if (mon == NULL) {
- if (NO == debug_flag)
- os_terminal_detach_complete(ectx,
- filedes,
- NO);
- return SYSERR;
+ if (NO != debug_flag)
+ os_write_pid_file(ectx,
+ cfg,
+ (unsigned int)getpid());
+ if (OK != post_detach()) {
+ if (NO == debug_flag)
+ os_terminal_detach_complete(ectx,
+ filedes,
+ NO);
+ else
+ os_delete_pid_file(ectx, cfg);
+ return SYSERR;
}
cron = cron_create(ectx);
GE_ASSERT(ectx,
cron != NULL);
#ifndef WINDOWS
- shc_hup = signal_handler_install(SIGHUP, &reread_config);
+ shc_hup = signal_handler_install(SIGHUP,
+ &reread_config);
#endif
if (OK != initCore(ectx,
cfg,
cron,
mon)) {
- GE_LOG(ectx, GE_FATAL | GE_USER | GE_IMMEDIATE,
+ GE_LOG(ectx,
+ GE_FATAL | GE_USER | GE_IMMEDIATE,
_("Core initialization failed.\n"));
cron_destroy(cron);
@@ -142,7 +162,6 @@
initConnection(ectx, cfg, mon, cron);
loadApplicationModules();
- writePIDFile(ectx, cfg);
if (NO == debug_flag)
os_terminal_detach_complete(ectx,
filedes,
@@ -152,7 +171,7 @@
waitForSignalHandler(ectx);
disableCoreProcessing();
cron_stop(cron);
- deletePIDFile(ectx, cfg);
+ os_delete_pid_file(ectx, cfg);
stopTCPServer();
unloadApplicationModules();
doneConnection();
@@ -240,10 +259,6 @@
GE_IMMEDIATE));
}
}
- if (OK != changeUser(ectx, cfg)) {
- GNUNET_fini(ectx, cfg);
- return 1;
- }
setFdLimit(ectx, cfg);
if (OK != checkUpToDate(ectx,
cfg)) {
@@ -256,13 +271,16 @@
}
#ifdef MINGW
- if (GC_get_configuration_value_yesno(cfg, "GNUNETD", "WINSERVICE", NO) ==
YES) {
+ if (GC_get_configuration_value_yesno(cfg,
+ "GNUNETD",
+ "WINSERVICE",
+ NO) == YES) {
SERVICE_TABLE_ENTRY DispatchTable[] =
{{"GNUnet", ServiceMain}, {NULL, NULL}};
ret = (GNStartServiceCtrlDispatcher(DispatchTable) != 0);
} else
#endif
- ret = gnunet_main();
+ ret = gnunet_main();
GNUNET_fini(ectx, cfg);
if (ret != OK)
return 1;
Modified: GNUnet/src/server/startup.c
===================================================================
--- GNUnet/src/server/startup.c 2007-04-14 22:41:44 UTC (rev 4744)
+++ GNUnet/src/server/startup.c 2007-04-15 21:35:13 UTC (rev 4745)
@@ -250,67 +250,80 @@
#endif
}
-static char * getPIDFile(struct GC_Configuration * cfg) {
- char * pif;
-
- if (0 != GC_get_configuration_value_filename(cfg,
- "GNUNETD",
- "PIDFILE",
- VAR_DAEMON_DIRECTORY
"/gnunetd.pid",
- &pif))
- return NULL;
- return pif;
+int checkPermission(struct GE_Context * ectx,
+ struct GC_Configuration * cfg,
+ const char * section,
+ const char * option,
+ const char * def,
+ int is_directory,
+ int mode) {
+ char * fn;
+ int i;
+
+ GC_get_configuration_value_filename(cfg,
+ section,
+ option,
+ def,
+ &fn);
+ if (is_directory)
+ disk_directory_create(ectx, fn);
+ else
+ disk_directory_create_for_file(ectx, fn);
+ if ( (0 != ACCESS(fn, F_OK)) &&
+ (mode == W_OK) ) {
+ /* adjust check to see if directory is writable */
+ i = strlen(fn);
+ while ( (i > 1) &&
+ (fn[i] != DIR_SEPARATOR) )
+ i--;
+ fn[i] = '\0';
+ mode = X_OK | W_OK;
+ }
+ if (0 != ACCESS(fn, mode)) {
+ GE_LOG(ectx,
+ GE_FATAL | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+ _("Insufficient access permissions for `%s': %s"),
+ fn,
+ STRERROR(errno));
+ FREE(fn);
+ return SYSERR;
+ }
+ FREE(fn);
+ return OK;
}
-/**
- * Write our process ID to the pid file.
- */
-void writePIDFile(struct GE_Context * ectx,
- struct GC_Configuration * cfg) {
- FILE * pidfd;
- char * pif;
+#define CHECK(a,b,c,d,e) if (OK != checkPermission(ectx, cfg, a, b, c, d, e))
return SYSERR;
- pif = getPIDFile(cfg);
- if (pif == NULL)
- return; /* no PID file */
- pidfd = FOPEN(pif, "w");
- if (pidfd == NULL) {
- GE_LOG_STRERROR_FILE(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "fopen",
- pif);
- FREE(pif);
- return;
- }
- if (0 > FPRINTF(pidfd,
- "%u",
- (unsigned int) getpid()))
- GE_LOG_STRERROR_FILE(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "fprintf",
- pif);
- if (0 != fclose(pidfd))
- GE_LOG_STRERROR_FILE(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "fclose",
- pif);
- FREE(pif);
+int checkPermissions(struct GE_Context * ectx,
+ struct GC_Configuration * cfg) {
+ CHECK("PATHS",
+ "GNUNETD_HOME",
+ "/var/lib/gnunet",
+ YES,
+ W_OK | X_OK);
+ CHECK("GNUNETD",
+ "LOGFILE",
+ "$GNUNETD_HOME/daemon-logs",
+ NO,
+ W_OK);
+ /* these should only be checked if "fs" is actually
+ loaded; we clearly should not check everything here
+ that just might be used (MYSQL-CONFIG, F2F-FRIENDS),
+ OTOH, late messages in the startup sequence are also
+ not great. Would be nice if we could find a way to
+ keep things decentralized and still do a nice job
+ with reporting errors... */
+ CHECK("FS",
+ "DIR",
+ "$GNUNETD_HOME/data/fs",
+ YES,
+ W_OK | X_OK);
+ CHECK("FS",
+ "INDEX-DIRECTORY",
+ "$GNUNETD_HOME/data/shared",
+ YES,
+ W_OK | X_OK);
+ return OK;
}
-void deletePIDFile(struct GE_Context * ectx,
- struct GC_Configuration * cfg) {
- char * pif = getPIDFile(cfg);
- if (pif == NULL)
- return; /* no PID file */
- if (YES == disk_file_test(ectx,
- pif)) {
- if (0 != UNLINK(pif))
- GE_LOG_STRERROR_FILE(ectx,
- GE_WARNING | GE_ADMIN | GE_BULK,
- "unlink",
- pif);
- }
- FREE(pif);
-}
-
/* end of startup.c */
Modified: GNUnet/src/server/startup.h
===================================================================
--- GNUnet/src/server/startup.h 2007-04-14 22:41:44 UTC (rev 4744)
+++ GNUnet/src/server/startup.h 2007-04-15 21:35:13 UTC (rev 4745)
@@ -37,19 +37,10 @@
int setFdLimit(struct GE_Context * ectx,
struct GC_Configuration * cfg);
-/**
- * Write our process ID to the pid file.
- */
-void writePIDFile(struct GE_Context * ectx,
- struct GC_Configuration * cfg);
+int checkPermissions(struct GE_Context * ectx,
+ struct GC_Configuration * cfg);
/**
- * Delete the pid file.
- */
-void deletePIDFile(struct GE_Context * ectx,
- struct GC_Configuration * cfg);
-
-/**
* @brief Cap datastore limit to the filesystem's capabilities
* @notice FAT does not support files larger than 2/4 GB
* @param ectx error handler
Modified: GNUnet/src/util/os/console.c
===================================================================
--- GNUnet/src/util/os/console.c 2007-04-14 22:41:44 UTC (rev 4744)
+++ GNUnet/src/util/os/console.c 2007-04-15 21:35:13 UTC (rev 4745)
@@ -27,13 +27,128 @@
* receives a SIGTERM/SIGHUP etc.
*/
+#include "gnunet_directories.h"
#include "gnunet_util_os.h"
#include "gnunet_util_error.h"
#include "gnunet_util_string.h"
#include "gnunet_util_disk.h"
#include "platform.h"
+
+static char *
+getPIDFile(struct GC_Configuration * cfg) {
+ char * pif;
+
+ if (0 != GC_get_configuration_value_filename(cfg,
+ "GNUNETD",
+ "PIDFILE",
+ VAR_DAEMON_DIRECTORY
"/gnunetd/pid",
+ &pif))
+ return NULL;
+ return pif;
+}
+
+
/**
+ * Write our process ID to the pid file.
+ *
+ * @return OK on success, SYSERR on error
+ */
+int os_write_pid_file(struct GE_Context * ectx,
+ struct GC_Configuration * cfg,
+ unsigned int pid) {
+ FILE * pidfd;
+ char * pif;
+ char * user;
+ char * rdir;
+ int len;
+
+ pif = getPIDFile(cfg);
+ if (pif == NULL)
+ return OK; /* no PID file */
+ GC_get_configuration_value_string(cfg,
+ "GNUNETD",
+ "USER",
+ "",
+ &user);
+ rdir = STRDUP(pif);
+ len = strlen(rdir);
+ while ( (len > 0) &&
+ (rdir[len] != DIR_SEPARATOR) )
+ len--;
+ rdir[len] = '\0';
+ if (0 != ACCESS(rdir, F_OK)) {
+ /* we get to create a directory -- and claim it
+ as ours! */
+ disk_directory_create(ectx, rdir);
+ if (strlen(user))
+ os_change_owner(ectx,
+ rdir,
+ user);
+ }
+ if (0 != ACCESS(rdir, W_OK | X_OK)) {
+ GE_LOG_STRERROR_FILE(ectx,
+ GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
+ "access",
+ rdir);
+ FREE(rdir);
+ FREE(user);
+ return SYSERR;
+ }
+ FREE(rdir);
+ pidfd = FOPEN(pif, "w");
+ if (pidfd == NULL) {
+ GE_LOG_STRERROR_FILE(ectx,
+ GE_WARNING | GE_ADMIN | GE_BULK,
+ "fopen",
+ pif);
+ FREE(pif);
+ FREE(user);
+ return SYSERR;
+ }
+ if (0 > FPRINTF(pidfd,
+ "%u",
+ pid))
+ GE_LOG_STRERROR_FILE(ectx,
+ GE_WARNING | GE_ADMIN | GE_BULK,
+ "fprintf",
+ pif);
+ if (0 != fclose(pidfd))
+ GE_LOG_STRERROR_FILE(ectx,
+ GE_WARNING | GE_ADMIN | GE_BULK,
+ "fclose",
+ pif);
+ if (strlen(user))
+ os_change_owner(ectx,
+ pif,
+ user);
+ FREE(user);
+ FREE(pif);
+ return OK;
+}
+
+int os_delete_pid_file(struct GE_Context * ectx,
+ struct GC_Configuration * cfg) {
+ char * pif = getPIDFile(cfg);
+ if (pif == NULL)
+ return OK; /* no PID file */
+ if (YES == disk_file_test(ectx,
+ pif)) {
+ if (0 != UNLINK(pif)) {
+ GE_LOG_STRERROR_FILE(ectx,
+ GE_WARNING | GE_ADMIN | GE_BULK,
+ "unlink",
+ pif);
+ FREE(pif);
+ return SYSERR;
+ }
+ }
+ FREE(pif);
+ return OK;
+}
+
+
+/**
* Fork and start a new session to go into the background
* in the way a good deamon should.
*
@@ -41,6 +156,7 @@
* to complete the detachment protocol (handshake)
*/
int os_terminal_detach(struct GE_Context * ectx,
+ struct GC_Configuration * cfg,
int * filedes) {
pid_t pid;
int nullfd;
@@ -78,10 +194,14 @@
ok = OK;
}
fflush(stdout);
- if (ok == OK)
+ if (ok == OK) {
+ os_write_pid_file(ectx,
+ cfg,
+ pid);
exit(0);
- else
+ } else {
exit(1); /* child reported error */
+ }
}
if (0 != CLOSE(filedes[0]))
GE_LOG_STRERROR(ectx,
Modified: GNUnet/src/util/os/user.c
===================================================================
--- GNUnet/src/util/os/user.c 2007-04-14 22:41:44 UTC (rev 4744)
+++ GNUnet/src/util/os/user.c 2007-04-15 21:35:13 UTC (rev 4745)
@@ -109,6 +109,7 @@
}
+
/**
* @brief Change user ID
*/
@@ -120,9 +121,10 @@
pws = getpwnam(user);
if (pws == NULL) {
GE_LOG(ectx,
- GE_FATAL | GE_USER | GE_ADMIN | GE_IMMEDIATE,
- _("User `%s' not known, cannot change UID to it.\n"),
- user);
+ GE_ERROR | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+ _("Cannot obtain information about user `%s': %s\n"),
+ user,
+ STRERROR(errno));
return SYSERR;
}
if((0 != setgid(pws->pw_gid)) ||
@@ -147,3 +149,34 @@
}
+
+/**
+ * @brief Change owner of a file
+ */
+int os_change_owner(struct GE_Context * ectx,
+ const char * filename,
+ const char * user) {
+#ifndef MINGW
+ struct passwd * pws;
+
+ pws = getpwnam(user);
+ if (pws == NULL) {
+ GE_LOG(ectx,
+ GE_ERROR | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+ _("Cannot obtain information about user `%s': %s\n"),
+ user,
+ STRERROR(errno));
+ return SYSERR;
+ }
+ if (0 != chown(filename,
+ pws->pw_uid,
+ pws->pw_gid))
+ GE_LOG_STRERROR_FILE(ectx,
+ GE_ERROR | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+ "chown",
+ filename);
+#endif
+ return OK;
+}
+
+
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r4745 - in GNUnet: contrib src/include src/server src/util/os,
gnunet <=