X-Git-Url: http://git.annexia.org/?p=whenjobs.git;a=blobdiff_plain;f=daemon%2Fwhenjobsd.ml;fp=daemon%2Fwhenjobsd.ml;h=a994279b30ad29765c587e9fe74567ada67ae86d;hp=0000000000000000000000000000000000000000;hb=61cad7bbaf63389b520b695eefdd735bc11a8aa6;hpb=21298f7a45ee536800be5e771438b01089a5cb2c diff --git a/daemon/whenjobsd.ml b/daemon/whenjobsd.ml new file mode 100644 index 0000000..a994279 --- /dev/null +++ b/daemon/whenjobsd.ml @@ -0,0 +1,129 @@ +(* whenjobs daemon + * Copyright (C) 2012 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *) + +open Unix +open Printf + +let () = + (* Running the daemon as root is a mistake. It must be run as a + * non-root user. + *) + let euid = geteuid () in + if euid = 0 then ( + eprintf "whenjobsd: this daemon must run as the local user, NOT root\n"; + exit 1 + ); + + (* $HOME must be defined and must exist and be a directory and must be + * owned by the current user. + *) + let home = + try getenv "HOME" + with Not_found -> + eprintf "whenjobsd: $HOME environment variable must be defined\n"; + exit 1 in + + let stat = + try lstat home + with Unix_error (err, fn, _) -> + eprintf "whenjobsd: %s: %s ($HOME): %s\n" fn home (error_message err); + exit 1 in + if stat.st_kind != S_DIR then ( + eprintf "whenjobsd: %s ($HOME): not a directory\n" home; + exit 1 + ); + + if stat.st_uid != euid then ( + eprintf "whenjobsd: %s ($HOME): not owned by the current user (uid %d)\n" + home euid; + exit 1 + ); + + (* Parse the command line arguments. *) + let debug = ref false in + let do_fork = ref true in + + let display_version () = + printf "%s %s\n" Config.package_name Config.package_version; + exit 0 + in + + let argspec = Arg.align [ + "-d", Arg.Set debug, " Enable extra debugging messages"; + "-f", Arg.Clear do_fork, " Don't fork into background"; + "-V", Arg.Unit display_version, " Display version number and exit"; + "--version", Arg.Unit display_version, " Display version number and exit"; + ] in + + let anon_fun _ = raise (Arg.Bad "unknown command line argument") in + + let usage_msg = "\ +Usage: + whenjobsd [--options] + +For documentation see the whenjobs(1) and whenjobsd(8) man pages. + +Options: +" in + + Arg.parse argspec anon_fun usage_msg; + + let debug = !debug in + let do_fork = !do_fork in + + (* Make the $HOME/.whenjobs directory if it doesn't exist. *) + let jobsdir = sprintf "%s/.whenjobs" home in + (try mkdir jobsdir 0o700 with Unix_error _ -> ()); + + (* Create the socket. *) + Daemon.init jobsdir debug; + + (* Fork into background. *) + if do_fork then ( + let pid = fork () in + if pid > 0 then exit 0; + + (* chdir / so we don't prevent filesystems from being unmounted. *) + chdir "/"; + + (* Close file descriptors. *) + close stdin; + close stdout; + close stderr; + + (* Create a new session. *) + ignore (setsid ()); + + (* Ignore SIGHUP. *) + Sys.set_signal Sys.sighup Sys.Signal_ignore; + + (* Update the PID file since we just forked. *) + Whenlock.update_pid (); + ); + + (* Start syslog. *) + Syslog.notice "daemon started: uid=%d home=%s" euid home; + + (* If there is a jobs.cmo file, load it. *) + let () = + let file = sprintf "%s/jobs.cmo" jobsdir in + if Sys.file_exists file then + try Daemon.reload_file () with Failure _ -> () in + + (* Go into main loop. *) + Daemon.main_loop ()