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

Last change on this file since 516 was 516, checked in by mabarracus, 5 years ago

Copy trusty code

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