/*- * Copyright (C) 2005-2007 Nick Withers. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #ifndef BSD /* sysexits.h only exists on BSD systems (as far as I know), so define exit codes for other platforms */ #define EX_USAGE EXIT_FAILURE #define EX_DATAERR EXIT_FAILURE #define EX_NOINPUT EXIT_FAILURE #define EX_NOUSER EXIT_FAILURE #define EX_NOHOST EXIT_FAILURE #define EX_UNAVAILABLE EXIT_FAILURE #define EX_SOFTWARE EXIT_FAILURE #define EX_OSERR EXIT_FAILURE #define EX_OSFILE EXIT_FAILURE #define EX_CANTCREAT EXIT_FAILURE #define EX_IOERR EXIT_FAILURE #define EX_TEMPFAIL EXIT_FAILURE #define EX_PROTOCOL EXIT_FAILURE #define EX_NOPERM EXIT_FAILURE #define EX_CONFIG EXIT_FAILURE #endif #ifndef EFTYPE #define EFTYPE EINVAL /* EFTYPE ("Inappropriate file type or format") doesn't necessarily exist, so if it doesn't, #define it to be EINVAL ("Invalid argument") */ #endif #define PRGNAME "DownTime" #define VERSION "0.3.1.1" #define COPYRIGHT "Copyright (c) 2005-2007, Nick Withers. All rights reserved." #define LICENSE_SHORT "BSD License" #define LICENSE_LONG \ PRGNAME " is distributed under the following terms:\n"\ "\n"\ COPYRIGHT "\n"\ "\n"\ "Redistribution and use in source and binary forms, with or without\n"\ "modification, are permitted provided that the following conditions\n"\ "are met:\n"\ "1. Redistributions of source code must retain the above copyright\n"\ " notice, this list of conditions and the following disclaimer.\n"\ "2. Redistributions in binary form must reproduce the above copyright\n"\ " notice, this list of conditions and the following disclaimer in the\n"\ " documentation and/or other materials provided with the distribution.\n"\ "\n"\ "THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND\n"\ "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"\ "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"\ "ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE\n"\ "FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"\ "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"\ "OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n"\ "HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n"\ "LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n"\ "OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"\ "SUCH DAMAGE." #define CONTACT_EMAIL "downtime@nickwithers.com" #define CONTACT_WWW "http://nickwithers.com/downtime" #define AUTHORS { \ "Nick Withers (nick@nickwithers.com)", \ (char *) NULL \ } enum SHUTDOWN_TYPES {POWEROFF, RESTART, HALT, SINGLE_USER}; enum TIMEOUT_UNITS {MINUTES, HOURS, DAYS}; #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define DEFAULT_TIMEOUT 60 #define DEFAULT_TIMEOUT_UNIT MINUTES #define DEFAULT_SHUTDOWN_TYPE POWEROFF #define DEFAULT_REMEMBER TRUE #define SHUTDOWN_FILENAME "shutdown" #define DEFAULT_SHUTDOWN_PATH "/sbin/" SHUTDOWN_FILENAME #ifndef WITH_NOFORK_SHUTDOWN_PARAMETER #define PID_OUTPUT_FILENO STDERR_FILENO /* The file descriptor on which shutdown(8) outputs its PID */ #define START_SHUTDOWN_PID_OUTPUT SHUTDOWN_FILENAME ": [pid " /* In order for DownTime to be able to pick up shutdown(8)'s PID, the correct preceding text needs to be specified here. The number immediately following this text (whitespace is fine) will be taken to be the PID */ #endif #define DIR_SEPARATOR '/' #define DIR_SEPARATOR_STRING "/" #define PATH_SEPARATOR ':' #define CONFIG_FILE_NAME ".downtime" typedef struct { pid_t pid; unsigned long int timeout; /* Stores the timeout value for the shutdown in minutes */ time_t start_time; time_t shutdown_time; unsigned int type : 3; /* This'll actually store an index of enum SHUTDOWN_TYPES, so doesn't need to occupy too much space! We've got 0 - 7 here */ unsigned int in_progress : 1; unsigned int paused : 1; } shutdown_t; typedef struct { char *config_path; unsigned long int timeout; /* This holds the timeout value as specified by the user. It must be used in conjunction with timeout_unit to get a value in minutes that can be stored in shutdown.timeout */ unsigned int timeout_unit : 2; /* This'll actually store an index of enum SHUTDOWN_TYPES, so doesn't need to occupy too much space! We've got 0 - 3 here */ unsigned int shutdown_type : 3; /* This'll actually store an index of enum SHUTDOWN_TYPES, so doesn't need to occupy too much space! We've got 0 - 7 here */ unsigned int remember : 1; unsigned int advanced_main : 1; /* Preferences */ unsigned int main_window_always_on_top : 1; unsigned int progress_window_always_on_top : 1; } user_specs_t; char add_to_unique_string_array(char ***string_array, size_t *array_length, char *string_to_add); char add_to_string_array(char ***string_array, size_t *array_length, char *string_to_add); char array_add(void **array, size_t *length, const void *add_me, size_t elem_size); char cat_strchar(char **original_string, const char append_me); char * cat_strings(const char *shutdown_string, const char *append_me); char * find_executable_in_path(char *filename); char * get_config_path(void); char * get_filename_from_path(const char *path); char * get_shutdown_time_left_string(shutdown_t *shutdown); void init_user_specs(user_specs_t *specs); char is_in_string_array(char **string_array, size_t array_length, char *string_to_add); char load_user_specs(user_specs_t *specs, char *config_path); long int max_minutes_to_shutdown(shutdown_t *shutdown); int pasprintf(char **ret, const char *fmt, ...); int pvasprintf(char **ret, const char *fmt, va_list ap); void save_user_specs(user_specs_t *specs, char *config_path); void show_error_dialog(int eval, const char *fmt, ...); void show_main_window(user_specs_t *specs); void show_stderr(const char *fmt, ...); void show_warning_dialog(const char *fmt, ...); shutdown_t * start_shutdown(user_specs_t *specs, shutdown_t *shutdown); char * trim_white(const char *string);