Implemented crossplatform automatic startup management.
[udpgate.git] / src / startup-lsb.c
1 /* $Id$
2  * UDP Gateway utility startup scripts support using lsb(8)
3  * Copyright (C) 2004 Jan Kratochvil <project-udpgate@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
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.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #include <glib/gmessages.h>
23 #include <stdlib.h>
24 #include <sys/types.h>
25 #include <sys/wait.h>
26 #include <unistd.h>
27 #include <glib/gmem.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <sys/stat.h>
31
32 #include "startup-lsb.h"        /* self */
33
34 #ifdef ENABLE_BUNDLE
35 #include "bundle-util.h"
36 #endif
37
38
39 /* Config: */
40 /* Do not: /etc/rc.d/init.d/...
41  * to comply with http://www.linuxbase.org/spec/booksets/LSB-Core/LSB-Core.html#INITSRCINSTRM
42  */
43 #define INIT_D_PATHNAME G_STRINGIFY(SYSCONFDIR) "/init.d/" PACKAGE
44
45 #define COMMAND_INSTALL_INIT_D "/usr/lib/lsb/install_initd"
46 #define COMMAND_REMOVE_INIT_D  "/usr/lib/lsb/remove_initd"
47
48
49 #define STATUS_0_1(status) ( \
50                 !(WIFEXITED((status)) && (WEXITSTATUS((status))==0 || WEXITSTATUS((status))==1) \
51                                                 && !WIFSIGNALED((status)) \
52                                                 && !WIFSTOPPED((status))) \
53                                 ? -1 : WEXITSTATUS((status)))
54
55 static gboolean chkexec(const gchar *binary)
56 {
57 struct stat statbuf;
58
59         g_return_val_if_fail(binary!=NULL,FALSE);
60
61         if (stat(COMMAND_INSTALL_INIT_D,&statbuf))
62                 return FALSE;
63         if ((statbuf.st_mode&(S_IFMT|0111))!=(S_IFREG|0111))
64                 return FALSE;
65
66         return TRUE;
67 }
68
69
70 static gboolean udpgate_startup_lsb_init(UdpgateStartup *udpgate_startup)
71 {
72         g_return_val_if_fail(UDPGATE_IS_STARTUP_LSB(udpgate_startup),FALSE);
73
74         /* LSB compliant 'query' is not standardized. */
75         if (chkexec(COMMAND_INSTALL_INIT_D) && chkexec(COMMAND_REMOVE_INIT_D))
76                 return TRUE;
77         return FALSE;
78 }
79
80 static gboolean udpgate_startup_lsb_query(UdpgateStartup *udpgate_startup,gboolean *is_on)
81 {
82         g_return_val_if_fail(UDPGATE_IS_STARTUP_LSB(udpgate_startup),FALSE);
83
84         /* LSB compliant 'query' is not standardized. */
85         return FALSE;
86 }
87
88 static gboolean udpgate_startup_lsb_on(UdpgateStartup *udpgate_startup)
89 {
90 const gchar *command=COMMAND_INSTALL_INIT_D " " PACKAGE;
91 int status;
92
93         g_return_val_if_fail(UDPGATE_IS_STARTUP_LSB(udpgate_startup),FALSE);
94
95 #ifdef ENABLE_BUNDLE
96         if (!bundle_util_file_write(
97                         INIT_D_PATHNAME,        /* pathname */
98                         PACKAGE ".init",        /* basename */
99                         0755,   /* pathname_mode */
100                         TRUE))  /* pathname_backup */
101                 return FALSE;
102 #endif /* ENABLE_BUNDLE */
103
104         status=system(command);
105         if (0!=STATUS_0_1(status)) {
106                 g_warning(_("Error registering automatic program startup by: %s"),command);
107                 return FALSE;
108                 }
109         return TRUE;
110 }
111
112 static gboolean udpgate_startup_lsb_off(UdpgateStartup *udpgate_startup)
113 {
114 const gchar *command=COMMAND_REMOVE_INIT_D " " PACKAGE;
115 int status;
116
117         g_return_val_if_fail(UDPGATE_IS_STARTUP_LSB(udpgate_startup),FALSE);
118
119         status=system(command);
120         if (0!=STATUS_0_1(status)) {
121                 g_warning(_("Error removing program's system startup registrance by: %s"),command);
122                 return FALSE;
123                 }
124
125 #ifdef ENABLE_BUNDLE
126         if (!bundle_util_file_remove(INIT_D_PATHNAME,PACKAGE ".init"))
127                 return FALSE;
128 #endif /* ENABLE_BUNDLE */
129
130         return TRUE;
131 }
132
133 static void udpgate_startup_lsb_class_init (UdpgateStartupLsbClass *class)
134 {
135         UdpgateStartupClass *udpgate_startup_class = UDPGATE_STARTUP_CLASS(class);
136
137         udpgate_startup_class->init = udpgate_startup_lsb_init;
138         udpgate_startup_class->query = udpgate_startup_lsb_query;
139         udpgate_startup_class->on = udpgate_startup_lsb_on;
140         udpgate_startup_class->off = udpgate_startup_lsb_off;
141 }
142
143 GType udpgate_startup_lsb_get_type(void)
144 {
145   static GType udpgate_startup_lsb_type=0;
146
147   if (!udpgate_startup_lsb_type) {
148                 static const GTypeInfo udpgate_startup_lsb_info={
149                         sizeof(UdpgateStartupLsbClass),
150                         NULL,           /* base_init */
151                         NULL,           /* base_finalize */
152                         (GClassInitFunc)udpgate_startup_lsb_class_init,
153                         NULL,           /* class_finalize */
154                         NULL,           /* class_data */
155                         sizeof(UdpgateStartupLsb),
156                         0,              /* n_preallocs */
157                         NULL,           /* instance_init */
158                         NULL,           /* value_table */
159       };
160
161                 udpgate_startup_lsb_type=g_type_register_static(UDPGATE_TYPE_STARTUP,"UdpgateStartupLsb",
162                                  &udpgate_startup_lsb_info,0);
163     }
164
165   return udpgate_startup_lsb_type;
166 }