00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <glib.h>
00023 #include <glib-object.h>
00024 #include <errno.h>
00025 #include <fcntl.h>
00026 #include <stdio.h>
00027 #include <getopt.h>
00028 #include <signal.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <unistd.h>
00032 #include <sys/stat.h>
00033 #include <sys/types.h>
00034 #include <osso-log.h>
00035
00036 #include "alarmd.h"
00037 #include "initialize.h"
00038 #include "queue.h"
00039 #include "rpc-osso.h"
00040 #include "rpc-dbus.h"
00041 #include "osso-log.h"
00042
00043 #define ALARMD_LOCKFILE "/var/run/alarmd.pid"
00044 #define PRG_NAME "alarmd"
00045
00046 extern int optind;
00047 extern char *optarg;
00048
00049 static const gchar *progname;
00050
00051
00052
00053
00054 static void usage(void)
00055 {
00056 fprintf(stdout,
00057 _("Usage: %s [OPTION]...\n"
00058 "Alarm daemon\n"
00059 "\n"
00060 " -d, --daemonflag run alarmd as a daemon\n"
00061 " --help display this help and exit\n"
00062 " --version output version information and exit\n"
00063 "\n"
00064 "Report bugs to <david.weinehall@nokia.com>\n"),
00065 progname);
00066 }
00067
00068
00069
00070
00071 static void version(void)
00072 {
00073 fprintf(stdout, _("%s v%s\n%s"),
00074 progname,
00075 VERSION,
00076 _("Written by Santtu Lakkala.\n"
00077 "Contact person: David Weinehall "
00078 "<david.weinehall@nokia.com>\n"
00079 "\n"
00080 "Copyright (C) 2006 Nokia Corporation.\n"
00081 "This is free software; see the source for copying "
00082 "conditions. There is NO\n"
00083 "warranty; not even for MERCHANTABILITY or FITNESS FOR A "
00084 "PARTICULAR PURPOSE.\n"));
00085 }
00086
00087
00088
00089
00090
00091
00092
00093 static gint init_locales(const gchar *const name)
00094 {
00095 gint status = 0;
00096
00097 #ifdef ENABLE_NLS
00098 setlocale(LC_ALL, "");
00099
00100 if ((bindtextdomain(name, LOCALEDIR) == 0) && (errno == ENOMEM)) {
00101 status = errno;
00102 goto EXIT;
00103 }
00104
00105 if ((textdomain(name) == 0) && (errno == ENOMEM)) {
00106 status = errno;
00107 return 0;
00108 }
00109
00110 EXIT:
00111
00112
00113
00114
00115 if (status != 0) {
00116 fprintf(stderr,
00117 "%s: `%s' failed; %s. Aborting.\n",
00118 name, "init_locales", strerror(errno));
00119 } else {
00120 progname = _(name);
00121 errno = 0;
00122 }
00123 #else
00124 progname = name;
00125 #endif
00126
00127 return status;
00128 }
00129
00130
00131
00132
00133
00134
00135 static void signal_handler(const gint signr)
00136 {
00137 switch (signr) {
00138 case SIGUSR1:
00139
00140 break;
00141
00142 case SIGHUP:
00143
00144 break;
00145
00146 case SIGTERM:
00147 DLOG_DEBUG("Stopping alarmd...");
00148 g_main_loop_quit(mainloop);
00149 break;
00150
00151 default:
00152
00153 break;
00154 }
00155 }
00156
00157
00158
00159
00160 static void daemonize(void)
00161 {
00162 gint i = 0;
00163 gchar str[10];
00164
00165 if (getppid() == 1)
00166 return;
00167
00168
00169 switch (fork()) {
00170 case -1:
00171
00172 DLOG_CRIT("daemonize: fork failed: %s", strerror(errno));
00173 LOG_CLOSE();
00174 exit(EXIT_FAILURE);
00175
00176 case 0:
00177
00178 break;
00179
00180 default:
00181
00182 exit(EXIT_SUCCESS);
00183 }
00184
00185
00186 setsid();
00187
00188
00189 if ((i = getdtablesize()) == -1)
00190 i = 256;
00191
00192 while (--i >= 0)
00193 close(i);
00194
00195 i = open("/dev/null", O_RDWR);
00196 dup(i);
00197 dup(i);
00198
00199
00200 umask(022);
00201
00202
00203 chdir("/tmp");
00204
00205
00206 if (access(ALARMD_LOCKFILE, F_OK) == 0) {
00207
00208 } else if (errno != ENOENT) {
00209 DLOG_CRIT("access() failed: %s. Exiting.", g_strerror(errno));
00210 LOG_CLOSE();
00211 exit(EXIT_FAILURE);
00212 }
00213
00214
00215 if ((i = open(ALARMD_LOCKFILE, O_RDWR | O_CREAT, 0640)) < 0) {
00216 DLOG_CRIT("Cannot open lockfile. Exiting.");
00217 LOG_CLOSE();
00218 exit(EXIT_FAILURE);
00219 }
00220
00221 if (lockf(i, F_TLOCK, 0) < 0) {
00222 DLOG_CRIT("Already running. Exiting.");
00223 LOG_CLOSE();
00224 exit(EXIT_FAILURE);
00225 }
00226
00227 sprintf(str, "%d\n", getpid());
00228 write(i, str, strlen(str));
00229 close(i);
00230
00231
00232 signal(SIGTSTP, SIG_IGN);
00233 signal(SIGTTOU, SIG_IGN);
00234 signal(SIGTTIN, SIG_IGN);
00235
00236
00237 signal(SIGCHLD, SIG_IGN);
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 int main(int argc, char **argv)
00248 {
00249 int optc;
00250 int opt_index;
00251
00252 gint status = 0;
00253 gboolean daemonflag = FALSE;
00254
00255 AlarmdQueue *queue = NULL;
00256 osso_context_t *osso = NULL;
00257 gchar *queue_file = NULL;
00258 gchar *next_time_file = NULL;
00259 gchar *next_mode_file = NULL;
00260
00261 const char optline[] = "d";
00262
00263 struct option const options[] = {
00264 { "daemonflag", no_argument, 0, 'd' },
00265 { "help", no_argument, 0, 'h' },
00266 { "version", no_argument, 0, 'V' },
00267 { 0, 0, 0, 0 }
00268 };
00269
00270
00271 mainloop = NULL;
00272
00273
00274 if (init_locales(PRG_NAME) != 0)
00275 goto EXIT;
00276
00277
00278 while ((optc = getopt_long(argc, argv, optline,
00279 options, &opt_index)) != -1) {
00280 switch (optc) {
00281 case 'd':
00282 daemonflag = TRUE;
00283 break;
00284
00285 case 'h':
00286 usage();
00287 goto EXIT;
00288
00289 case 'V':
00290 version();
00291 goto EXIT;
00292
00293 default:
00294 usage();
00295 status = EINVAL;
00296 goto EXIT;
00297 }
00298 }
00299
00300
00301 if ((argc - optind) > 0) {
00302 fprintf(stderr,
00303 _("%s: Too many arguments\n"
00304 "Try: `%s --help' for more information.\n"),
00305 progname, progname);
00306 status = EINVAL;
00307 goto EXIT;
00308 }
00309
00310 DLOG_OPEN(PRG_NAME);
00311
00312
00313 if (daemonflag == TRUE)
00314 daemonize();
00315
00316 signal(SIGUSR1, signal_handler);
00317 signal(SIGHUP, signal_handler);
00318 signal(SIGTERM, signal_handler);
00319
00320
00321 g_type_init();
00322
00323 alarmd_type_init();
00324 osso = init_osso();
00325 dbus_set_osso(osso);
00326
00327 queue_file = g_build_filename(DATADIR, "alarm_queue.xml", NULL);
00328 next_time_file = g_build_filename(DATADIR, "next_alarm_time", NULL);
00329 next_mode_file = g_build_filename(DATADIR, "next_alarm_mode", NULL);
00330
00331 queue = init_queue(queue_file, next_time_file, next_mode_file);
00332 set_osso_callbacks(osso, queue);
00333 g_free(queue_file);
00334 g_free(next_time_file);
00335 g_free(next_mode_file);
00336
00337
00338 mainloop = g_main_loop_new(NULL, FALSE);
00339
00340
00341 g_main_loop_run(mainloop);
00342
00343
00344 deinit_osso(osso, queue);
00345 g_object_unref(queue);
00346
00347
00348
00349 EXIT:
00350
00351 if (mainloop != NULL)
00352 g_main_loop_unref(mainloop);
00353
00354
00355 DLOG_INFO("Exiting...");
00356 LOG_CLOSE();
00357
00358 return status;
00359 }