From: short <> Date: Sun, 26 Jun 2005 01:58:58 +0000 (+0000) Subject: Implemented crossplatform automatic startup management. X-Git-Tag: udpgate-1_0_2~26 X-Git-Url: http://git.jankratochvil.net/?p=udpgate.git;a=commitdiff_plain;h=91537644d1e946d3ed9b53c6eb69d1dbe2579f4e Implemented crossplatform automatic startup management. --- diff --git a/src/main.c b/src/main.c index a2a7c61..e9833d9 100644 --- a/src/main.c +++ b/src/main.c @@ -37,7 +37,7 @@ #include "ui-line.h" #include "network.h" #include "configuration.h" -#include "startup.h" +#include "static-startup.h" #ifdef ENABLE_BUNDLE #include "bundle-util.h" #endif @@ -276,16 +276,13 @@ guint handler_id; if (!is_interactive) { - if (optarg_startup_query || optarg_startup_off || optarg_startup_on) - startup_init(); - if (optarg_stop) if (!network_stop()) exit_rc=2; if (optarg_startup_query) { gboolean is_on; - if (startup_query(&is_on)) { + if (static_startup_query(&is_on)) { g_message((is_on ? _("System startup registrance is turned on.") : _("System startup registrance is turned off."))); @@ -296,11 +293,11 @@ gboolean is_on; exit_rc=2; } if (optarg_startup_off) { - if (!startup_off()) + if (!static_startup_off()) exit_rc=2; } if (optarg_startup_on) { - if (!startup_on()) + if (!static_startup_on()) exit_rc=2; } if (optarg_start) diff --git a/src/startup-chkconfig.c b/src/startup-chkconfig.c index 09900d6..6c0aa0d 100644 --- a/src/startup-chkconfig.c +++ b/src/startup-chkconfig.c @@ -42,9 +42,6 @@ */ #define INIT_D_PATHNAME G_STRINGIFY(SYSCONFDIR) "/init.d/" PACKAGE -#define COMMAND_INSTALL_INIT_D "/usr/lib/lsb/install_initd" -#define COMMAND_REMOVE_INIT_D "/usr/lib/lsb/remove_initd" - #define STATUS_0_1(status) ( \ !(WIFEXITED((status)) && (WEXITSTATUS((status))==0 || WEXITSTATUS((status))==1) \ @@ -52,74 +49,44 @@ && !WIFSTOPPED((status))) \ ? -1 : WEXITSTATUS((status))) -static gboolean chkexec(const gchar *binary) + +static gboolean udpgate_startup_chkconfig_init(UdpgateStartup *udpgate_startup) { -struct stat statbuf; +int status; +const gchar *command="chkconfig " PACKAGE " 2>/dev/null"; - g_return_val_if_fail(binary!=NULL,FALSE); + g_return_val_if_fail(UDPGATE_IS_STARTUP_CHKCONFIG(udpgate_startup),FALSE); - if (stat(COMMAND_INSTALL_INIT_D,&statbuf)) - return FALSE; - if ((statbuf.st_mode&(S_IFMT|0111))!=(S_IFREG|0111)) + status=system(command); + if (STATUS_0_1(status)<0) return FALSE; - return TRUE; } - -gboolean startup_chkconfig_init(void) -{ -static gboolean r,r_set=FALSE; - - if (!r_set) { -int status; -const gchar *command="chkconfig " PACKAGE; - - /* LSB compliant 'query' is not standardized. */ - if (chkexec(COMMAND_INSTALL_INIT_D) && chkexec(COMMAND_REMOVE_INIT_D)) - r=TRUE; - else { - status=system(command); - if (STATUS_0_1(status)<0) { - g_warning(_("Error checking validity of chkconfig(8) setup; automatic startup disabled; failed command: %s"),command); - r=FALSE; - } - else - r=TRUE; - } - r_set=TRUE; - } - return r; -} - -gboolean startup_chkconfig_query(gboolean *is_on) +static gboolean udpgate_startup_chkconfig_query(UdpgateStartup *udpgate_startup,gboolean *is_on) { int status,status_0_1; const gchar *command="chkconfig " PACKAGE; - g_return_val_if_fail(is_on!=NULL,FALSE); - - if (!startup_chkconfig_init()) - return FALSE; + g_return_val_if_fail(UDPGATE_IS_STARTUP_CHKCONFIG(udpgate_startup),FALSE); - /* LSB compliant 'query' is not standardized. */ status=system(command); status_0_1=STATUS_0_1(status); if (status_0_1<0) { g_warning(_("Error checking registrance of this program automatic startup by: %s"),command); return FALSE; } - *is_on=(status_0_1==0); + if (is_on) + *is_on=(status_0_1==0); return TRUE; } -gboolean startup_chkconfig_on(void) +static gboolean udpgate_startup_chkconfig_on(UdpgateStartup *udpgate_startup) { +const gchar *command="chkconfig --add " PACKAGE; int status; -const gchar *command="chkconfig --add"; - if (!startup_chkconfig_init()) - return FALSE; + g_return_val_if_fail(UDPGATE_IS_STARTUP_CHKCONFIG(udpgate_startup),FALSE); #ifdef ENABLE_BUNDLE if (!bundle_util_file_write( @@ -130,9 +97,6 @@ const gchar *command="chkconfig --add"; return FALSE; #endif /* ENABLE_BUNDLE */ - if (chkexec(COMMAND_INSTALL_INIT_D)) - command=COMMAND_INSTALL_INIT_D; - command=udpgate_printf_alloca("%s %s",command,PACKAGE); status=system(command); if (0!=STATUS_0_1(status)) { @@ -142,25 +106,58 @@ const gchar *command="chkconfig --add"; return TRUE; } -gboolean startup_chkconfig_off(void) +static gboolean udpgate_startup_chkconfig_off(UdpgateStartup *udpgate_startup) { -const gchar *command="chkconfig --del"; +const gchar *command="chkconfig --del " PACKAGE; int status; - if (!startup_chkconfig_init()) - return FALSE; + g_return_val_if_fail(UDPGATE_IS_STARTUP_CHKCONFIG(udpgate_startup),FALSE); - if (chkexec(COMMAND_REMOVE_INIT_D)) - command=COMMAND_REMOVE_INIT_D; - command=udpgate_printf_alloca("%s %s",command,PACKAGE); status=system(command); if (0!=STATUS_0_1(status)) { g_warning(_("Error removing program's system startup registrance by: %s"),command); return FALSE; } + #ifdef ENABLE_BUNDLE if (!bundle_util_file_remove(INIT_D_PATHNAME,PACKAGE ".init")) return FALSE; #endif /* ENABLE_BUNDLE */ + return TRUE; } + +static void udpgate_startup_chkconfig_class_init (UdpgateStartupChkconfigClass *class) +{ + UdpgateStartupClass *udpgate_startup_class = UDPGATE_STARTUP_CLASS(class); + + udpgate_startup_class->init = udpgate_startup_chkconfig_init; + udpgate_startup_class->query = udpgate_startup_chkconfig_query; + udpgate_startup_class->on = udpgate_startup_chkconfig_on; + udpgate_startup_class->off = udpgate_startup_chkconfig_off; +} + +GType udpgate_startup_chkconfig_get_type(void) +{ + static GType udpgate_startup_chkconfig_type=0; + + if (!udpgate_startup_chkconfig_type) { + static const GTypeInfo udpgate_startup_chkconfig_info={ + sizeof(UdpgateStartupChkconfigClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)udpgate_startup_chkconfig_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(UdpgateStartupChkconfig), + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + + udpgate_startup_chkconfig_type=g_type_register_static(UDPGATE_TYPE_STARTUP,"UdpgateStartupChkconfig", + &udpgate_startup_chkconfig_info,0); + } + + return udpgate_startup_chkconfig_type; +} diff --git a/src/startup-chkconfig.h b/src/startup-chkconfig.h index 829d21d..6abcecd 100644 --- a/src/startup-chkconfig.h +++ b/src/startup-chkconfig.h @@ -1,5 +1,5 @@ /* $Id$ - * Include file for UDP Gateway utility startup scripts support using chkconfig(8) + * Include file for UDP Gateway utility startup_chkconfig scripts inheritance support * Copyright (C) 2004 Jan Kratochvil * * This program is free software; you can redistribute it and/or modify @@ -22,14 +22,34 @@ #include +#include +#include "startup.h" G_BEGIN_DECLS -gboolean startup_chkconfig_init(void); -gboolean startup_chkconfig_query(gboolean *is_on); -gboolean startup_chkconfig_on(void); -gboolean startup_chkconfig_off(void); +#define UDPGATE_TYPE_STARTUP_CHKCONFIG (udpgate_startup_chkconfig_get_type()) +#define UDPGATE_STARTUP_CHKCONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),UDPGATE_TYPE_STARTUP_CHKCONFIG,UdpgateStartupChkconfig)) +#define UDPGATE_STARTUP_CHKCONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),UDPGATE_TYPE_STARTUP_CHKCONFIG,UdpgateStartupChkconfigClass)) +#define UDPGATE_IS_STARTUP_CHKCONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),UDPGATE_TYPE_STARTUP_CHKCONFIG)) +#define UDPGATE_IS_STARTUP_CHKCONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),UDPGATE_TYPE_STARTUP_CHKCONFIG)) +#define UDPGATE_STARTUP_CHKCONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),UDPGATE_TYPE_STARTUP_CHKCONFIG,UdpgateStartupChkconfigClass)) + +typedef struct _UdpgateStartupChkconfig UdpgateStartupChkconfig; +typedef struct _UdpgateStartupChkconfigClass UdpgateStartupChkconfigClass; + +struct _UdpgateStartupChkconfig +{ + UdpgateStartup parent_instance; +}; + +struct _UdpgateStartupChkconfigClass +{ + UdpgateStartupClass parent_class; +}; + +GType udpgate_startup_chkconfig_get_type(void) G_GNUC_CONST; +UdpgateStartupChkconfig *udpgate_startup_chkconfig_new(void); G_END_DECLS diff --git a/src/startup-debian.c b/src/startup-debian.c new file mode 100644 index 0000000..16a931c --- /dev/null +++ b/src/startup-debian.c @@ -0,0 +1,238 @@ +/* $Id$ + * UDP Gateway utility startup scripts support using debian(8) + * Copyright (C) 2004 Jan Kratochvil + * + * 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; exactly version 2 of June 1991 is required + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "startup-debian.h" /* self */ + +#ifdef ENABLE_BUNDLE +#include "bundle-util.h" +#endif + + +/* Config: */ +/* Do not: /etc/rc.d/init.d/... + * to comply with http://www.linuxbase.org/spec/booksets/LSB-Core/LSB-Core.html#INITSRCINSTRM + */ +#define INIT_D_PATHNAME G_STRINGIFY(SYSCONFDIR) "/init.d/" PACKAGE + + +#define STATUS_0_1(status) ( \ + !(WIFEXITED((status)) && (WEXITSTATUS((status))==0 || WEXITSTATUS((status))==1) \ + && !WIFSIGNALED((status)) \ + && !WIFSTOPPED((status))) \ + ? -1 : WEXITSTATUS((status))) + + +static gboolean udpgate_startup_debian_init(UdpgateStartup *udpgate_startup) +{ +int status; +/* ">/dev/null" for: Adding system startup for /etc/init.d/PACKAGE ... + * "2>/dev/null" for: bash: update-rc.d: command not found + */ +const gchar *command="update-rc.d -n " PACKAGE " defaults &>/dev/null"; + + g_return_val_if_fail(UDPGATE_IS_STARTUP_DEBIAN(udpgate_startup),FALSE); + + status=system(command); + if (STATUS_0_1(status)<0) { + g_warning(_("Error checking validity of debian(8) setup; automatic startup disabled; failed command: %s"),command); + return FALSE; + } + return TRUE; +} + +static gboolean udpgate_startup_debian_query(UdpgateStartup *udpgate_startup,gboolean *is_on) +{ +const gchar *command="update-rc.d -n " PACKAGE " defaults 2>/dev/null"; +static char buffer[0x1000]; +char *s; +size_t fread_got; +FILE *f; + + g_return_val_if_fail(UDPGATE_IS_STARTUP_DEBIAN(udpgate_startup),FALSE); + + if (!(f=popen(command,"r"))) { +#if 0 + g_warning(_("Error checking registrance of this program automatic startup opening \"%s\": %m"),command); +#endif + return FALSE; + } + fread_got=fread(buffer,1,sizeof(buffer),f); + if (fclose(f)) { +#if 0 + g_warning(_("Error checking registrance of this program automatic startup closing \"%s\": %m"),command); +#endif + return FALSE; + } + if (fread_got<=0 || fread_got>=sizeof(buffer)) { +#if 0 + g_warning(_("Error checking registrance of this program automatic startup reading \"%s\": %m"),command); +#endif + return FALSE; + } + buffer[fread_got]='\0'; + for (s=buffer;*s && isspace(*s);s++); + /* Fortunately update-rc.d(8) is just a dumb script without messages localization. */ + +#define TEXT_ADDING_SYSTEM_STARTUP_FOR "Adding system startup for" +/* + Adding system startup for /etc/init.d/PACKAGE ... + /etc/rc0.d/K20PACKAGE -> ../init.d/PACKAGE +... + /etc/rc5.d/S20PACKAGE -> ../init.d/PACKAGE +*/ + if (!strncasecmp(s,TEXT_ADDING_SYSTEM_STARTUP_FOR,strlen(TEXT_ADDING_SYSTEM_STARTUP_FOR))) { + if (is_on) + *is_on=FALSE; + return TRUE; + } + +#define TEXT_SYSTEM_STARTUP_LINKS_FOR "System startup links for" +/* + System startup links for /etc/init.d/PACKAGE already exist. +*/ + if (!strncasecmp(s,TEXT_SYSTEM_STARTUP_LINKS_FOR,strlen(TEXT_SYSTEM_STARTUP_LINKS_FOR))) { + if (is_on) + *is_on=TRUE; + return TRUE; + } + + /* Failed: */ + if ((s=strchr(buffer,'\n'))) + *s='\0'; + g_warning(_("Error checking registrance of this program, unknown output of \"%s\": %s"),command,buffer); + return FALSE; +} + +static gboolean udpgate_startup_debian_on(UdpgateStartup *udpgate_startup) +{ +/* Do not: " >/dev/null" + * as it is useful for: Adding system startup for /etc/init.d/PACKAGE ... + * but it is bad for: + * Adding system startup for /etc/init.d/PACKAGE ... + * /etc/rc0.d/K20PACKAGE -> ../init.d/PACKAGE + * update-rc.d: symlink: Permission denied + * as the second line also gets hidden. + */ +const gchar *command="update-rc.d " PACKAGE " defaults"; +int status; + + g_return_val_if_fail(UDPGATE_IS_STARTUP_DEBIAN(udpgate_startup),FALSE); + +#ifdef ENABLE_BUNDLE + if (!bundle_util_file_write( + INIT_D_PATHNAME, /* pathname */ + PACKAGE ".init", /* basename */ + 0755, /* pathname_mode */ + TRUE)) /* pathname_backup */ + return FALSE; +#endif /* ENABLE_BUNDLE */ + + status=system(command); + + if (0!=STATUS_0_1(status)) { + g_warning(_("Error registering automatic program startup by: %s"),command); + return FALSE; + } + return TRUE; +} + +static gboolean udpgate_startup_debian_off(UdpgateStartup *udpgate_startup) +{ +/* Do not: " >/dev/null" + * as it is useful for: Removing any system startup links for /etc/init.d/PACKAGE ... + * but it is bad for: + * Removing any system startup links for /etc/init.d/PACKAGE ... + * /etc/rc0.d/S30PACKAGE + * update-rc.d: unlink: Permission denied + * as the second line also gets hidden. + */ +/* "-f" can be prevented for: ENABLE_BUNDLE + * by removing 'INIT_D_PATHNAME' first but it would still not work for + * regular non-bundled packaging. + */ +const gchar *command="update-rc.d -f " PACKAGE " remove"; +int status; + + g_return_val_if_fail(UDPGATE_IS_STARTUP_DEBIAN(udpgate_startup),FALSE); + +#ifdef ENABLE_BUNDLE + /* init.d file must no longer exist for: update-rc.d PACKAGE remove + * without using its: -f|--force + */ + if (!bundle_util_file_remove(INIT_D_PATHNAME,PACKAGE ".init")) + return FALSE; +#endif /* ENABLE_BUNDLE */ + + status=system(command); + if (0!=STATUS_0_1(status)) { + g_warning(_("Error removing program's system startup registrance by: %s"),command); + return FALSE; + } + + return TRUE; +} + +static void udpgate_startup_debian_class_init (UdpgateStartupDebianClass *class) +{ + UdpgateStartupClass *udpgate_startup_class = UDPGATE_STARTUP_CLASS(class); + + udpgate_startup_class->init = udpgate_startup_debian_init; + udpgate_startup_class->query = udpgate_startup_debian_query; + udpgate_startup_class->on = udpgate_startup_debian_on; + udpgate_startup_class->off = udpgate_startup_debian_off; +} + +GType udpgate_startup_debian_get_type(void) +{ + static GType udpgate_startup_debian_type=0; + + if (!udpgate_startup_debian_type) { + static const GTypeInfo udpgate_startup_debian_info={ + sizeof(UdpgateStartupDebianClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)udpgate_startup_debian_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(UdpgateStartupDebian), + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + + udpgate_startup_debian_type=g_type_register_static(UDPGATE_TYPE_STARTUP,"UdpgateStartupDebian", + &udpgate_startup_debian_info,0); + } + + return udpgate_startup_debian_type; +} diff --git a/src/startup-debian.h b/src/startup-debian.h new file mode 100644 index 0000000..d49b38f --- /dev/null +++ b/src/startup-debian.h @@ -0,0 +1,57 @@ +/* $Id$ + * Include file for UDP Gateway utility startup_debian scripts inheritance support + * Copyright (C) 2004 Jan Kratochvil + * + * 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; exactly version 2 of June 1991 is required + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _UDPGATE_STARTUP_DEBIAN_H +#define _UDPGATE_STARTUP_DEBIAN_H 1 + + +#include +#include +#include "startup.h" + + +G_BEGIN_DECLS + +#define UDPGATE_TYPE_STARTUP_DEBIAN (udpgate_startup_debian_get_type()) +#define UDPGATE_STARTUP_DEBIAN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),UDPGATE_TYPE_STARTUP_DEBIAN,UdpgateStartupDebian)) +#define UDPGATE_STARTUP_DEBIAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),UDPGATE_TYPE_STARTUP_DEBIAN,UdpgateStartupDebianClass)) +#define UDPGATE_IS_STARTUP_DEBIAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),UDPGATE_TYPE_STARTUP_DEBIAN)) +#define UDPGATE_IS_STARTUP_DEBIAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),UDPGATE_TYPE_STARTUP_DEBIAN)) +#define UDPGATE_STARTUP_DEBIAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),UDPGATE_TYPE_STARTUP_DEBIAN,UdpgateStartupDebianClass)) + +typedef struct _UdpgateStartupDebian UdpgateStartupDebian; +typedef struct _UdpgateStartupDebianClass UdpgateStartupDebianClass; + +struct _UdpgateStartupDebian +{ + UdpgateStartup parent_instance; +}; + +struct _UdpgateStartupDebianClass +{ + UdpgateStartupClass parent_class; +}; + +GType udpgate_startup_debian_get_type(void) G_GNUC_CONST; +UdpgateStartupDebian *udpgate_startup_debian_new(void); + +G_END_DECLS + + +#endif /* _UDPGATE_STARTUP_DEBIAN_H */ diff --git a/src/startup-lsb.c b/src/startup-lsb.c new file mode 100644 index 0000000..00d8839 --- /dev/null +++ b/src/startup-lsb.c @@ -0,0 +1,166 @@ +/* $Id$ + * UDP Gateway utility startup scripts support using lsb(8) + * Copyright (C) 2004 Jan Kratochvil + * + * 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; exactly version 2 of June 1991 is required + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "startup-lsb.h" /* self */ + +#ifdef ENABLE_BUNDLE +#include "bundle-util.h" +#endif + + +/* Config: */ +/* Do not: /etc/rc.d/init.d/... + * to comply with http://www.linuxbase.org/spec/booksets/LSB-Core/LSB-Core.html#INITSRCINSTRM + */ +#define INIT_D_PATHNAME G_STRINGIFY(SYSCONFDIR) "/init.d/" PACKAGE + +#define COMMAND_INSTALL_INIT_D "/usr/lib/lsb/install_initd" +#define COMMAND_REMOVE_INIT_D "/usr/lib/lsb/remove_initd" + + +#define STATUS_0_1(status) ( \ + !(WIFEXITED((status)) && (WEXITSTATUS((status))==0 || WEXITSTATUS((status))==1) \ + && !WIFSIGNALED((status)) \ + && !WIFSTOPPED((status))) \ + ? -1 : WEXITSTATUS((status))) + +static gboolean chkexec(const gchar *binary) +{ +struct stat statbuf; + + g_return_val_if_fail(binary!=NULL,FALSE); + + if (stat(COMMAND_INSTALL_INIT_D,&statbuf)) + return FALSE; + if ((statbuf.st_mode&(S_IFMT|0111))!=(S_IFREG|0111)) + return FALSE; + + return TRUE; +} + + +static gboolean udpgate_startup_lsb_init(UdpgateStartup *udpgate_startup) +{ + g_return_val_if_fail(UDPGATE_IS_STARTUP_LSB(udpgate_startup),FALSE); + + /* LSB compliant 'query' is not standardized. */ + if (chkexec(COMMAND_INSTALL_INIT_D) && chkexec(COMMAND_REMOVE_INIT_D)) + return TRUE; + return FALSE; +} + +static gboolean udpgate_startup_lsb_query(UdpgateStartup *udpgate_startup,gboolean *is_on) +{ + g_return_val_if_fail(UDPGATE_IS_STARTUP_LSB(udpgate_startup),FALSE); + + /* LSB compliant 'query' is not standardized. */ + return FALSE; +} + +static gboolean udpgate_startup_lsb_on(UdpgateStartup *udpgate_startup) +{ +const gchar *command=COMMAND_INSTALL_INIT_D " " PACKAGE; +int status; + + g_return_val_if_fail(UDPGATE_IS_STARTUP_LSB(udpgate_startup),FALSE); + +#ifdef ENABLE_BUNDLE + if (!bundle_util_file_write( + INIT_D_PATHNAME, /* pathname */ + PACKAGE ".init", /* basename */ + 0755, /* pathname_mode */ + TRUE)) /* pathname_backup */ + return FALSE; +#endif /* ENABLE_BUNDLE */ + + status=system(command); + if (0!=STATUS_0_1(status)) { + g_warning(_("Error registering automatic program startup by: %s"),command); + return FALSE; + } + return TRUE; +} + +static gboolean udpgate_startup_lsb_off(UdpgateStartup *udpgate_startup) +{ +const gchar *command=COMMAND_REMOVE_INIT_D " " PACKAGE; +int status; + + g_return_val_if_fail(UDPGATE_IS_STARTUP_LSB(udpgate_startup),FALSE); + + status=system(command); + if (0!=STATUS_0_1(status)) { + g_warning(_("Error removing program's system startup registrance by: %s"),command); + return FALSE; + } + +#ifdef ENABLE_BUNDLE + if (!bundle_util_file_remove(INIT_D_PATHNAME,PACKAGE ".init")) + return FALSE; +#endif /* ENABLE_BUNDLE */ + + return TRUE; +} + +static void udpgate_startup_lsb_class_init (UdpgateStartupLsbClass *class) +{ + UdpgateStartupClass *udpgate_startup_class = UDPGATE_STARTUP_CLASS(class); + + udpgate_startup_class->init = udpgate_startup_lsb_init; + udpgate_startup_class->query = udpgate_startup_lsb_query; + udpgate_startup_class->on = udpgate_startup_lsb_on; + udpgate_startup_class->off = udpgate_startup_lsb_off; +} + +GType udpgate_startup_lsb_get_type(void) +{ + static GType udpgate_startup_lsb_type=0; + + if (!udpgate_startup_lsb_type) { + static const GTypeInfo udpgate_startup_lsb_info={ + sizeof(UdpgateStartupLsbClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)udpgate_startup_lsb_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(UdpgateStartupLsb), + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + + udpgate_startup_lsb_type=g_type_register_static(UDPGATE_TYPE_STARTUP,"UdpgateStartupLsb", + &udpgate_startup_lsb_info,0); + } + + return udpgate_startup_lsb_type; +} diff --git a/src/startup-lsb.h b/src/startup-lsb.h new file mode 100644 index 0000000..2c2c575 --- /dev/null +++ b/src/startup-lsb.h @@ -0,0 +1,57 @@ +/* $Id$ + * Include file for UDP Gateway utility startup_lsb scripts inheritance support + * Copyright (C) 2004 Jan Kratochvil + * + * 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; exactly version 2 of June 1991 is required + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _UDPGATE_STARTUP_LSB_H +#define _UDPGATE_STARTUP_LSB_H 1 + + +#include +#include +#include "startup.h" + + +G_BEGIN_DECLS + +#define UDPGATE_TYPE_STARTUP_LSB (udpgate_startup_lsb_get_type()) +#define UDPGATE_STARTUP_LSB(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),UDPGATE_TYPE_STARTUP_LSB,UdpgateStartupLsb)) +#define UDPGATE_STARTUP_LSB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),UDPGATE_TYPE_STARTUP_LSB,UdpgateStartupLsbClass)) +#define UDPGATE_IS_STARTUP_LSB(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),UDPGATE_TYPE_STARTUP_LSB)) +#define UDPGATE_IS_STARTUP_LSB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),UDPGATE_TYPE_STARTUP_LSB)) +#define UDPGATE_STARTUP_LSB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),UDPGATE_TYPE_STARTUP_LSB,UdpgateStartupLsbClass)) + +typedef struct _UdpgateStartupLsb UdpgateStartupLsb; +typedef struct _UdpgateStartupLsbClass UdpgateStartupLsbClass; + +struct _UdpgateStartupLsb +{ + UdpgateStartup parent_instance; +}; + +struct _UdpgateStartupLsbClass +{ + UdpgateStartupClass parent_class; +}; + +GType udpgate_startup_lsb_get_type(void) G_GNUC_CONST; +UdpgateStartupLsb *udpgate_startup_lsb_new(void); + +G_END_DECLS + + +#endif /* _UDPGATE_STARTUP_LSB_H */ diff --git a/src/startup.c b/src/startup.c index 16114fd..d8e1928 100644 --- a/src/startup.c +++ b/src/startup.c @@ -22,30 +22,97 @@ #include #include "startup.h" /* self */ +#include "startup-lsb.h" #include "startup-chkconfig.h" +#include "startup-debian.h" -/* FIXME: Provide some layer for multiple 'startup' handling backends. */ +gboolean udpgate_startup_query(UdpgateStartup *udpgate_startup,gboolean *is_on) +{ + g_return_val_if_fail(UDPGATE_IS_STARTUP(udpgate_startup),FALSE); + return (*UDPGATE_STARTUP_GET_CLASS(udpgate_startup)->query)(udpgate_startup,is_on); +} -gboolean startup_init(void) +gboolean udpgate_startup_on(UdpgateStartup *udpgate_startup) { - return startup_chkconfig_init(); +gboolean is_on; + + g_return_val_if_fail(UDPGATE_IS_STARTUP(udpgate_startup),FALSE); + + if (!udpgate_startup_query(udpgate_startup,&is_on)) + return FALSE; + if (is_on==TRUE) + return TRUE; + + return (*UDPGATE_STARTUP_GET_CLASS(udpgate_startup)->on)(udpgate_startup); } -gboolean startup_query(gboolean *is_on) +gboolean udpgate_startup_off(UdpgateStartup *udpgate_startup) { - g_return_val_if_fail(is_on!=NULL,FALSE); +gboolean is_on; + + g_return_val_if_fail(UDPGATE_IS_STARTUP(udpgate_startup),FALSE); - return startup_chkconfig_query(is_on); + if (!udpgate_startup_query(udpgate_startup,&is_on)) + return FALSE; + if (is_on==FALSE) + return TRUE; + + return (*UDPGATE_STARTUP_GET_CLASS(udpgate_startup)->off)(udpgate_startup); } -gboolean startup_on(void) +UdpgateStartup *udpgate_startup_new(void) +{ + const GType impl_type_array[]={ + UDPGATE_TYPE_STARTUP_LSB, + UDPGATE_TYPE_STARTUP_CHKCONFIG, + UDPGATE_TYPE_STARTUP_DEBIAN, + }; + const GType *impl_type_pointer; + + for (impl_type_pointer = impl_type_array; + impl_type_pointer < impl_type_array + G_N_ELEMENTS(impl_type_array); + impl_type_pointer++) { + UdpgateStartup *udpgate_startup; + + udpgate_startup=g_object_new(*impl_type_pointer,NULL); + g_assert(UDPGATE_IS_STARTUP(udpgate_startup)); + if (UDPGATE_STARTUP_GET_CLASS(udpgate_startup)->init(udpgate_startup)) + return udpgate_startup; + g_object_unref(udpgate_startup); + } + + return NULL; +} + +static void +udpgate_startup_class_init (UdpgateStartupClass *class) { - return startup_chkconfig_on(); } -gboolean startup_off(void) +GType +udpgate_startup_get_type(void) { - return startup_chkconfig_off(); + static GType startup_type=0; + + if (!startup_type) { + static const GTypeInfo startup_info={ + sizeof(UdpgateStartupClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)udpgate_startup_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(UdpgateStartup), + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + + startup_type=g_type_register_static(G_TYPE_OBJECT,"UdpgateStartup", + &startup_info,G_TYPE_FLAG_ABSTRACT); + } + + return startup_type; } diff --git a/src/startup.h b/src/startup.h index da8727d..68abed1 100644 --- a/src/startup.h +++ b/src/startup.h @@ -1,5 +1,5 @@ /* $Id$ - * Include file for UDP Gateway utility startup scripts support + * Include file for UDP Gateway utility startup scripts s inheritance support * Copyright (C) 2004 Jan Kratochvil * * This program is free software; you can redistribute it and/or modify @@ -22,14 +22,41 @@ #include +#include G_BEGIN_DECLS -gboolean startup_init(void); -gboolean startup_query(gboolean *is_on); -gboolean startup_on(void); -gboolean startup_off(void); +#define UDPGATE_TYPE_STARTUP (udpgate_startup_get_type()) +#define UDPGATE_STARTUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),UDPGATE_TYPE_STARTUP,UdpgateStartup)) +#define UDPGATE_STARTUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),UDPGATE_TYPE_STARTUP,UdpgateStartupClass)) +#define UDPGATE_IS_STARTUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),UDPGATE_TYPE_STARTUP)) +#define UDPGATE_IS_STARTUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),UDPGATE_TYPE_STARTUP)) +#define UDPGATE_STARTUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),UDPGATE_TYPE_STARTUP,UdpgateStartupClass)) + +typedef struct _UdpgateStartup UdpgateStartup; +typedef struct _UdpgateStartupClass UdpgateStartupClass; + +struct _UdpgateStartup +{ + GObject parent_instance; +}; + +struct _UdpgateStartupClass +{ + GObjectClass parent_class; + + gboolean (*init)(UdpgateStartup *udpgate_startup); + gboolean (*query)(UdpgateStartup *udpgate_startup,gboolean *is_on); + gboolean (*on)(UdpgateStartup *udpgate_startup); + gboolean (*off)(UdpgateStartup *udpgate_startup); +}; + +GType udpgate_startup_get_type(void) G_GNUC_CONST; +UdpgateStartup *udpgate_startup_new(void); +gboolean udpgate_startup_query(UdpgateStartup *udpgate_startup,gboolean *is_on); +gboolean udpgate_startup_on(UdpgateStartup *udpgate_startup); +gboolean udpgate_startup_off(UdpgateStartup *udpgate_startup); G_END_DECLS diff --git a/src/static-startup.c b/src/static-startup.c new file mode 100644 index 0000000..431150f --- /dev/null +++ b/src/static-startup.c @@ -0,0 +1,81 @@ +/* $Id$ + * UDP Gateway utility startup scripts support + * Copyright (C) 2004 Jan Kratochvil + * + * 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; exactly version 2 of June 1991 is required + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "config.h" + +#include +#include + +#include "static-startup.h" /* self */ +#include "startup.h" +#include "main.h" /* for: optarg_verbose */ + + +static UdpgateStartup *static_startup_udpgate; + + +static gboolean static_startup_udpgate_init(void) +{ +static gboolean first=TRUE; + + if (!static_startup_udpgate && first) { + first=FALSE; + static_startup_udpgate=udpgate_startup_new(); + if (!static_startup_udpgate) + g_warning(_("All automatic startup methods failed; automatic startup disabled.")); + else { + if (optarg_verbose) { + const gchar *startup_base_name=g_type_name(UDPGATE_TYPE_STARTUP); + const gchar *startup_used_name=G_OBJECT_TYPE_NAME(static_startup_udpgate); + + if (!strncmp(startup_base_name,startup_used_name,strlen(startup_base_name))) + startup_used_name+=strlen(startup_base_name); + + g_message(_("Using automatic startup type: %s"),startup_used_name); + } + } + } + return !!static_startup_udpgate; +} + +gboolean static_startup_supported(void) +{ + return static_startup_udpgate_init(); +} + +gboolean static_startup_query(gboolean *is_on) +{ + if (!static_startup_udpgate_init()) + return FALSE; + return udpgate_startup_query(static_startup_udpgate,is_on); +} + +gboolean static_startup_on(void) +{ + if (!static_startup_udpgate_init()) + return FALSE; + return udpgate_startup_on(static_startup_udpgate); +} + +gboolean static_startup_off(void) +{ + if (!static_startup_udpgate_init()) + return FALSE; + return udpgate_startup_off(static_startup_udpgate); +} diff --git a/src/static-startup.h b/src/static-startup.h new file mode 100644 index 0000000..21cb358 --- /dev/null +++ b/src/static-startup.h @@ -0,0 +1,37 @@ +/* $Id$ + * Include file for UDP Gateway utility startup scripts static support + * Copyright (C) 2004 Jan Kratochvil + * + * 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; exactly version 2 of June 1991 is required + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _UDPGATE_STATIC_STARTUP_H +#define _UDPGATE_STATIC_STARTUP_H 1 + + +#include + + +G_BEGIN_DECLS + +gboolean static_startup_supported(void); +gboolean static_startup_query(gboolean *is_on); +gboolean static_startup_on(void); +gboolean static_startup_off(void); + +G_END_DECLS + + +#endif /* _UDPGATE_STATIC_STARTUP_H */