2 * Copyright (C) 2012 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 (* Ensures that Whentools module is linked to the daemon. *)
23 let _ = Whentools.set_variable
26 (* Running the daemon as root is a mistake. It must be run as a
29 let euid = geteuid () in
31 eprintf "whenjobsd: this daemon must run as the local user, NOT root\n";
35 (* $HOME must be defined and must exist and be a directory and must be
36 * owned by the current user.
41 eprintf "whenjobsd: $HOME environment variable must be defined\n";
46 with Unix_error (err, fn, _) ->
47 eprintf "whenjobsd: %s: %s ($HOME): %s\n" fn home (error_message err);
49 if stat.st_kind != S_DIR then (
50 eprintf "whenjobsd: %s ($HOME): not a directory\n" home;
54 if stat.st_uid != euid then (
55 eprintf "whenjobsd: %s ($HOME): not owned by the current user (uid %d)\n"
60 (* Parse the command line arguments. *)
61 let debug = ref false in
62 let do_fork = ref true in
64 let display_version () =
65 printf "%s %s\n" Config.package_name Config.package_version;
69 let argspec = Arg.align [
70 "-d", Arg.Set debug, " Enable extra debugging messages";
71 "-f", Arg.Clear do_fork, " Don't fork into background";
72 "-V", Arg.Unit display_version, " Display version number and exit";
73 "--version", Arg.Unit display_version, " Display version number and exit";
76 let anon_fun _ = raise (Arg.Bad "unknown command line argument") in
82 For documentation see the whenjobs(1) and whenjobsd(8) man pages.
87 Arg.parse argspec anon_fun usage_msg;
90 let do_fork = !do_fork in
92 (* Make the $HOME/.whenjobs directory if it doesn't exist. *)
93 let jobsdir = sprintf "%s/.whenjobs" home in
94 (try mkdir jobsdir 0o700 with Unix_error _ -> ());
96 (* Create the socket. *)
97 Daemon.init jobsdir debug;
99 (* Fork into background. *)
102 if pid > 0 then exit 0;
104 (* chdir / so we don't prevent filesystems from being unmounted. *)
107 (* Close file descriptors, replace with /dev/null. *)
111 ignore (openfile "/dev/null" [O_RDONLY] 0);
112 ignore (openfile "/dev/null" [O_WRONLY] 0);
113 ignore (openfile "/dev/null" [O_WRONLY] 0);
115 (* Create a new session. *)
119 Sys.set_signal Sys.sighup Sys.Signal_ignore;
121 (* Update the PID file since we just forked. *)
122 Whenlock.update_pid ();
126 Syslog.notice "daemon started: version=%s uid=%d home=%s"
127 Config.package_version euid home;
129 (* If there is a jobs.cmo file, load it. *)
131 let file = sprintf "%s/jobs.cmo" jobsdir in
132 if Sys.file_exists file then
133 try Daemon.reload_file () with Failure _ -> () in
135 (* Go into main loop. *)