#include #include #include #include #include #include #include #include #include #include #include #include #include #include "ldm.h" #include "ldmutils.h" #include "logging.h" /* * rc_files * * Run startup commands. */ void rc_files(char *action) { GPid rcpid; gchar *command; command = g_strjoin(" ", "/bin/sh", RC_DIR "/ldm-script", action, NULL); rcpid = ldm_spawn(command, NULL, NULL, NULL); ldm_wait(rcpid); g_free(command); } /* * get_ipaddr * Get ip address of host */ void get_ipaddr() { int numreqs = 10; struct ifconf ifc; struct ifreq *ifr; /* netdevice(7) */ struct ifreq info; struct sockaddr_in *sa; int skfd, n; skfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (skfd < 0) die("ldm", "socket"); /* * Get a list of all the interfaces. */ ifc.ifc_buf = NULL; while (TRUE) { ifc.ifc_len = sizeof(struct ifreq) * numreqs; ifc.ifc_buf = (char *) realloc(ifc.ifc_buf, ifc.ifc_len); if (ifc.ifc_buf == NULL) die("ldm", "out of memory"); if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) { log_entry("ldm", 4, "SIOCGIFCONF"); goto out; } if (ifc.ifc_len == (int) sizeof(struct ifreq) * numreqs) { /* assume it overflowed and try again */ numreqs += 10; continue; } break; } /* * Look for the first interface that has an IP address, is not * loopback, and is up. */ ifr = ifc.ifc_req; for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) { if (ifr->ifr_addr.sa_family != AF_INET) continue; strcpy(info.ifr_name, ifr->ifr_name); if (ioctl(skfd, SIOCGIFFLAGS, &info) < 0) { log_entry("ldm", 4, "SIOCGIFFLAGS"); goto out; } if (!(info.ifr_flags & IFF_LOOPBACK) && (info.ifr_flags & IFF_UP)) { sa = (struct sockaddr_in *) &ifr->ifr_addr; ldm.ipaddr = g_strdup(inet_ntoa(sa->sin_addr)); break; } ifr++; } out: if (ifc.ifc_buf) free(ifc.ifc_buf); if (n == ifc.ifc_len) die("ldm", "no configured interface found"); } /* * ldm_spawn: * * Execute commands. Prints nice error message if failure. */ GPid ldm_spawn(gchar * command, gint * rfd, gint * wfd, GSpawnChildSetupFunc setup) { GPid pid; GError *error = NULL; GSpawnFlags flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD; gint argc; gchar **argv = NULL; g_shell_parse_argv(command, &argc, &argv, NULL); if (!wfd) flags |= G_SPAWN_STDOUT_TO_DEV_NULL; g_spawn_async_with_pipes(NULL, /* Working directory: inherit */ argv, /* Arguments, null term */ NULL, /* Environment, inherit from parent */ flags, /* Flags, set above */ setup, /* Child setup function: passed to us */ NULL, /* No user data */ &pid, /* child pid */ wfd, /* Pointer to in file descriptor */ rfd, /* Pointer to out file descriptor */ NULL, /* No stderr */ &error); /* GError handler */ g_strfreev(argv); if (error) { log_entry("ldm", 3, "ldm_spawn failed to execute: %s", error->message); } else { log_entry("ldm", 7, "ldm_spawn: pid = %d", pid); } return pid; } /* * handle_sigchld * * Handle sigchld's for ldm processes. Empty function, * since we wait for things to happen in order via * ldm_wait */ void handle_sigchld(int signo) { /* do nothing */ child_exited = TRUE; } /* * ldm_wait * * wait for child process */ void ldm_wait(GPid pid) { siginfo_t info; log_entry("ldm", 7, "waiting for process: %d", pid); do { int res; res = waitid(P_PID, pid, &info, WEXITED | WSTOPPED); if (res == -1) { int temp; temp = errno; log_entry("ldm", 4, "waitid returned an error: %s", strerror(errno)); if (temp == ECHILD) { break; } } else { if (info.si_pid == pid) { /* * The process we were waiting for exited, * so break out of the loop. */ break; } else { log_entry("ldm", 4, "unexpected terminated process, pid: %d", info.si_pid); unexpected_child = TRUE; } } } while (TRUE); if (info.si_code == CLD_EXITED) { log_entry("ldm", 7, "process %d exited with status %d", info.si_pid, WEXITSTATUS(info.si_status)); } else if (info.si_code == CLD_KILLED) { log_entry("ldm", 7, "process %d killed by signal %d", info.si_pid, info.si_status); } } /* * close_wm * Close window manager by SIGKILL */ void close_wm() { if (!(ldm.wmpid)) { return; } log_entry("ldm", 7, "closing window manager"); if (kill(ldm.wmpid, SIGKILL) < 0) { log_entry("ldm", 3, "sending SIGKILL to window manager failed"); } ldm_wait(ldm.wmpid); ldm.wmpid = 0; }