source: ldm/trunk/fuentes/src/ldmutils.c @ 855

Last change on this file since 855 was 855, checked in by mabarracus, 5 years ago
  • Updated sources to 2.2.18
  • Ported code from patches to apply in 2.2.18
File size: 5.7 KB
Line 
1#include <arpa/inet.h>
2#include <errno.h>
3#include <glib.h>
4#include <glib-object.h>
5#include <libintl.h>
6#include <net/if.h>
7#include <signal.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <sys/ioctl.h>
12#include <syslog.h>
13#include <sys/wait.h>
14
15#include "ldm.h"
16#include "ldmutils.h"
17#include "logging.h"
18
19/*
20 * rc_files
21 *
22 * Run startup commands.
23 */
24void
25rc_files(char *action)
26{
27    GPid rcpid;
28    gchar *command;
29
30    command =
31        g_strjoin(" ", "/bin/sh", RC_DIR "/ldm-script", action, NULL);
32
33    rcpid = ldm_spawn(command, NULL, NULL, NULL);
34
35    ldm_wait(rcpid);
36    g_free(command);
37}
38
39/*
40 * get_ipaddr
41 *  Get ip address of host
42 */
43void
44get_ipaddr()
45{
46    int numreqs = 10;
47    struct ifconf ifc;
48    struct ifreq *ifr;          /* netdevice(7) */
49    struct ifreq info;
50    struct sockaddr_in *sa;
51
52    int skfd, n;
53
54    skfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
55    if (skfd < 0)
56        die("ldm", "socket");
57
58    /*
59     * Get a list of all the interfaces.
60     */
61
62    ifc.ifc_buf = NULL;
63
64    while (TRUE) {
65        ifc.ifc_len = sizeof(struct ifreq) * numreqs;
66        ifc.ifc_buf = (char *) realloc(ifc.ifc_buf, ifc.ifc_len);
67        if (ifc.ifc_buf == NULL)
68            die("ldm", "out of memory");
69
70        if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
71            log_entry("ldm", 4, "SIOCGIFCONF");
72            goto out;
73        }
74
75        if (ifc.ifc_len == (int) sizeof(struct ifreq) * numreqs) {
76            /* assume it overflowed and try again */
77            numreqs += 10;
78            continue;
79        }
80
81        break;
82    }
83
84    /*
85     * Look for the first interface that has an IP address, is not
86     * loopback, and is up.
87     */
88
89    ifr = ifc.ifc_req;
90    for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {
91        if (ifr->ifr_addr.sa_family != AF_INET)
92            continue;
93
94        strcpy(info.ifr_name, ifr->ifr_name);
95        if (ioctl(skfd, SIOCGIFFLAGS, &info) < 0) {
96            log_entry("ldm", 4, "SIOCGIFFLAGS");
97            goto out;
98        }
99
100        if (!(info.ifr_flags & IFF_LOOPBACK) && (info.ifr_flags & IFF_UP)) {
101            sa = (struct sockaddr_in *) &ifr->ifr_addr;
102            ldm.ipaddr = g_strdup(inet_ntoa(sa->sin_addr));
103            break;
104        }
105
106        ifr++;
107    }
108
109  out:
110    if (ifc.ifc_buf)
111        free(ifc.ifc_buf);
112
113    if (n == ifc.ifc_len)
114        die("ldm", "no configured interface found");
115}
116
117/*
118 * ldm_spawn:
119 *
120 * Execute commands.  Prints nice error message if failure.
121 */
122GPid
123ldm_spawn(gchar * command, gint * rfd, gint * wfd,
124          GSpawnChildSetupFunc setup)
125{
126    GPid pid;
127    GError *error = NULL;
128    GSpawnFlags flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD;
129    gint argc;
130    gchar **argv = NULL;
131
132    g_shell_parse_argv(command, &argc, &argv, NULL);
133
134    if (!wfd)
135        flags |= G_SPAWN_STDOUT_TO_DEV_NULL;
136
137    g_spawn_async_with_pipes(NULL,               /* Working directory: inherit */
138                             argv,               /* Arguments, null term */
139                             NULL,               /* Environment, inherit from parent */
140                             flags,              /* Flags, set above */
141                             setup,              /* Child setup function: passed to us */
142                             NULL,               /* No user data */
143                             &pid,               /* child pid */
144                             wfd,                /* Pointer to in file descriptor */
145                             rfd,                /* Pointer to out file descriptor */
146                             NULL,               /* No stderr */
147                             &error);            /* GError handler */
148
149    g_strfreev(argv);
150
151    if (error) {
152        log_entry("ldm", 3, "ldm_spawn failed to execute: %s",
153                  error->message);
154    } else {
155        log_entry("ldm", 7, "ldm_spawn: pid = %d", pid);
156    }
157
158    return pid;
159}
160
161/*
162 * handle_sigchld
163 *
164 * Handle sigchld's for ldm processes.  Empty function,
165 * since we wait for things to happen in order via
166 * ldm_wait
167 */
168void
169handle_sigchld(int signo)
170{
171    /* do nothing */
172    child_exited = TRUE;
173}
174
175/*
176 * ldm_wait
177 *
178 * wait for child process
179 */
180void
181ldm_wait(GPid pid)
182{
183    siginfo_t info;
184    log_entry("ldm", 7, "waiting for process: %d", pid);
185    do {
186        int res;
187        res = waitid(P_PID, pid, &info, WEXITED | WSTOPPED);
188        if (res == -1) {
189            int temp;
190            temp = errno;
191            log_entry("ldm", 4, "waitid returned an error: %s",
192                      strerror(errno));
193            if (temp == ECHILD) {
194                break;
195            }
196        } else {
197            if (info.si_pid == pid) {
198                /*
199                 * The process we were waiting for exited,
200                 * so break out of the loop.
201                 */
202                break;
203            } else {
204                log_entry("ldm", 4,
205                          "unexpected terminated process, pid: %d",
206                          info.si_pid);
207                unexpected_child = TRUE;
208            }
209        }
210    } while (TRUE);
211
212    if (info.si_code == CLD_EXITED) {
213        log_entry("ldm", 7, "process %d exited with status %d",
214                  info.si_pid, WEXITSTATUS(info.si_status));
215    } else if (info.si_code == CLD_KILLED) {
216        log_entry("ldm", 7, "process %d killed by signal %d", info.si_pid,
217                  info.si_status);
218    }
219}
220
221/*
222 * close_wm
223 *  Close window manager by SIGKILL
224 */
225void
226close_wm()
227{
228    if (!(ldm.wmpid)) {
229        return;
230    }
231
232    log_entry("ldm", 7, "closing window manager");
233    if (kill(ldm.wmpid, SIGKILL) < 0) {
234        log_entry("ldm", 3, "sending SIGKILL to window manager failed");
235    }
236    ldm_wait(ldm.wmpid);
237    ldm.wmpid = 0;
238}
Note: See TracBrowser for help on using the repository browser.