Advertisement
Guest User

Untitled

a guest
Jul 27th, 2017
455
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 64.04 KB | None | 0 0
  1. /*
  2. * Init A System-V Init Clone.
  3. *
  4. * Usage: /sbin/init
  5. * init [0123456SsQqAaBbCc]
  6. * telinit [0123456SsQqAaBbCc]
  7. *
  8. * Version: @(#)init.c 2.86 30-Jul-2004 miquels@cistron.nl
  9. */
  10. #define VERSION "2.88"
  11. #define DATE "26-Mar-2010"
  12. /*
  13. * This file is part of the sysvinit suite,
  14. * Copyright (C) 1991-2004 Miquel van Smoorenburg.
  15. *
  16. * This program is free software; you can redistribute it and/or modify
  17. * it under the terms of the GNU General Public License as published by
  18. * the Free Software Foundation; either version 2 of the License, or
  19. * (at your option) any later version.
  20. *
  21. * This program is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU General Public License
  27. * along with this program; if not, write to the Free Software
  28. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  29. *
  30. */
  31.  
  32. #include <sys/types.h>
  33. #include <sys/stat.h>
  34. #include <sys/ioctl.h>
  35. #include <sys/wait.h>
  36. #ifdef __linux__
  37. #include <sys/kd.h>
  38. #endif
  39. #include <sys/resource.h>
  40. #include <stdlib.h>
  41. #include <unistd.h>
  42. #include <errno.h>
  43. #include <stdio.h>
  44. #include <time.h>
  45. #include <fcntl.h>
  46. #include <string.h>
  47. #include <signal.h>
  48. #include <termios.h>
  49. #include <utmp.h>
  50. #include <ctype.h>
  51. #include <stdarg.h>
  52. #include <sys/syslog.h>
  53. #include <sys/time.h>
  54.  
  55. #ifdef WITH_SELINUX
  56. # include <selinux/selinux.h>
  57. # include <sys/mount.h>
  58. # ifndef MNT_DETACH /* present in glibc 2.10, missing in 2.7 */
  59. # define MNT_DETACH 2
  60. # endif
  61. #endif
  62.  
  63. #ifdef __i386__
  64. # ifdef __GLIBC__
  65. /* GNU libc 2.x */
  66. # define STACK_DEBUG 1
  67. # if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
  68. /* Only glibc 2.0 needs this */
  69. # include <sigcontext.h>
  70. # elif ( __GLIBC__ > 2) && ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
  71. # include <bits/sigcontext.h>
  72. # endif
  73. # endif
  74. #endif
  75.  
  76. #include "init.h"
  77. #include "initreq.h"
  78. #include "paths.h"
  79. #include "reboot.h"
  80. #include "set.h"
  81.  
  82. #ifndef SIGPWR
  83. # define SIGPWR SIGUSR2
  84. #endif
  85.  
  86. #ifndef CBAUD
  87. # define CBAUD 0
  88. #endif
  89. #ifndef CBAUDEX
  90. # define CBAUDEX 0
  91. #endif
  92.  
  93. /* Set a signal handler. */
  94. #define SETSIG(sa, sig, fun, flags) \
  95. do { \
  96. sa.sa_handler = fun; \
  97. sa.sa_flags = flags; \
  98. sigemptyset(&sa.sa_mask); \
  99. sigaction(sig, &sa, NULL); \
  100. } while(0)
  101.  
  102. /* Version information */
  103. char *Version = "@(#) init " VERSION " " DATE " miquels@cistron.nl";
  104. char *bootmsg = "version " VERSION " %s";
  105. #define E_VERSION "INIT_VERSION=sysvinit-" VERSION
  106.  
  107. CHILD *family = NULL; /* The linked list of all entries */
  108. CHILD *newFamily = NULL; /* The list after inittab re-read */
  109.  
  110. CHILD ch_emerg = { /* Emergency shell */
  111. WAITING, 0, 0, 0, 0,
  112. "~~",
  113. "S",
  114. 3,
  115. "/sbin/sulogin",
  116. NULL,
  117. NULL
  118. };
  119.  
  120. char runlevel = 'S'; /* The current run level */
  121. char thislevel = 'S'; /* The current runlevel */
  122. char prevlevel = 'N'; /* Previous runlevel */
  123. int dfl_level = 0; /* Default runlevel */
  124. sig_atomic_t got_cont = 0; /* Set if we received the SIGCONT signal */
  125. sig_atomic_t got_signals; /* Set if we received a signal. */
  126. int emerg_shell = 0; /* Start emergency shell? */
  127. int wrote_wtmp_reboot = 1; /* Set when we wrote the reboot record */
  128. int wrote_utmp_reboot = 1; /* Set when we wrote the reboot record */
  129. int wrote_wtmp_rlevel = 1; /* Set when we wrote the runlevel record */
  130. int wrote_utmp_rlevel = 1; /* Set when we wrote the runlevel record */
  131. int sltime = 5; /* Sleep time between TERM and KILL */
  132. char *argv0; /* First arguments; show up in ps listing */
  133. int maxproclen; /* Maximal length of argv[0] with \0 */
  134. struct utmp utproto; /* Only used for sizeof(utproto.ut_id) */
  135. char *console_dev; /* Console device. */
  136. int pipe_fd = -1; /* /dev/initctl */
  137. int did_boot = 0; /* Did we already do BOOT* stuff? */
  138. int main(int, char **);
  139.  
  140. /* Used by re-exec part */
  141. int reload = 0; /* Should we do initialization stuff? */
  142. char *myname="/sbin/init"; /* What should we exec */
  143. int oops_error; /* Used by some of the re-exec code. */
  144. const char *Signature = "12567362"; /* Signature for re-exec fd */
  145.  
  146. /* Macro to see if this is a special action */
  147. #define ISPOWER(i) ((i) == POWERWAIT || (i) == POWERFAIL || \
  148. (i) == POWEROKWAIT || (i) == POWERFAILNOW || \
  149. (i) == CTRLALTDEL)
  150.  
  151. /* ascii values for the `action' field. */
  152. struct actions {
  153. char *name;
  154. int act;
  155. } actions[] = {
  156. { "respawn", RESPAWN },
  157. { "wait", WAIT },
  158. { "once", ONCE },
  159. { "boot", BOOT },
  160. { "bootwait", BOOTWAIT },
  161. { "powerfail", POWERFAIL },
  162. { "powerfailnow",POWERFAILNOW },
  163. { "powerwait", POWERWAIT },
  164. { "powerokwait", POWEROKWAIT },
  165. { "ctrlaltdel", CTRLALTDEL },
  166. { "off", OFF },
  167. { "ondemand", ONDEMAND },
  168. { "initdefault", INITDEFAULT },
  169. { "sysinit", SYSINIT },
  170. { "kbrequest", KBREQUEST },
  171. { NULL, 0 },
  172. };
  173.  
  174. /*
  175. * State parser token table (see receive_state)
  176. */
  177. struct {
  178. char name[4];
  179. int cmd;
  180. } cmds[] = {
  181. { "VER", C_VER },
  182. { "END", C_END },
  183. { "REC", C_REC },
  184. { "EOR", C_EOR },
  185. { "LEV", C_LEV },
  186. { "FL ", C_FLAG },
  187. { "AC ", C_ACTION },
  188. { "CMD", C_PROCESS },
  189. { "PID", C_PID },
  190. { "EXS", C_EXS },
  191. { "-RL", D_RUNLEVEL },
  192. { "-TL", D_THISLEVEL },
  193. { "-PL", D_PREVLEVEL },
  194. { "-SI", D_GOTSIGN },
  195. { "-WR", D_WROTE_WTMP_REBOOT},
  196. { "-WU", D_WROTE_UTMP_REBOOT},
  197. { "-ST", D_SLTIME },
  198. { "-DB", D_DIDBOOT },
  199. { "-LW", D_WROTE_WTMP_RLEVEL},
  200. { "-LU", D_WROTE_UTMP_RLEVEL},
  201. { "", 0 }
  202. };
  203. struct {
  204. char *name;
  205. int mask;
  206. } flags[]={
  207. {"RU",RUNNING},
  208. {"DE",DEMAND},
  209. {"XD",XECUTED},
  210. {"WT",WAITING},
  211. {NULL,0}
  212. };
  213.  
  214. #define NR_EXTRA_ENV 16
  215. char *extra_env[NR_EXTRA_ENV];
  216.  
  217.  
  218. /*
  219. * Sleep a number of seconds.
  220. *
  221. * This only works correctly because the linux select updates
  222. * the elapsed time in the struct timeval passed to select!
  223. */
  224. static
  225. void do_sleep(int sec)
  226. {
  227. struct timeval tv;
  228.  
  229. tv.tv_sec = sec;
  230. tv.tv_usec = 0;
  231.  
  232. while(select(0, NULL, NULL, NULL, &tv) < 0 && errno == EINTR)
  233. ;
  234. }
  235.  
  236.  
  237. /*
  238. * Non-failing allocation routines (init cannot fail).
  239. */
  240. static
  241. void *imalloc(size_t size)
  242. {
  243. void *m;
  244.  
  245. while ((m = malloc(size)) == NULL) {
  246. initlog(L_VB, "out of memory");
  247. do_sleep(5);
  248. }
  249. memset(m, 0, size);
  250. return m;
  251. }
  252.  
  253. static
  254. char *istrdup(char *s)
  255. {
  256. char *m;
  257. int l;
  258.  
  259. l = strlen(s) + 1;
  260. m = imalloc(l);
  261. memcpy(m, s, l);
  262. return m;
  263. }
  264.  
  265.  
  266. /*
  267. * Send the state info of the previous running init to
  268. * the new one, in a version-independant way.
  269. */
  270. static
  271. void send_state(int fd)
  272. {
  273. FILE *fp;
  274. CHILD *p;
  275. int i,val;
  276.  
  277. fp = fdopen(fd,"w");
  278.  
  279. fprintf(fp, "VER%s\n", Version);
  280. fprintf(fp, "-RL%c\n", runlevel);
  281. fprintf(fp, "-TL%c\n", thislevel);
  282. fprintf(fp, "-PL%c\n", prevlevel);
  283. fprintf(fp, "-SI%u\n", got_signals);
  284. fprintf(fp, "-WR%d\n", wrote_wtmp_reboot);
  285. fprintf(fp, "-WU%d\n", wrote_utmp_reboot);
  286. fprintf(fp, "-ST%d\n", sltime);
  287. fprintf(fp, "-DB%d\n", did_boot);
  288.  
  289. for (p = family; p; p = p->next) {
  290. fprintf(fp, "REC%s\n", p->id);
  291. fprintf(fp, "LEV%s\n", p->rlevel);
  292. for (i = 0, val = p->flags; flags[i].mask; i++)
  293. if (val & flags[i].mask) {
  294. val &= ~flags[i].mask;
  295. fprintf(fp, "FL %s\n",flags[i].name);
  296. }
  297. fprintf(fp, "PID%d\n",p->pid);
  298. fprintf(fp, "EXS%u\n",p->exstat);
  299. for(i = 0; actions[i].act; i++)
  300. if (actions[i].act == p->action) {
  301. fprintf(fp, "AC %s\n", actions[i].name);
  302. break;
  303. }
  304. fprintf(fp, "CMD%s\n", p->process);
  305. fprintf(fp, "EOR\n");
  306. }
  307. fprintf(fp, "END\n");
  308. fclose(fp);
  309. }
  310.  
  311. /*
  312. * Read a string from a file descriptor.
  313. * FIXME: why not use fgets() ?
  314. */
  315. static int get_string(char *p, int size, FILE *f)
  316. {
  317. int c;
  318.  
  319. while ((c = getc(f)) != EOF && c != '\n') {
  320. if (--size > 0)
  321. *p++ = c;
  322. }
  323. *p = '\0';
  324. return (c != EOF) && (size > 0);
  325. }
  326.  
  327. /*
  328. * Read trailing data from the state pipe until we see a newline.
  329. */
  330. static int get_void(FILE *f)
  331. {
  332. int c;
  333.  
  334. while ((c = getc(f)) != EOF && c != '\n')
  335. ;
  336.  
  337. return (c != EOF);
  338. }
  339.  
  340. /*
  341. * Read the next "command" from the state pipe.
  342. */
  343. static int get_cmd(FILE *f)
  344. {
  345. char cmd[4] = " ";
  346. int i;
  347.  
  348. if (fread(cmd, 1, sizeof(cmd) - 1, f) != sizeof(cmd) - 1)
  349. return C_EOF;
  350.  
  351. for(i = 0; cmds[i].cmd && strcmp(cmds[i].name, cmd) != 0; i++)
  352. ;
  353. return cmds[i].cmd;
  354. }
  355.  
  356. /*
  357. * Read a CHILD * from the state pipe.
  358. */
  359. static CHILD *get_record(FILE *f)
  360. {
  361. int cmd;
  362. char s[32];
  363. int i;
  364. CHILD *p;
  365.  
  366. do {
  367. switch (cmd = get_cmd(f)) {
  368. case C_END:
  369. get_void(f);
  370. return NULL;
  371. case 0:
  372. get_void(f);
  373. break;
  374. case C_REC:
  375. break;
  376. case D_RUNLEVEL:
  377. fscanf(f, "%c\n", &runlevel);
  378. break;
  379. case D_THISLEVEL:
  380. fscanf(f, "%c\n", &thislevel);
  381. break;
  382. case D_PREVLEVEL:
  383. fscanf(f, "%c\n", &prevlevel);
  384. break;
  385. case D_GOTSIGN:
  386. fscanf(f, "%u\n", &got_signals);
  387. break;
  388. case D_WROTE_WTMP_REBOOT:
  389. fscanf(f, "%d\n", &wrote_wtmp_reboot);
  390. break;
  391. case D_WROTE_UTMP_REBOOT:
  392. fscanf(f, "%d\n", &wrote_utmp_reboot);
  393. break;
  394. case D_SLTIME:
  395. fscanf(f, "%d\n", &sltime);
  396. break;
  397. case D_DIDBOOT:
  398. fscanf(f, "%d\n", &did_boot);
  399. break;
  400. case D_WROTE_WTMP_RLEVEL:
  401. fscanf(f, "%d\n", &wrote_wtmp_rlevel);
  402. break;
  403. case D_WROTE_UTMP_RLEVEL:
  404. fscanf(f, "%d\n", &wrote_utmp_rlevel);
  405. break;
  406. default:
  407. if (cmd > 0 || cmd == C_EOF) {
  408. oops_error = -1;
  409. return NULL;
  410. }
  411. }
  412. } while (cmd != C_REC);
  413.  
  414. p = imalloc(sizeof(CHILD));
  415. get_string(p->id, sizeof(p->id), f);
  416.  
  417. do switch(cmd = get_cmd(f)) {
  418. case 0:
  419. case C_EOR:
  420. get_void(f);
  421. break;
  422. case C_PID:
  423. fscanf(f, "%d\n", &(p->pid));
  424. break;
  425. case C_EXS:
  426. fscanf(f, "%u\n", &(p->exstat));
  427. break;
  428. case C_LEV:
  429. get_string(p->rlevel, sizeof(p->rlevel), f);
  430. break;
  431. case C_PROCESS:
  432. get_string(p->process, sizeof(p->process), f);
  433. break;
  434. case C_FLAG:
  435. get_string(s, sizeof(s), f);
  436. for(i = 0; flags[i].name; i++) {
  437. if (strcmp(flags[i].name,s) == 0)
  438. break;
  439. }
  440. p->flags |= flags[i].mask;
  441. break;
  442. case C_ACTION:
  443. get_string(s, sizeof(s), f);
  444. for(i = 0; actions[i].name; i++) {
  445. if (strcmp(actions[i].name, s) == 0)
  446. break;
  447. }
  448. p->action = actions[i].act ? actions[i].act : OFF;
  449. break;
  450. default:
  451. free(p);
  452. oops_error = -1;
  453. return NULL;
  454. } while( cmd != C_EOR);
  455.  
  456. return p;
  457. }
  458.  
  459. /*
  460. * Read the complete state info from the state pipe.
  461. * Returns 0 on success
  462. */
  463. static
  464. int receive_state(int fd)
  465. {
  466. FILE *f;
  467. char old_version[256];
  468. CHILD **pp;
  469.  
  470. f = fdopen(fd, "r");
  471.  
  472. if (get_cmd(f) != C_VER)
  473. return -1;
  474. get_string(old_version, sizeof(old_version), f);
  475. oops_error = 0;
  476. for (pp = &family; (*pp = get_record(f)) != NULL; pp = &((*pp)->next))
  477. ;
  478. fclose(f);
  479. return oops_error;
  480. }
  481.  
  482. /*
  483. * Set the process title.
  484. */
  485. #ifdef __GNUC__
  486. __attribute__ ((format (printf, 1, 2)))
  487. #endif
  488. static int setproctitle(char *fmt, ...)
  489. {
  490. va_list ap;
  491. int len;
  492. char buf[256];
  493.  
  494. buf[0] = 0;
  495.  
  496. va_start(ap, fmt);
  497. len = vsnprintf(buf, sizeof(buf), fmt, ap);
  498. va_end(ap);
  499.  
  500. if (maxproclen > 1) {
  501. memset(argv0, 0, maxproclen);
  502. strncpy(argv0, buf, maxproclen - 1);
  503. }
  504.  
  505. return len;
  506. }
  507.  
  508. /*
  509. * Set console_dev to a working console.
  510. */
  511. static
  512. void console_init(void)
  513. {
  514. int fd;
  515. int tried_devcons = 0;
  516. int tried_vtmaster = 0;
  517. char *s;
  518.  
  519. if ((s = getenv("CONSOLE")) != NULL)
  520. console_dev = s;
  521. else {
  522. console_dev = CONSOLE;
  523. tried_devcons++;
  524. }
  525.  
  526. while ((fd = open(console_dev, O_RDONLY|O_NONBLOCK)) < 0) {
  527. if (!tried_devcons) {
  528. tried_devcons++;
  529. console_dev = CONSOLE;
  530. continue;
  531. }
  532. if (!tried_vtmaster) {
  533. tried_vtmaster++;
  534. console_dev = VT_MASTER;
  535. continue;
  536. }
  537. break;
  538. }
  539. if (fd < 0)
  540. console_dev = "/dev/null";
  541. else
  542. close(fd);
  543. }
  544.  
  545.  
  546. /*
  547. * Open the console with retries.
  548. */
  549. static
  550. int console_open(int mode)
  551. {
  552. int f, fd = -1;
  553. int m;
  554.  
  555. /*
  556. * Open device in nonblocking mode.
  557. */
  558. m = mode | O_NONBLOCK;
  559.  
  560. /*
  561. * Retry the open five times.
  562. */
  563. for(f = 0; f < 5; f++) {
  564. if ((fd = open(console_dev, m)) >= 0) break;
  565. usleep(10000);
  566. }
  567.  
  568. if (fd < 0) return fd;
  569.  
  570. /*
  571. * Set original flags.
  572. */
  573. if (m != mode)
  574. fcntl(fd, F_SETFL, mode);
  575. return fd;
  576. }
  577.  
  578. /*
  579. * We got a signal (HUP PWR WINCH ALRM INT)
  580. */
  581. static
  582. void signal_handler(int sig)
  583. {
  584. ADDSET(got_signals, sig);
  585. }
  586.  
  587. /*
  588. * SIGCHLD: one of our children has died.
  589. */
  590. static
  591. # ifdef __GNUC__
  592. void chld_handler(int sig __attribute__((unused)))
  593. # else
  594. void chld_handler(int sig)
  595. # endif
  596. {
  597. CHILD *ch;
  598. int pid, st;
  599. int saved_errno = errno;
  600.  
  601. /*
  602. * Find out which process(es) this was (were)
  603. */
  604. while((pid = waitpid(-1, &st, WNOHANG)) != 0) {
  605. if (errno == ECHILD) break;
  606. for( ch = family; ch; ch = ch->next )
  607. if ( ch->pid == pid && (ch->flags & RUNNING) ) {
  608. INITDBG(L_VB,
  609. "chld_handler: marked %d as zombie",
  610. ch->pid);
  611. ADDSET(got_signals, SIGCHLD);
  612. ch->exstat = st;
  613. ch->flags |= ZOMBIE;
  614. if (ch->new) {
  615. ch->new->exstat = st;
  616. ch->new->flags |= ZOMBIE;
  617. }
  618. break;
  619. }
  620. if (ch == NULL) {
  621. INITDBG(L_VB, "chld_handler: unknown child %d exited.",
  622. pid);
  623. }
  624. }
  625. errno = saved_errno;
  626. }
  627.  
  628. /*
  629. * Linux ignores all signals sent to init when the
  630. * SIG_DFL handler is installed. Therefore we must catch SIGTSTP
  631. * and SIGCONT, or else they won't work....
  632. *
  633. * The SIGCONT handler
  634. */
  635. static
  636. # ifdef __GNUC__
  637. void cont_handler(int sig __attribute__((unused)))
  638. # else
  639. void cont_handler(int sig)
  640. # endif
  641. {
  642. got_cont = 1;
  643. }
  644.  
  645. /*
  646. * Fork and dump core in /.
  647. */
  648. static
  649. void coredump(void)
  650. {
  651. static int dumped = 0;
  652. struct rlimit rlim;
  653. sigset_t mask;
  654.  
  655. if (dumped) return;
  656. dumped = 1;
  657.  
  658. if (fork() != 0) return;
  659.  
  660. sigfillset(&mask);
  661. sigprocmask(SIG_SETMASK, &mask, NULL);
  662.  
  663. rlim.rlim_cur = RLIM_INFINITY;
  664. rlim.rlim_max = RLIM_INFINITY;
  665. setrlimit(RLIMIT_CORE, &rlim);
  666. chdir("/");
  667.  
  668. signal(SIGSEGV, SIG_DFL);
  669. raise(SIGSEGV);
  670. sigdelset(&mask, SIGSEGV);
  671. sigprocmask(SIG_SETMASK, &mask, NULL);
  672.  
  673. do_sleep(5);
  674. exit(0);
  675. }
  676.  
  677. /*
  678. * OOPS: segmentation violation!
  679. * If we have the info, print where it occured.
  680. * Then sleep 30 seconds and try to continue.
  681. */
  682. static
  683. #if defined(STACK_DEBUG) && defined(__linux__)
  684. # ifdef __GNUC__
  685. void segv_handler(int sig __attribute__((unused)), struct sigcontext ctx)
  686. # else
  687. void segv_handler(int sig, struct sigcontext ctx)
  688. # endif
  689. {
  690. char *p = "";
  691. int saved_errno = errno;
  692.  
  693. if ((void *)ctx.eip >= (void *)do_sleep &&
  694. (void *)ctx.eip < (void *)main)
  695. p = " (code)";
  696. initlog(L_VB, "PANIC: segmentation violation at %p%s! "
  697. "sleeping for 30 seconds.", (void *)ctx.eip, p);
  698. coredump();
  699. do_sleep(30);
  700. errno = saved_errno;
  701. }
  702. #else
  703. # ifdef __GNUC__
  704. void segv_handler(int sig __attribute__((unused)))
  705. # else
  706. void segv_handler(int sig)
  707. # endif
  708. {
  709. int saved_errno = errno;
  710.  
  711. initlog(L_VB,
  712. "PANIC: segmentation violation! sleeping for 30 seconds.");
  713. coredump();
  714. do_sleep(30);
  715. errno = saved_errno;
  716. }
  717. #endif
  718.  
  719. /*
  720. * The SIGSTOP & SIGTSTP handler
  721. */
  722. static
  723. # ifdef __GNUC__
  724. void stop_handler(int sig __attribute__((unused)))
  725. # else
  726. void stop_handler(int sig)
  727. # endif
  728. {
  729. int saved_errno = errno;
  730.  
  731. got_cont = 0;
  732. while(!got_cont) pause();
  733. got_cont = 0;
  734. errno = saved_errno;
  735. }
  736.  
  737. /*
  738. * Set terminal settings to reasonable defaults
  739. */
  740. static
  741. void console_stty(void)
  742. {
  743. struct termios tty;
  744. int fd;
  745.  
  746. if ((fd = console_open(O_RDWR|O_NOCTTY)) < 0) {
  747. initlog(L_VB, "can't open %s", console_dev);
  748. return;
  749. }
  750.  
  751. #ifdef __FreeBSD_kernel__
  752. /*
  753. * The kernel of FreeBSD expects userland to set TERM. Usually, we want
  754. * "cons25". Later, gettys might disagree on this (i.e. we're not using
  755. * syscons) but some boot scripts, like /etc/init.d/xserver-xorg, still
  756. * need a non-dumb terminal.
  757. */
  758. putenv ("TERM=cons25");
  759. #endif
  760.  
  761. (void) tcgetattr(fd, &tty);
  762.  
  763. tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
  764. tty.c_cflag |= HUPCL|CLOCAL|CREAD;
  765.  
  766. tty.c_cc[VINTR] = CINTR;
  767. tty.c_cc[VQUIT] = CQUIT;
  768. tty.c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */
  769. tty.c_cc[VKILL] = CKILL;
  770. tty.c_cc[VEOF] = CEOF;
  771. tty.c_cc[VTIME] = 0;
  772. tty.c_cc[VMIN] = 1;
  773. tty.c_cc[VSWTC] = _POSIX_VDISABLE;
  774. tty.c_cc[VSTART] = CSTART;
  775. tty.c_cc[VSTOP] = CSTOP;
  776. tty.c_cc[VSUSP] = CSUSP;
  777. tty.c_cc[VEOL] = _POSIX_VDISABLE;
  778. tty.c_cc[VREPRINT] = CREPRINT;
  779. tty.c_cc[VDISCARD] = CDISCARD;
  780. tty.c_cc[VWERASE] = CWERASE;
  781. tty.c_cc[VLNEXT] = CLNEXT;
  782. tty.c_cc[VEOL2] = _POSIX_VDISABLE;
  783.  
  784. /*
  785. * Set pre and post processing
  786. */
  787. tty.c_iflag = IGNPAR|ICRNL|IXON|IXANY;
  788. #ifdef IUTF8 /* Not defined on FreeBSD */
  789. tty.c_iflag |= IUTF8;
  790. #endif /* IUTF8 */
  791. tty.c_oflag = OPOST|ONLCR;
  792. tty.c_lflag = ISIG|ICANON|ECHO|ECHOCTL|ECHOPRT|ECHOKE;
  793.  
  794. #if defined(SANE_TIO) && (SANE_TIO == 1)
  795. /*
  796. * Disable flow control (-ixon), ignore break (ignbrk),
  797. * and make nl/cr more usable (sane).
  798. */
  799. tty.c_iflag |= IGNBRK;
  800. tty.c_iflag &= ~(BRKINT|INLCR|IGNCR|IXON);
  801. tty.c_oflag &= ~(OCRNL|ONLRET);
  802. #endif
  803. /*
  804. * Now set the terminal line.
  805. * We don't care about non-transmitted output data
  806. * and non-read input data.
  807. */
  808. (void) tcsetattr(fd, TCSANOW, &tty);
  809. (void) tcflush(fd, TCIOFLUSH);
  810. (void) close(fd);
  811. }
  812.  
  813. /*
  814. * Print to the system console
  815. */
  816. void print(char *s)
  817. {
  818. int fd;
  819.  
  820. if ((fd = console_open(O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) {
  821. write(fd, s, strlen(s));
  822. close(fd);
  823. }
  824. }
  825.  
  826. /*
  827. * Log something to a logfile and the console.
  828. */
  829. #ifdef __GNUC__
  830. __attribute__ ((format (printf, 2, 3)))
  831. #endif
  832. void initlog(int loglevel, char *s, ...)
  833. {
  834. va_list va_alist;
  835. char buf[256];
  836. sigset_t nmask, omask;
  837.  
  838. va_start(va_alist, s);
  839. vsnprintf(buf, sizeof(buf), s, va_alist);
  840. va_end(va_alist);
  841.  
  842. if (loglevel & L_SY) {
  843. /*
  844. * Re-establish connection with syslogd every time.
  845. * Block signals while talking to syslog.
  846. */
  847. sigfillset(&nmask);
  848. sigprocmask(SIG_BLOCK, &nmask, &omask);
  849. openlog("init", 0, LOG_DAEMON);
  850. syslog(LOG_INFO, "%s", buf);
  851. closelog();
  852. sigprocmask(SIG_SETMASK, &omask, NULL);
  853. }
  854.  
  855. /*
  856. * And log to the console.
  857. */
  858. if (loglevel & L_CO) {
  859. print("\rINIT: ");
  860. print(buf);
  861. print("\r\n");
  862. }
  863. }
  864.  
  865.  
  866. /*
  867. * Build a new environment for execve().
  868. */
  869. char **init_buildenv(int child)
  870. {
  871. char i_lvl[] = "RUNLEVEL=x";
  872. char i_prev[] = "PREVLEVEL=x";
  873. char i_cons[32];
  874. char i_shell[] = "SHELL=" SHELL;
  875. char **e;
  876. int n, i;
  877.  
  878. for (n = 0; environ[n]; n++)
  879. ;
  880. n += NR_EXTRA_ENV;
  881. if (child)
  882. n += 8;
  883. e = calloc(n, sizeof(char *));
  884.  
  885. for (n = 0; environ[n]; n++)
  886. e[n] = istrdup(environ[n]);
  887.  
  888. for (i = 0; i < NR_EXTRA_ENV; i++) {
  889. if (extra_env[i])
  890. e[n++] = istrdup(extra_env[i]);
  891. }
  892.  
  893. if (child) {
  894. snprintf(i_cons, sizeof(i_cons), "CONSOLE=%s", console_dev);
  895. i_lvl[9] = thislevel;
  896. i_prev[10] = prevlevel;
  897. e[n++] = istrdup(i_shell);
  898. e[n++] = istrdup(i_lvl);
  899. e[n++] = istrdup(i_prev);
  900. e[n++] = istrdup(i_cons);
  901. e[n++] = istrdup(E_VERSION);
  902. }
  903.  
  904. e[n++] = NULL;
  905.  
  906. return e;
  907. }
  908.  
  909.  
  910. void init_freeenv(char **e)
  911. {
  912. int n;
  913.  
  914. for (n = 0; e[n]; n++)
  915. free(e[n]);
  916. free(e);
  917. }
  918.  
  919.  
  920. /*
  921. * Fork and execute.
  922. *
  923. * This function is too long and indents too deep.
  924. *
  925. */
  926. static
  927. pid_t spawn(CHILD *ch, int *res)
  928. {
  929. char *args[16]; /* Argv array */
  930. char buf[136]; /* Line buffer */
  931. int f, st; /* Scratch variables */
  932. char *ptr; /* Ditto */
  933. time_t t; /* System time */
  934. int oldAlarm; /* Previous alarm value */
  935. char *proc = ch->process; /* Command line */
  936. pid_t pid, pgrp; /* child, console process group. */
  937. sigset_t nmask, omask; /* For blocking SIGCHLD */
  938. struct sigaction sa;
  939.  
  940. *res = -1;
  941. buf[sizeof(buf) - 1] = 0;
  942.  
  943. /* Skip '+' if it's there */
  944. if (proc[0] == '+') proc++;
  945.  
  946. ch->flags |= XECUTED;
  947.  
  948. if (ch->action == RESPAWN || ch->action == ONDEMAND) {
  949. /* Is the date stamp from less than 2 minutes ago? */
  950. time(&t);
  951. if (ch->tm + TESTTIME > t) {
  952. ch->count++;
  953. } else {
  954. ch->count = 0;
  955. ch->tm = t;
  956. }
  957.  
  958. /* Do we try to respawn too fast? */
  959. if (ch->count >= MAXSPAWN) {
  960.  
  961. initlog(L_VB,
  962. "Id \"%s\" respawning too fast: disabled for %d minutes",
  963. ch->id, SLEEPTIME / 60);
  964. ch->flags &= ~RUNNING;
  965. ch->flags |= FAILING;
  966.  
  967. /* Remember the time we stopped */
  968. ch->tm = t;
  969.  
  970. /* Try again in 5 minutes */
  971. oldAlarm = alarm(0);
  972. if (oldAlarm > SLEEPTIME || oldAlarm <= 0) oldAlarm = SLEEPTIME;
  973. alarm(oldAlarm);
  974. return(-1);
  975. }
  976. }
  977.  
  978. /* See if there is an "initscript" (except in single user mode). */
  979. if (access(INITSCRIPT, R_OK) == 0 && runlevel != 'S') {
  980. /* Build command line using "initscript" */
  981. args[1] = SHELL;
  982. args[2] = INITSCRIPT;
  983. args[3] = ch->id;
  984. args[4] = ch->rlevel;
  985. args[5] = "unknown";
  986. for(f = 0; actions[f].name; f++) {
  987. if (ch->action == actions[f].act) {
  988. args[5] = actions[f].name;
  989. break;
  990. }
  991. }
  992. args[6] = proc;
  993. args[7] = NULL;
  994. } else if (strpbrk(proc, "~`!$^&*()=|\\{}[];\"'<>?")) {
  995. /* See if we need to fire off a shell for this command */
  996. /* Give command line to shell */
  997. args[1] = SHELL;
  998. args[2] = "-c";
  999. strcpy(buf, "exec ");
  1000. strncat(buf, proc, sizeof(buf) - strlen(buf) - 1);
  1001. args[3] = buf;
  1002. args[4] = NULL;
  1003. } else {
  1004. /* Split up command line arguments */
  1005. buf[0] = 0;
  1006. strncat(buf, proc, sizeof(buf) - 1);
  1007. ptr = buf;
  1008. for(f = 1; f < 15; f++) {
  1009. /* Skip white space */
  1010. while(*ptr == ' ' || *ptr == '\t') ptr++;
  1011. args[f] = ptr;
  1012.  
  1013. /* May be trailing space.. */
  1014. if (*ptr == 0) break;
  1015.  
  1016. /* Skip this `word' */
  1017. while(*ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '#')
  1018. ptr++;
  1019.  
  1020. /* If end-of-line, break */
  1021. if (*ptr == '#' || *ptr == 0) {
  1022. f++;
  1023. *ptr = 0;
  1024. break;
  1025. }
  1026. /* End word with \0 and continue */
  1027. *ptr++ = 0;
  1028. }
  1029. args[f] = NULL;
  1030. }
  1031. args[0] = args[1];
  1032. while(1) {
  1033. /*
  1034. * Block sigchild while forking.
  1035. */
  1036. sigemptyset(&nmask);
  1037. sigaddset(&nmask, SIGCHLD);
  1038. sigprocmask(SIG_BLOCK, &nmask, &omask);
  1039.  
  1040. if ((pid = fork()) == 0) {
  1041.  
  1042. close(0);
  1043. close(1);
  1044. close(2);
  1045. if (pipe_fd >= 0) close(pipe_fd);
  1046.  
  1047. sigprocmask(SIG_SETMASK, &omask, NULL);
  1048.  
  1049. /*
  1050. * In sysinit, boot, bootwait or single user mode:
  1051. * for any wait-type subprocess we _force_ the console
  1052. * to be its controlling tty.
  1053. */
  1054. if (strchr("*#sS", runlevel) && ch->flags & WAITING) {
  1055. /*
  1056. * We fork once extra. This is so that we can
  1057. * wait and change the process group and session
  1058. * of the console after exit of the leader.
  1059. */
  1060. setsid();
  1061. if ((f = console_open(O_RDWR|O_NOCTTY)) >= 0) {
  1062. /* Take over controlling tty by force */
  1063. (void)ioctl(f, TIOCSCTTY, 1);
  1064. dup(f);
  1065. dup(f);
  1066. }
  1067.  
  1068. /*
  1069. * 4 Sep 2001, Andrea Arcangeli:
  1070. * Fix a race in spawn() that is used to deadlock init in a
  1071. * waitpid() loop: must set the childhandler as default before forking
  1072. * off the child or the chld_handler could run before the waitpid loop
  1073. * has a chance to find its zombie-child.
  1074. */
  1075. SETSIG(sa, SIGCHLD, SIG_DFL, SA_RESTART);
  1076. if ((pid = fork()) < 0) {
  1077. initlog(L_VB, "cannot fork: %s",
  1078. strerror(errno));
  1079. exit(1);
  1080. }
  1081. if (pid > 0) {
  1082. pid_t rc;
  1083. /*
  1084. * Ignore keyboard signals etc.
  1085. * Then wait for child to exit.
  1086. */
  1087. SETSIG(sa, SIGINT, SIG_IGN, SA_RESTART);
  1088. SETSIG(sa, SIGTSTP, SIG_IGN, SA_RESTART);
  1089. SETSIG(sa, SIGQUIT, SIG_IGN, SA_RESTART);
  1090.  
  1091. while ((rc = waitpid(pid, &st, 0)) != pid)
  1092. if (rc < 0 && errno == ECHILD)
  1093. break;
  1094.  
  1095. /*
  1096. * Small optimization. See if stealing
  1097. * controlling tty back is needed.
  1098. */
  1099. pgrp = tcgetpgrp(f);
  1100. if (pgrp != getpid())
  1101. exit(0);
  1102.  
  1103. /*
  1104. * Steal controlling tty away. We do
  1105. * this with a temporary process.
  1106. */
  1107. if ((pid = fork()) < 0) {
  1108. initlog(L_VB, "cannot fork: %s",
  1109. strerror(errno));
  1110. exit(1);
  1111. }
  1112. if (pid == 0) {
  1113. setsid();
  1114. (void)ioctl(f, TIOCSCTTY, 1);
  1115. exit(0);
  1116. }
  1117. while((rc = waitpid(pid, &st, 0)) != pid)
  1118. if (rc < 0 && errno == ECHILD)
  1119. break;
  1120. exit(0);
  1121. }
  1122.  
  1123. /* Set ioctl settings to default ones */
  1124. console_stty();
  1125.  
  1126. } else {
  1127. setsid();
  1128. if ((f = console_open(O_RDWR|O_NOCTTY)) < 0) {
  1129. initlog(L_VB, "open(%s): %s", console_dev,
  1130. strerror(errno));
  1131. f = open("/dev/null", O_RDWR);
  1132. }
  1133. dup(f);
  1134. dup(f);
  1135. }
  1136.  
  1137. /*
  1138. * Update utmp/wtmp file prior to starting
  1139. * any child. This MUST be done right here in
  1140. * the child process in order to prevent a race
  1141. * condition that occurs when the child
  1142. * process' time slice executes before the
  1143. * parent (can and does happen in a uniprocessor
  1144. * environment). If the child is a getty and
  1145. * the race condition happens, then init's utmp
  1146. * update will happen AFTER the getty runs
  1147. * and expects utmp to be updated already!
  1148. *
  1149. * Do NOT log if process field starts with '+'
  1150. * FIXME: that's for compatibility with *very*
  1151. * old getties - probably it can be taken out.
  1152. */
  1153. if (ch->process[0] != '+')
  1154. write_utmp_wtmp("", ch->id, getpid(), INIT_PROCESS, "");
  1155.  
  1156. /* Reset all the signals, set up environment */
  1157. for(f = 1; f < NSIG; f++) SETSIG(sa, f, SIG_DFL, SA_RESTART);
  1158. environ = init_buildenv(1);
  1159.  
  1160. /*
  1161. * Execute prog. In case of ENOEXEC try again
  1162. * as a shell script.
  1163. */
  1164. execvp(args[1], args + 1);
  1165. if (errno == ENOEXEC) {
  1166. args[1] = SHELL;
  1167. args[2] = "-c";
  1168. strcpy(buf, "exec ");
  1169. strncat(buf, proc, sizeof(buf) - strlen(buf) - 1);
  1170. args[3] = buf;
  1171. args[4] = NULL;
  1172. execvp(args[1], args + 1);
  1173. }
  1174. initlog(L_VB, "cannot execute \"%s\"", args[1]);
  1175.  
  1176. if (ch->process[0] != '+')
  1177. write_utmp_wtmp("", ch->id, getpid(), DEAD_PROCESS, NULL);
  1178. exit(1);
  1179. }
  1180. *res = pid;
  1181. sigprocmask(SIG_SETMASK, &omask, NULL);
  1182.  
  1183. INITDBG(L_VB, "Started id %s (pid %d)", ch->id, pid);
  1184.  
  1185. if (pid == -1) {
  1186. initlog(L_VB, "cannot fork, retry..");
  1187. do_sleep(5);
  1188. continue;
  1189. }
  1190. return(pid);
  1191. }
  1192. }
  1193.  
  1194. /*
  1195. * Start a child running!
  1196. */
  1197. static
  1198. void startup(CHILD *ch)
  1199. {
  1200. /*
  1201. * See if it's disabled
  1202. */
  1203. if (ch->flags & FAILING) return;
  1204.  
  1205. switch(ch->action) {
  1206.  
  1207. case SYSINIT:
  1208. case BOOTWAIT:
  1209. case WAIT:
  1210. case POWERWAIT:
  1211. case POWERFAILNOW:
  1212. case POWEROKWAIT:
  1213. case CTRLALTDEL:
  1214. if (!(ch->flags & XECUTED)) ch->flags |= WAITING;
  1215. case KBREQUEST:
  1216. case BOOT:
  1217. case POWERFAIL:
  1218. case ONCE:
  1219. if (ch->flags & XECUTED) break;
  1220. case ONDEMAND:
  1221. case RESPAWN:
  1222. ch->flags |= RUNNING;
  1223. (void)spawn(ch, &(ch->pid));
  1224. break;
  1225. }
  1226. }
  1227.  
  1228.  
  1229. /*
  1230. * Read the inittab file.
  1231. */
  1232. static
  1233. void read_inittab(void)
  1234. {
  1235. FILE *fp; /* The INITTAB file */
  1236. CHILD *ch, *old, *i; /* Pointers to CHILD structure */
  1237. CHILD *head = NULL; /* Head of linked list */
  1238. #ifdef INITLVL
  1239. struct stat st; /* To stat INITLVL */
  1240. #endif
  1241. sigset_t nmask, omask; /* For blocking SIGCHLD. */
  1242. char buf[256]; /* Line buffer */
  1243. char err[64]; /* Error message. */
  1244. char *id, *rlevel,
  1245. *action, *process; /* Fields of a line */
  1246. char *p;
  1247. int lineNo = 0; /* Line number in INITTAB file */
  1248. int actionNo; /* Decoded action field */
  1249. int f; /* Counter */
  1250. int round; /* round 0 for SIGTERM, 1 for SIGKILL */
  1251. int foundOne = 0; /* No killing no sleep */
  1252. int talk; /* Talk to the user */
  1253. int done = 0; /* Ready yet? */
  1254.  
  1255. #if DEBUG
  1256. if (newFamily != NULL) {
  1257. INITDBG(L_VB, "PANIC newFamily != NULL");
  1258. exit(1);
  1259. }
  1260. INITDBG(L_VB, "Reading inittab");
  1261. #endif
  1262.  
  1263. /*
  1264. * Open INITTAB and real line by line.
  1265. */
  1266. if ((fp = fopen(INITTAB, "r")) == NULL)
  1267. initlog(L_VB, "No inittab file found");
  1268.  
  1269. while(!done) {
  1270. /*
  1271. * Add single user shell entry at the end.
  1272. */
  1273. if (fp == NULL || fgets(buf, sizeof(buf), fp) == NULL) {
  1274. done = 1;
  1275. /*
  1276. * See if we have a single user entry.
  1277. */
  1278. for(old = newFamily; old; old = old->next)
  1279. if (strpbrk(old->rlevel, "S")) break;
  1280. if (old == NULL)
  1281. snprintf(buf, sizeof(buf), "~~:S:wait:%s\n", SULOGIN);
  1282. else
  1283. continue;
  1284. }
  1285. lineNo++;
  1286. /*
  1287. * Skip comments and empty lines
  1288. */
  1289. for(p = buf; *p == ' ' || *p == '\t'; p++)
  1290. ;
  1291. if (*p == '#' || *p == '\n') continue;
  1292.  
  1293. /*
  1294. * Decode the fields
  1295. */
  1296. id = strsep(&p, ":");
  1297. rlevel = strsep(&p, ":");
  1298. action = strsep(&p, ":");
  1299. process = strsep(&p, "\n");
  1300.  
  1301. /*
  1302. * Check if syntax is OK. Be very verbose here, to
  1303. * avoid newbie postings on comp.os.linux.setup :)
  1304. */
  1305. err[0] = 0;
  1306. if (!id || !*id) strcpy(err, "missing id field");
  1307. if (!rlevel) strcpy(err, "missing runlevel field");
  1308. if (!process) strcpy(err, "missing process field");
  1309. if (!action || !*action)
  1310. strcpy(err, "missing action field");
  1311. if (id && strlen(id) > sizeof(utproto.ut_id))
  1312. sprintf(err, "id field too long (max %d characters)",
  1313. (int)sizeof(utproto.ut_id));
  1314. if (rlevel && strlen(rlevel) > 11)
  1315. strcpy(err, "rlevel field too long (max 11 characters)");
  1316. if (process && strlen(process) > 127)
  1317. strcpy(err, "process field too long");
  1318. if (action && strlen(action) > 32)
  1319. strcpy(err, "action field too long");
  1320. if (err[0] != 0) {
  1321. initlog(L_VB, "%s[%d]: %s", INITTAB, lineNo, err);
  1322. INITDBG(L_VB, "%s:%s:%s:%s", id, rlevel, action, process);
  1323. continue;
  1324. }
  1325.  
  1326. /*
  1327. * Decode the "action" field
  1328. */
  1329. actionNo = -1;
  1330. for(f = 0; actions[f].name; f++)
  1331. if (strcasecmp(action, actions[f].name) == 0) {
  1332. actionNo = actions[f].act;
  1333. break;
  1334. }
  1335. if (actionNo == -1) {
  1336. initlog(L_VB, "%s[%d]: %s: unknown action field",
  1337. INITTAB, lineNo, action);
  1338. continue;
  1339. }
  1340.  
  1341. /*
  1342. * See if the id field is unique
  1343. */
  1344. for(old = newFamily; old; old = old->next) {
  1345. if(strcmp(old->id, id) == 0 && strcmp(id, "~~")) {
  1346. initlog(L_VB, "%s[%d]: duplicate ID field \"%s\"",
  1347. INITTAB, lineNo, id);
  1348. break;
  1349. }
  1350. }
  1351. if (old) continue;
  1352.  
  1353. /*
  1354. * Allocate a CHILD structure
  1355. */
  1356. ch = imalloc(sizeof(CHILD));
  1357.  
  1358. /*
  1359. * And fill it in.
  1360. */
  1361. ch->action = actionNo;
  1362. strncpy(ch->id, id, sizeof(utproto.ut_id) + 1); /* Hack for different libs. */
  1363. strncpy(ch->process, process, sizeof(ch->process) - 1);
  1364. if (rlevel[0]) {
  1365. for(f = 0; f < (int)sizeof(rlevel) - 1 && rlevel[f]; f++) {
  1366. ch->rlevel[f] = rlevel[f];
  1367. if (ch->rlevel[f] == 's') ch->rlevel[f] = 'S';
  1368. }
  1369. strncpy(ch->rlevel, rlevel, sizeof(ch->rlevel) - 1);
  1370. } else {
  1371. strcpy(ch->rlevel, "0123456789");
  1372. if (ISPOWER(ch->action))
  1373. strcpy(ch->rlevel, "S0123456789");
  1374. }
  1375. /*
  1376. * We have the fake runlevel '#' for SYSINIT and
  1377. * '*' for BOOT and BOOTWAIT.
  1378. */
  1379. if (ch->action == SYSINIT) strcpy(ch->rlevel, "#");
  1380. if (ch->action == BOOT || ch->action == BOOTWAIT)
  1381. strcpy(ch->rlevel, "*");
  1382.  
  1383. /*
  1384. * Now add it to the linked list. Special for powerfail.
  1385. */
  1386. if (ISPOWER(ch->action)) {
  1387.  
  1388. /*
  1389. * Disable by default
  1390. */
  1391. ch->flags |= XECUTED;
  1392.  
  1393. /*
  1394. * Tricky: insert at the front of the list..
  1395. */
  1396. old = NULL;
  1397. for(i = newFamily; i; i = i->next) {
  1398. if (!ISPOWER(i->action)) break;
  1399. old = i;
  1400. }
  1401. /*
  1402. * Now add after entry "old"
  1403. */
  1404. if (old) {
  1405. ch->next = i;
  1406. old->next = ch;
  1407. if (i == NULL) head = ch;
  1408. } else {
  1409. ch->next = newFamily;
  1410. newFamily = ch;
  1411. if (ch->next == NULL) head = ch;
  1412. }
  1413. } else {
  1414. /*
  1415. * Just add at end of the list
  1416. */
  1417. if (ch->action == KBREQUEST) ch->flags |= XECUTED;
  1418. ch->next = NULL;
  1419. if (head)
  1420. head->next = ch;
  1421. else
  1422. newFamily = ch;
  1423. head = ch;
  1424. }
  1425.  
  1426. /*
  1427. * Walk through the old list comparing id fields
  1428. */
  1429. for(old = family; old; old = old->next)
  1430. if (strcmp(old->id, ch->id) == 0) {
  1431. old->new = ch;
  1432. break;
  1433. }
  1434. }
  1435. /*
  1436. * We're done.
  1437. */
  1438. if (fp) fclose(fp);
  1439.  
  1440. /*
  1441. * Loop through the list of children, and see if they need to
  1442. * be killed.
  1443. */
  1444.  
  1445. INITDBG(L_VB, "Checking for children to kill");
  1446. for(round = 0; round < 2; round++) {
  1447. talk = 1;
  1448. for(ch = family; ch; ch = ch->next) {
  1449. ch->flags &= ~KILLME;
  1450.  
  1451. /*
  1452. * Is this line deleted?
  1453. */
  1454. if (ch->new == NULL) ch->flags |= KILLME;
  1455.  
  1456. /*
  1457. * If the entry has changed, kill it anyway. Note that
  1458. * we do not check ch->process, only the "action" field.
  1459. * This way, you can turn an entry "off" immediately, but
  1460. * changes in the command line will only become effective
  1461. * after the running version has exited.
  1462. */
  1463. if (ch->new && ch->action != ch->new->action) ch->flags |= KILLME;
  1464.  
  1465. /*
  1466. * Only BOOT processes may live in all levels
  1467. */
  1468. if (ch->action != BOOT &&
  1469. strchr(ch->rlevel, runlevel) == NULL) {
  1470. /*
  1471. * Ondemand procedures live always,
  1472. * except in single user
  1473. */
  1474. if (runlevel == 'S' || !(ch->flags & DEMAND))
  1475. ch->flags |= KILLME;
  1476. }
  1477.  
  1478. /*
  1479. * Now, if this process may live note so in the new list
  1480. */
  1481. if ((ch->flags & KILLME) == 0) {
  1482. ch->new->flags = ch->flags;
  1483. ch->new->pid = ch->pid;
  1484. ch->new->exstat = ch->exstat;
  1485. continue;
  1486. }
  1487.  
  1488.  
  1489. /*
  1490. * Is this process still around?
  1491. */
  1492. if ((ch->flags & RUNNING) == 0) {
  1493. ch->flags &= ~KILLME;
  1494. continue;
  1495. }
  1496. INITDBG(L_VB, "Killing \"%s\"", ch->process);
  1497. switch(round) {
  1498. case 0: /* Send TERM signal */
  1499. if (talk)
  1500. initlog(L_CO,
  1501. "Sending processes the TERM signal");
  1502. kill(-(ch->pid), SIGTERM);
  1503. foundOne = 1;
  1504. break;
  1505. case 1: /* Send KILL signal and collect status */
  1506. if (talk)
  1507. initlog(L_CO,
  1508. "Sending processes the KILL signal");
  1509. kill(-(ch->pid), SIGKILL);
  1510. break;
  1511. }
  1512. talk = 0;
  1513.  
  1514. }
  1515. /*
  1516. * See if we have to wait 5 seconds
  1517. */
  1518. if (foundOne && round == 0) {
  1519. /*
  1520. * Yup, but check every second if we still have children.
  1521. */
  1522. for(f = 0; f < sltime; f++) {
  1523. for(ch = family; ch; ch = ch->next) {
  1524. if (!(ch->flags & KILLME)) continue;
  1525. if ((ch->flags & RUNNING) && !(ch->flags & ZOMBIE))
  1526. break;
  1527. }
  1528. if (ch == NULL) {
  1529. /*
  1530. * No running children, skip SIGKILL
  1531. */
  1532. round = 1;
  1533. foundOne = 0; /* Skip the sleep below. */
  1534. break;
  1535. }
  1536. do_sleep(1);
  1537. }
  1538. }
  1539. }
  1540.  
  1541. /*
  1542. * Now give all processes the chance to die and collect exit statuses.
  1543. */
  1544. if (foundOne) do_sleep(1);
  1545. for(ch = family; ch; ch = ch->next)
  1546. if (ch->flags & KILLME) {
  1547. if (!(ch->flags & ZOMBIE))
  1548. initlog(L_CO, "Pid %d [id %s] seems to hang", ch->pid,
  1549. ch->id);
  1550. else {
  1551. INITDBG(L_VB, "Updating utmp for pid %d [id %s]",
  1552. ch->pid, ch->id);
  1553. ch->flags &= ~RUNNING;
  1554. if (ch->process[0] != '+')
  1555. write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
  1556. }
  1557. }
  1558.  
  1559. /*
  1560. * Both rounds done; clean up the list.
  1561. */
  1562. sigemptyset(&nmask);
  1563. sigaddset(&nmask, SIGCHLD);
  1564. sigprocmask(SIG_BLOCK, &nmask, &omask);
  1565. for(ch = family; ch; ch = old) {
  1566. old = ch->next;
  1567. free(ch);
  1568. }
  1569. family = newFamily;
  1570. for(ch = family; ch; ch = ch->next) ch->new = NULL;
  1571. newFamily = NULL;
  1572. sigprocmask(SIG_SETMASK, &omask, NULL);
  1573.  
  1574. #ifdef INITLVL
  1575. /*
  1576. * Dispose of INITLVL file.
  1577. */
  1578. if (lstat(INITLVL, &st) >= 0 && S_ISLNK(st.st_mode)) {
  1579. /*
  1580. * INITLVL is a symbolic link, so just truncate the file.
  1581. */
  1582. close(open(INITLVL, O_WRONLY|O_TRUNC));
  1583. } else {
  1584. /*
  1585. * Delete INITLVL file.
  1586. */
  1587. unlink(INITLVL);
  1588. }
  1589. #endif
  1590. #ifdef INITLVL2
  1591. /*
  1592. * Dispose of INITLVL2 file.
  1593. */
  1594. if (lstat(INITLVL2, &st) >= 0 && S_ISLNK(st.st_mode)) {
  1595. /*
  1596. * INITLVL2 is a symbolic link, so just truncate the file.
  1597. */
  1598. close(open(INITLVL2, O_WRONLY|O_TRUNC));
  1599. } else {
  1600. /*
  1601. * Delete INITLVL2 file.
  1602. */
  1603. unlink(INITLVL2);
  1604. }
  1605. #endif
  1606. }
  1607.  
  1608. /*
  1609. * Walk through the family list and start up children.
  1610. * The entries that do not belong here at all are removed
  1611. * from the list.
  1612. */
  1613. static
  1614. void start_if_needed(void)
  1615. {
  1616. CHILD *ch; /* Pointer to child */
  1617. int delete; /* Delete this entry from list? */
  1618.  
  1619. INITDBG(L_VB, "Checking for children to start");
  1620.  
  1621. for(ch = family; ch; ch = ch->next) {
  1622.  
  1623. #if DEBUG
  1624. if (ch->rlevel[0] == 'C') {
  1625. INITDBG(L_VB, "%s: flags %d", ch->process, ch->flags);
  1626. }
  1627. #endif
  1628.  
  1629. /* Are we waiting for this process? Then quit here. */
  1630. if (ch->flags & WAITING) break;
  1631.  
  1632. /* Already running? OK, don't touch it */
  1633. if (ch->flags & RUNNING) continue;
  1634.  
  1635. /* See if we have to start it up */
  1636. delete = 1;
  1637. if (strchr(ch->rlevel, runlevel) ||
  1638. ((ch->flags & DEMAND) && !strchr("#*Ss", runlevel))) {
  1639. startup(ch);
  1640. delete = 0;
  1641. }
  1642.  
  1643. if (delete) {
  1644. /* FIXME: is this OK? */
  1645. ch->flags &= ~(RUNNING|WAITING);
  1646. if (!ISPOWER(ch->action) && ch->action != KBREQUEST)
  1647. ch->flags &= ~XECUTED;
  1648. ch->pid = 0;
  1649. } else
  1650. /* Do we have to wait for this process? */
  1651. if (ch->flags & WAITING) break;
  1652. }
  1653. /* Done. */
  1654. }
  1655.  
  1656. /*
  1657. * Ask the user on the console for a runlevel
  1658. */
  1659. static
  1660. int ask_runlevel(void)
  1661. {
  1662. const char prompt[] = "\nEnter runlevel: ";
  1663. char buf[8];
  1664. int lvl = -1;
  1665. int fd;
  1666.  
  1667. console_stty();
  1668. fd = console_open(O_RDWR|O_NOCTTY);
  1669.  
  1670. if (fd < 0) return('S');
  1671.  
  1672. while(!strchr("0123456789S", lvl)) {
  1673. write(fd, prompt, sizeof(prompt) - 1);
  1674. buf[0] = 0;
  1675. read(fd, buf, sizeof(buf));
  1676. if (buf[0] != 0 && (buf[1] == '\r' || buf[1] == '\n'))
  1677. lvl = buf[0];
  1678. if (islower(lvl)) lvl = toupper(lvl);
  1679. }
  1680. close(fd);
  1681. return lvl;
  1682. }
  1683.  
  1684. /*
  1685. * Search the INITTAB file for the 'initdefault' field, with the default
  1686. * runlevel. If this fails, ask the user to supply a runlevel.
  1687. */
  1688. static
  1689. int get_init_default(void)
  1690. {
  1691. CHILD *ch;
  1692. int lvl = -1;
  1693. char *p;
  1694.  
  1695. /*
  1696. * Look for initdefault.
  1697. */
  1698. for(ch = family; ch; ch = ch->next)
  1699. if (ch->action == INITDEFAULT) {
  1700. p = ch->rlevel;
  1701. while(*p) {
  1702. if (*p > lvl) lvl = *p;
  1703. p++;
  1704. }
  1705. break;
  1706. }
  1707. /*
  1708. * See if level is valid
  1709. */
  1710. if (lvl > 0) {
  1711. if (islower(lvl)) lvl = toupper(lvl);
  1712. if (strchr("0123456789S", lvl) == NULL) {
  1713. initlog(L_VB,
  1714. "Initdefault level '%c' is invalid", lvl);
  1715. lvl = 0;
  1716. }
  1717. }
  1718. /*
  1719. * Ask for runlevel on console if needed.
  1720. */
  1721. if (lvl <= 0) lvl = ask_runlevel();
  1722.  
  1723. /*
  1724. * Log the fact that we have a runlevel now.
  1725. */
  1726. return lvl;
  1727. }
  1728.  
  1729.  
  1730. /*
  1731. * We got signaled.
  1732. *
  1733. * Do actions for the new level. If we are compatible with
  1734. * the "old" INITLVL and arg == 0, try to read the new
  1735. * runlevel from that file first.
  1736. */
  1737. static
  1738. int read_level(int arg)
  1739. {
  1740. CHILD *ch; /* Walk through list */
  1741. unsigned char foo = 'X'; /* Contents of INITLVL */
  1742. int ok = 1;
  1743. #ifdef INITLVL
  1744. FILE *fp;
  1745. struct stat stt;
  1746. int st;
  1747. #endif
  1748.  
  1749. if (arg) foo = arg;
  1750.  
  1751. #ifdef INITLVL
  1752. ok = 0;
  1753.  
  1754. if (arg == 0) {
  1755. fp = NULL;
  1756. if (stat(INITLVL, &stt) != 0 || stt.st_size != 0L)
  1757. fp = fopen(INITLVL, "r");
  1758. #ifdef INITLVL2
  1759. if (fp == NULL &&
  1760. (stat(INITLVL2, &stt) != 0 || stt.st_size != 0L))
  1761. fp = fopen(INITLVL2, "r");
  1762. #endif
  1763. if (fp == NULL) {
  1764. /* INITLVL file empty or not there - act as 'init q' */
  1765. initlog(L_SY, "Re-reading inittab");
  1766. return(runlevel);
  1767. }
  1768. ok = fscanf(fp, "%c %d", &foo, &st);
  1769. fclose(fp);
  1770. } else {
  1771. /* We go to the new runlevel passed as an argument. */
  1772. foo = arg;
  1773. ok = 1;
  1774. }
  1775. if (ok == 2) sltime = st;
  1776.  
  1777. #endif /* INITLVL */
  1778.  
  1779. if (islower(foo)) foo = toupper(foo);
  1780. if (ok < 1 || ok > 2 || strchr("QS0123456789ABCU", foo) == NULL) {
  1781. initlog(L_VB, "bad runlevel: %c", foo);
  1782. return runlevel;
  1783. }
  1784.  
  1785. /* Log this action */
  1786. switch(foo) {
  1787. case 'S':
  1788. initlog(L_VB, "Going single user");
  1789. break;
  1790. case 'Q':
  1791. initlog(L_SY, "Re-reading inittab");
  1792. break;
  1793. case 'A':
  1794. case 'B':
  1795. case 'C':
  1796. initlog(L_SY,
  1797. "Activating demand-procedures for '%c'", foo);
  1798. break;
  1799. case 'U':
  1800. initlog(L_SY, "Trying to re-exec init");
  1801. return 'U';
  1802. default:
  1803. initlog(L_VB, "Switching to runlevel: %c", foo);
  1804. }
  1805.  
  1806. if (foo == 'Q') {
  1807. #if defined(SIGINT_ONLYONCE) && (SIGINT_ONLYONCE == 1)
  1808. /* Re-enable signal from keyboard */
  1809. struct sigaction sa;
  1810. SETSIG(sa, SIGINT, signal_handler, 0);
  1811. #endif
  1812. return runlevel;
  1813. }
  1814.  
  1815. /* Check if this is a runlevel a, b or c */
  1816. if (strchr("ABC", foo)) {
  1817. if (runlevel == 'S') return(runlevel);
  1818.  
  1819. /* Read inittab again first! */
  1820. read_inittab();
  1821.  
  1822. /* Mark those special tasks */
  1823. for(ch = family; ch; ch = ch->next)
  1824. if (strchr(ch->rlevel, foo) != NULL ||
  1825. strchr(ch->rlevel, tolower(foo)) != NULL) {
  1826. ch->flags |= DEMAND;
  1827. ch->flags &= ~XECUTED;
  1828. INITDBG(L_VB,
  1829. "Marking (%s) as ondemand, flags %d",
  1830. ch->id, ch->flags);
  1831. }
  1832. return runlevel;
  1833. }
  1834.  
  1835. /* Store both the old and the new runlevel. */
  1836. wrote_utmp_rlevel = 0;
  1837. wrote_wtmp_rlevel = 0;
  1838. write_utmp_wtmp("runlevel", "~~", foo + 256*runlevel, RUN_LVL, "~");
  1839. thislevel = foo;
  1840. prevlevel = runlevel;
  1841. return foo;
  1842. }
  1843.  
  1844.  
  1845. /*
  1846. * This procedure is called after every signal (SIGHUP, SIGALRM..)
  1847. *
  1848. * Only clear the 'failing' flag if the process is sleeping
  1849. * longer than 5 minutes, or inittab was read again due
  1850. * to user interaction.
  1851. */
  1852. static
  1853. void fail_check(void)
  1854. {
  1855. CHILD *ch; /* Pointer to child structure */
  1856. time_t t; /* System time */
  1857. time_t next_alarm = 0; /* When to set next alarm */
  1858.  
  1859. time(&t);
  1860.  
  1861. for(ch = family; ch; ch = ch->next) {
  1862.  
  1863. if (ch->flags & FAILING) {
  1864. /* Can we free this sucker? */
  1865. if (ch->tm + SLEEPTIME < t) {
  1866. ch->flags &= ~FAILING;
  1867. ch->count = 0;
  1868. ch->tm = 0;
  1869. } else {
  1870. /* No, we'll look again later */
  1871. if (next_alarm == 0 ||
  1872. ch->tm + SLEEPTIME > next_alarm)
  1873. next_alarm = ch->tm + SLEEPTIME;
  1874. }
  1875. }
  1876. }
  1877. if (next_alarm) {
  1878. next_alarm -= t;
  1879. if (next_alarm < 1) next_alarm = 1;
  1880. alarm(next_alarm);
  1881. }
  1882. }
  1883.  
  1884. /* Set all 'Fail' timers to 0 */
  1885. static
  1886. void fail_cancel(void)
  1887. {
  1888. CHILD *ch;
  1889.  
  1890. for(ch = family; ch; ch = ch->next) {
  1891. ch->count = 0;
  1892. ch->tm = 0;
  1893. ch->flags &= ~FAILING;
  1894. }
  1895. }
  1896.  
  1897. /*
  1898. * Start up powerfail entries.
  1899. */
  1900. static
  1901. void do_power_fail(int pwrstat)
  1902. {
  1903. CHILD *ch;
  1904.  
  1905. /*
  1906. * Tell powerwait & powerfail entries to start up
  1907. */
  1908. for (ch = family; ch; ch = ch->next) {
  1909. if (pwrstat == 'O') {
  1910. /*
  1911. * The power is OK again.
  1912. */
  1913. if (ch->action == POWEROKWAIT)
  1914. ch->flags &= ~XECUTED;
  1915. } else if (pwrstat == 'L') {
  1916. /*
  1917. * Low battery, shut down now.
  1918. */
  1919. if (ch->action == POWERFAILNOW)
  1920. ch->flags &= ~XECUTED;
  1921. } else {
  1922. /*
  1923. * Power is failing, shutdown imminent
  1924. */
  1925. if (ch->action == POWERFAIL || ch->action == POWERWAIT)
  1926. ch->flags &= ~XECUTED;
  1927. }
  1928. }
  1929. }
  1930.  
  1931. /*
  1932. * Check for state-pipe presence
  1933. */
  1934. static
  1935. int check_pipe(int fd)
  1936. {
  1937. struct timeval t;
  1938. fd_set s;
  1939. char signature[8];
  1940.  
  1941. FD_ZERO(&s);
  1942. FD_SET(fd, &s);
  1943. t.tv_sec = t.tv_usec = 0;
  1944.  
  1945. if (select(fd+1, &s, NULL, NULL, &t) != 1)
  1946. return 0;
  1947. if (read(fd, signature, 8) != 8)
  1948. return 0;
  1949. return strncmp(Signature, signature, 8) == 0;
  1950. }
  1951.  
  1952. /*
  1953. * Make a state-pipe.
  1954. */
  1955. static
  1956. int make_pipe(int fd)
  1957. {
  1958. int fds[2];
  1959.  
  1960. pipe(fds);
  1961. dup2(fds[0], fd);
  1962. close(fds[0]);
  1963. fcntl(fds[1], F_SETFD, 1);
  1964. fcntl(fd, F_SETFD, 0);
  1965. write(fds[1], Signature, 8);
  1966.  
  1967. return fds[1];
  1968. }
  1969.  
  1970. /*
  1971. * Attempt to re-exec.
  1972. */
  1973. static
  1974. void re_exec(void)
  1975. {
  1976. CHILD *ch;
  1977. sigset_t mask, oldset;
  1978. pid_t pid;
  1979. char **env;
  1980. int fd;
  1981.  
  1982. if (strchr("S0123456",runlevel) == NULL)
  1983. return;
  1984.  
  1985. /*
  1986. * Reset the alarm, and block all signals.
  1987. */
  1988. alarm(0);
  1989. sigfillset(&mask);
  1990. sigprocmask(SIG_BLOCK, &mask, &oldset);
  1991.  
  1992. /*
  1993. * construct a pipe fd --> STATE_PIPE and write a signature
  1994. */
  1995. fd = make_pipe(STATE_PIPE);
  1996.  
  1997. /*
  1998. * It's a backup day today, so I'm pissed off. Being a BOFH, however,
  1999. * does have it's advantages...
  2000. */
  2001. fail_cancel();
  2002. close(pipe_fd);
  2003. pipe_fd = -1;
  2004. DELSET(got_signals, SIGCHLD);
  2005. DELSET(got_signals, SIGHUP);
  2006. DELSET(got_signals, SIGUSR1);
  2007.  
  2008. /*
  2009. * That should be cleaned.
  2010. */
  2011. for(ch = family; ch; ch = ch->next)
  2012. if (ch->flags & ZOMBIE) {
  2013. INITDBG(L_VB, "Child died, PID= %d", ch->pid);
  2014. ch->flags &= ~(RUNNING|ZOMBIE|WAITING);
  2015. if (ch->process[0] != '+')
  2016. write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
  2017. }
  2018.  
  2019. if ((pid = fork()) == 0) {
  2020. /*
  2021. * Child sends state information to the parent.
  2022. */
  2023. send_state(fd);
  2024. exit(0);
  2025. }
  2026.  
  2027. /*
  2028. * The existing init process execs a new init binary.
  2029. */
  2030. env = init_buildenv(0);
  2031. execle(myname, myname, "--init", NULL, env);
  2032.  
  2033. /*
  2034. * We shouldn't be here, something failed.
  2035. * Bitch, close the state pipe, unblock signals and return.
  2036. */
  2037. close(fd);
  2038. close(STATE_PIPE);
  2039. sigprocmask(SIG_SETMASK, &oldset, NULL);
  2040. init_freeenv(env);
  2041. initlog(L_CO, "Attempt to re-exec failed");
  2042. }
  2043.  
  2044. /*
  2045. * Redo utmp/wtmp entries if required or requested
  2046. * Check for written records and size of utmp
  2047. */
  2048. static
  2049. void redo_utmp_wtmp(void)
  2050. {
  2051. struct stat ustat;
  2052. const int ret = stat(UTMP_FILE, &ustat);
  2053.  
  2054. if ((ret < 0) || (ustat.st_size == 0))
  2055. wrote_utmp_rlevel = wrote_utmp_reboot = 0;
  2056.  
  2057. if ((wrote_wtmp_reboot == 0) || (wrote_utmp_reboot == 0))
  2058. write_utmp_wtmp("reboot", "~~", 0, BOOT_TIME, "~");
  2059.  
  2060. if ((wrote_wtmp_rlevel == 0) || (wrote_wtmp_rlevel == 0))
  2061. write_utmp_wtmp("runlevel", "~~", thislevel + 256 * prevlevel, RUN_LVL, "~");
  2062. }
  2063.  
  2064. /*
  2065. * We got a change runlevel request through the
  2066. * init.fifo. Process it.
  2067. */
  2068. static
  2069. void fifo_new_level(int level)
  2070. {
  2071. #if CHANGE_WAIT
  2072. CHILD *ch;
  2073. #endif
  2074. int oldlevel;
  2075.  
  2076. if (level == runlevel) return;
  2077.  
  2078. #if CHANGE_WAIT
  2079. /* Are we waiting for a child? */
  2080. for(ch = family; ch; ch = ch->next)
  2081. if (ch->flags & WAITING) break;
  2082. if (ch == NULL)
  2083. #endif
  2084. {
  2085. /* We need to go into a new runlevel */
  2086. oldlevel = runlevel;
  2087. runlevel = read_level(level);
  2088. if (runlevel == 'U') {
  2089. runlevel = oldlevel;
  2090. re_exec();
  2091. } else {
  2092. if (oldlevel != 'S' && runlevel == 'S') console_stty();
  2093. if (runlevel == '6' || runlevel == '0' ||
  2094. runlevel == '1') console_stty();
  2095. if (runlevel > '1' && runlevel < '6') redo_utmp_wtmp();
  2096. read_inittab();
  2097. fail_cancel();
  2098. setproctitle("init [%c]", (int)runlevel);
  2099. }
  2100. }
  2101. }
  2102.  
  2103.  
  2104. /*
  2105. * Set/unset environment variables. The variables are
  2106. * encoded as KEY=VAL\0KEY=VAL\0\0. With "=VAL" it means
  2107. * setenv, without it means unsetenv.
  2108. */
  2109. static
  2110. void initcmd_setenv(char *data, int size)
  2111. {
  2112. char *env, *p, *e, *eq;
  2113. int i, sz;
  2114.  
  2115. e = data + size;
  2116.  
  2117. while (*data && data < e) {
  2118. eq = NULL;
  2119. for (p = data; *p && p < e; p++)
  2120. if (*p == '=') eq = p;
  2121. if (*p) break;
  2122. env = data;
  2123. data = ++p;
  2124.  
  2125. sz = eq ? (eq - env) : (p - env);
  2126.  
  2127. /*initlog(L_SY, "init_setenv: %s, %s, %d", env, eq, sz);*/
  2128.  
  2129. /*
  2130. * We only allow INIT_* to be set.
  2131. */
  2132. if (strncmp(env, "INIT_", 5) != 0)
  2133. continue;
  2134.  
  2135. /* Free existing vars. */
  2136. for (i = 0; i < NR_EXTRA_ENV; i++) {
  2137. if (extra_env[i] == NULL) continue;
  2138. if (!strncmp(extra_env[i], env, sz) &&
  2139. extra_env[i][sz] == '=') {
  2140. free(extra_env[i]);
  2141. extra_env[i] = NULL;
  2142. }
  2143. }
  2144.  
  2145. /* Set new vars if needed. */
  2146. if (eq == NULL) continue;
  2147. for (i = 0; i < NR_EXTRA_ENV; i++) {
  2148. if (extra_env[i] == NULL) {
  2149. extra_env[i] = istrdup(env);
  2150. break;
  2151. }
  2152. }
  2153. }
  2154. }
  2155.  
  2156.  
  2157. /*
  2158. * Read from the init FIFO. Processes like telnetd and rlogind can
  2159. * ask us to create login processes on their behalf.
  2160. *
  2161. * FIXME: this needs to be finished. NOT that it is buggy, but we need
  2162. * to add the telnetd/rlogind stuff so people can start using it.
  2163. * Maybe move to using an AF_UNIX socket so we can use
  2164. * the 2.2 kernel credential stuff to see who we're talking to.
  2165. *
  2166. */
  2167. static
  2168. void check_init_fifo(void)
  2169. {
  2170. struct init_request request;
  2171. struct timeval tv;
  2172. struct stat st, st2;
  2173. fd_set fds;
  2174. int n;
  2175. int quit = 0;
  2176.  
  2177. /*
  2178. * First, try to create /dev/initctl if not present.
  2179. */
  2180. if (stat(INIT_FIFO, &st2) < 0 && errno == ENOENT)
  2181. (void)mkfifo(INIT_FIFO, 0600);
  2182.  
  2183. /*
  2184. * If /dev/initctl is open, stat the file to see if it
  2185. * is still the _same_ inode.
  2186. */
  2187. if (pipe_fd >= 0) {
  2188. fstat(pipe_fd, &st);
  2189. if (stat(INIT_FIFO, &st2) < 0 ||
  2190. st.st_dev != st2.st_dev ||
  2191. st.st_ino != st2.st_ino) {
  2192. close(pipe_fd);
  2193. pipe_fd = -1;
  2194. }
  2195. }
  2196.  
  2197. /*
  2198. * Now finally try to open /dev/initctl
  2199. */
  2200. if (pipe_fd < 0) {
  2201. if ((pipe_fd = open(INIT_FIFO, O_RDWR|O_NONBLOCK)) >= 0) {
  2202. fstat(pipe_fd, &st);
  2203. if (!S_ISFIFO(st.st_mode)) {
  2204. initlog(L_VB, "%s is not a fifo", INIT_FIFO);
  2205. close(pipe_fd);
  2206. pipe_fd = -1;
  2207. }
  2208. }
  2209. if (pipe_fd >= 0) {
  2210. /*
  2211. * Don't use fd's 0, 1 or 2.
  2212. */
  2213. (void) dup2(pipe_fd, PIPE_FD);
  2214. close(pipe_fd);
  2215. pipe_fd = PIPE_FD;
  2216.  
  2217. /*
  2218. * Return to caller - we'll be back later.
  2219. */
  2220. }
  2221. }
  2222.  
  2223. /* Wait for data to appear, _if_ the pipe was opened. */
  2224. if (pipe_fd >= 0) while(!quit) {
  2225.  
  2226. /* Do select, return on EINTR. */
  2227. FD_ZERO(&fds);
  2228. FD_SET(pipe_fd, &fds);
  2229. tv.tv_sec = 5;
  2230. tv.tv_usec = 0;
  2231. n = select(pipe_fd + 1, &fds, NULL, NULL, &tv);
  2232. if (n <= 0) {
  2233. if (n == 0 || errno == EINTR) return;
  2234. continue;
  2235. }
  2236.  
  2237. /* Read the data, return on EINTR. */
  2238. n = read(pipe_fd, &request, sizeof(request));
  2239. if (n == 0) {
  2240. /*
  2241. * End of file. This can't happen under Linux (because
  2242. * the pipe is opened O_RDWR - see select() in the
  2243. * kernel) but you never know...
  2244. */
  2245. close(pipe_fd);
  2246. pipe_fd = -1;
  2247. return;
  2248. }
  2249. if (n <= 0) {
  2250. if (errno == EINTR) return;
  2251. initlog(L_VB, "error reading initrequest");
  2252. continue;
  2253. }
  2254.  
  2255. /*
  2256. * This is a convenient point to also try to
  2257. * find the console device or check if it changed.
  2258. */
  2259. console_init();
  2260.  
  2261. /*
  2262. * Process request.
  2263. */
  2264. if (request.magic != INIT_MAGIC || n != sizeof(request)) {
  2265. initlog(L_VB, "got bogus initrequest");
  2266. continue;
  2267. }
  2268. switch(request.cmd) {
  2269. case INIT_CMD_RUNLVL:
  2270. sltime = request.sleeptime;
  2271. fifo_new_level(request.runlevel);
  2272. quit = 1;
  2273. break;
  2274. case INIT_CMD_POWERFAIL:
  2275. sltime = request.sleeptime;
  2276. do_power_fail('F');
  2277. quit = 1;
  2278. break;
  2279. case INIT_CMD_POWERFAILNOW:
  2280. sltime = request.sleeptime;
  2281. do_power_fail('L');
  2282. quit = 1;
  2283. break;
  2284. case INIT_CMD_POWEROK:
  2285. sltime = request.sleeptime;
  2286. do_power_fail('O');
  2287. quit = 1;
  2288. break;
  2289. case INIT_CMD_SETENV:
  2290. initcmd_setenv(request.i.data, sizeof(request.i.data));
  2291. break;
  2292. default:
  2293. initlog(L_VB, "got unimplemented initrequest.");
  2294. break;
  2295. }
  2296. }
  2297.  
  2298. /*
  2299. * We come here if the pipe couldn't be opened.
  2300. */
  2301. if (pipe_fd < 0) pause();
  2302.  
  2303. }
  2304.  
  2305.  
  2306. /*
  2307. * This function is used in the transition
  2308. * sysinit (-> single user) boot -> multi-user.
  2309. */
  2310. static
  2311. void boot_transitions()
  2312. {
  2313. CHILD *ch;
  2314. static int newlevel = 0;
  2315. static int warn = 1;
  2316. int loglevel;
  2317. int oldlevel;
  2318.  
  2319. /* Check if there is something to wait for! */
  2320. for( ch = family; ch; ch = ch->next )
  2321. if ((ch->flags & RUNNING) && ch->action != BOOT) break;
  2322.  
  2323. if (ch == NULL) {
  2324. /* No processes left in this level, proceed to next level. */
  2325. loglevel = -1;
  2326. oldlevel = 'N';
  2327. switch(runlevel) {
  2328. case '#': /* SYSINIT -> BOOT */
  2329. INITDBG(L_VB, "SYSINIT -> BOOT");
  2330.  
  2331. /* Write a boot record. */
  2332. wrote_utmp_reboot = 0;
  2333. wrote_wtmp_reboot = 0;
  2334. write_utmp_wtmp("reboot", "~~", 0, BOOT_TIME, "~");
  2335.  
  2336. /* Get our run level */
  2337. newlevel = dfl_level ? dfl_level : get_init_default();
  2338. if (newlevel == 'S') {
  2339. runlevel = newlevel;
  2340. /* Not really 'S' but show anyway. */
  2341. setproctitle("init [S]");
  2342. } else
  2343. runlevel = '*';
  2344. break;
  2345. case '*': /* BOOT -> NORMAL */
  2346. INITDBG(L_VB, "BOOT -> NORMAL");
  2347. if (runlevel != newlevel)
  2348. loglevel = newlevel;
  2349. runlevel = newlevel;
  2350. did_boot = 1;
  2351. warn = 1;
  2352. break;
  2353. case 'S': /* Ended SU mode */
  2354. case 's':
  2355. INITDBG(L_VB, "END SU MODE");
  2356. newlevel = get_init_default();
  2357. if (!did_boot && newlevel != 'S')
  2358. runlevel = '*';
  2359. else {
  2360. if (runlevel != newlevel)
  2361. loglevel = newlevel;
  2362. runlevel = newlevel;
  2363. oldlevel = 'S';
  2364. }
  2365. warn = 1;
  2366. for(ch = family; ch; ch = ch->next)
  2367. if (strcmp(ch->rlevel, "S") == 0)
  2368. ch->flags &= ~(FAILING|WAITING|XECUTED);
  2369. break;
  2370. default:
  2371. if (warn)
  2372. initlog(L_VB,
  2373. "no more processes left in this runlevel");
  2374. warn = 0;
  2375. loglevel = -1;
  2376. if (got_signals == 0)
  2377. check_init_fifo();
  2378. break;
  2379. }
  2380. if (loglevel > 0) {
  2381. initlog(L_VB, "Entering runlevel: %c", runlevel);
  2382. wrote_utmp_rlevel = 0;
  2383. wrote_wtmp_rlevel = 0;
  2384. write_utmp_wtmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~");
  2385. thislevel = runlevel;
  2386. prevlevel = oldlevel;
  2387. setproctitle("init [%c]", (int)runlevel);
  2388. }
  2389. }
  2390. }
  2391.  
  2392. /*
  2393. * Init got hit by a signal. See which signal it is,
  2394. * and act accordingly.
  2395. */
  2396. static
  2397. void process_signals()
  2398. {
  2399. CHILD *ch;
  2400. int pwrstat;
  2401. int oldlevel;
  2402. int fd;
  2403. char c;
  2404.  
  2405. if (ISMEMBER(got_signals, SIGPWR)) {
  2406. INITDBG(L_VB, "got SIGPWR");
  2407. /* See _what_ kind of SIGPWR this is. */
  2408. pwrstat = 0;
  2409. if ((fd = open(PWRSTAT, O_RDONLY)) >= 0) {
  2410. c = 0;
  2411. read(fd, &c, 1);
  2412. pwrstat = c;
  2413. close(fd);
  2414. unlink(PWRSTAT);
  2415. } else if ((fd = open(PWRSTAT_OLD, O_RDONLY)) >= 0) {
  2416. /* Path changed 2010-03-20. Look for the old path for a while. */
  2417. initlog(L_VB, "warning: found obsolete path %s, use %s instead",
  2418. PWRSTAT_OLD, PWRSTAT);
  2419. c = 0;
  2420. read(fd, &c, 1);
  2421. pwrstat = c;
  2422. close(fd);
  2423. unlink(PWRSTAT_OLD);
  2424. }
  2425. do_power_fail(pwrstat);
  2426. DELSET(got_signals, SIGPWR);
  2427. }
  2428.  
  2429. if (ISMEMBER(got_signals, SIGINT)) {
  2430. #if defined(SIGINT_ONLYONCE) && (SIGINT_ONLYONCE == 1)
  2431. /* Ignore any further signal from keyboard */
  2432. struct sigaction sa;
  2433. SETSIG(sa, SIGINT, SIG_IGN, SA_RESTART);
  2434. #endif
  2435. INITDBG(L_VB, "got SIGINT");
  2436. /* Tell ctrlaltdel entry to start up */
  2437. for(ch = family; ch; ch = ch->next)
  2438. if (ch->action == CTRLALTDEL)
  2439. ch->flags &= ~XECUTED;
  2440. DELSET(got_signals, SIGINT);
  2441. }
  2442.  
  2443. if (ISMEMBER(got_signals, SIGWINCH)) {
  2444. INITDBG(L_VB, "got SIGWINCH");
  2445. /* Tell kbrequest entry to start up */
  2446. for(ch = family; ch; ch = ch->next)
  2447. if (ch->action == KBREQUEST)
  2448. ch->flags &= ~XECUTED;
  2449. DELSET(got_signals, SIGWINCH);
  2450. }
  2451.  
  2452. if (ISMEMBER(got_signals, SIGALRM)) {
  2453. INITDBG(L_VB, "got SIGALRM");
  2454. /* The timer went off: check it out */
  2455. DELSET(got_signals, SIGALRM);
  2456. }
  2457.  
  2458. if (ISMEMBER(got_signals, SIGCHLD)) {
  2459. INITDBG(L_VB, "got SIGCHLD");
  2460. /* First set flag to 0 */
  2461. DELSET(got_signals, SIGCHLD);
  2462.  
  2463. /* See which child this was */
  2464. for(ch = family; ch; ch = ch->next)
  2465. if (ch->flags & ZOMBIE) {
  2466. INITDBG(L_VB, "Child died, PID= %d", ch->pid);
  2467. ch->flags &= ~(RUNNING|ZOMBIE|WAITING);
  2468. if (ch->process[0] != '+')
  2469. write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
  2470. }
  2471.  
  2472. }
  2473.  
  2474. if (ISMEMBER(got_signals, SIGHUP)) {
  2475. INITDBG(L_VB, "got SIGHUP");
  2476. #if CHANGE_WAIT
  2477. /* Are we waiting for a child? */
  2478. for(ch = family; ch; ch = ch->next)
  2479. if (ch->flags & WAITING) break;
  2480. if (ch == NULL)
  2481. #endif
  2482. {
  2483. /* We need to go into a new runlevel */
  2484. oldlevel = runlevel;
  2485. #ifdef INITLVL
  2486. runlevel = read_level(0);
  2487. #endif
  2488. if (runlevel == 'U') {
  2489. runlevel = oldlevel;
  2490. re_exec();
  2491. } else {
  2492. if (oldlevel != 'S' && runlevel == 'S') console_stty();
  2493. if (runlevel == '6' || runlevel == '0' ||
  2494. runlevel == '1') console_stty();
  2495. read_inittab();
  2496. fail_cancel();
  2497. setproctitle("init [%c]", (int)runlevel);
  2498. DELSET(got_signals, SIGHUP);
  2499. }
  2500. }
  2501. }
  2502. if (ISMEMBER(got_signals, SIGUSR1)) {
  2503. /*
  2504. * SIGUSR1 means close and reopen /dev/initctl
  2505. */
  2506. INITDBG(L_VB, "got SIGUSR1");
  2507. close(pipe_fd);
  2508. pipe_fd = -1;
  2509. DELSET(got_signals, SIGUSR1);
  2510. }
  2511. }
  2512.  
  2513. /*
  2514. * The main loop
  2515. */
  2516. static
  2517. void init_main(void)
  2518. {
  2519. CHILD *ch;
  2520. struct sigaction sa;
  2521. sigset_t sgt;
  2522. int f, st;
  2523.  
  2524. if (!reload) {
  2525.  
  2526. #if INITDEBUG
  2527. /*
  2528. * Fork so we can debug the init process.
  2529. */
  2530. if ((f = fork()) > 0) {
  2531. static const char killmsg[] = "PRNT: init killed.\r\n";
  2532. pid_t rc;
  2533.  
  2534. while((rc = wait(&st)) != f)
  2535. if (rc < 0 && errno == ECHILD)
  2536. break;
  2537. write(1, killmsg, sizeof(killmsg) - 1);
  2538. while(1) pause();
  2539. }
  2540. #endif
  2541.  
  2542. #ifdef __linux__
  2543. /*
  2544. * Tell the kernel to send us SIGINT when CTRL-ALT-DEL
  2545. * is pressed, and that we want to handle keyboard signals.
  2546. */
  2547. init_reboot(BMAGIC_SOFT);
  2548. if ((f = open(VT_MASTER, O_RDWR | O_NOCTTY)) >= 0) {
  2549. (void) ioctl(f, KDSIGACCEPT, SIGWINCH);
  2550. close(f);
  2551. } else
  2552. (void) ioctl(0, KDSIGACCEPT, SIGWINCH);
  2553. #endif
  2554.  
  2555. /*
  2556. * Ignore all signals.
  2557. */
  2558. for(f = 1; f <= NSIG; f++)
  2559. SETSIG(sa, f, SIG_IGN, SA_RESTART);
  2560. }
  2561.  
  2562. SETSIG(sa, SIGALRM, signal_handler, 0);
  2563. SETSIG(sa, SIGHUP, signal_handler, 0);
  2564. SETSIG(sa, SIGINT, signal_handler, 0);
  2565. SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
  2566. SETSIG(sa, SIGPWR, signal_handler, 0);
  2567. SETSIG(sa, SIGWINCH, signal_handler, 0);
  2568. SETSIG(sa, SIGUSR1, signal_handler, 0);
  2569. SETSIG(sa, SIGSTOP, stop_handler, SA_RESTART);
  2570. SETSIG(sa, SIGTSTP, stop_handler, SA_RESTART);
  2571. SETSIG(sa, SIGCONT, cont_handler, SA_RESTART);
  2572. SETSIG(sa, SIGSEGV, (void (*)(int))segv_handler, SA_RESTART);
  2573.  
  2574. console_init();
  2575.  
  2576. if (!reload) {
  2577. int fd;
  2578.  
  2579. /* Close whatever files are open, and reset the console. */
  2580. close(0);
  2581. close(1);
  2582. close(2);
  2583. console_stty();
  2584. setsid();
  2585.  
  2586. /*
  2587. * Set default PATH variable.
  2588. */
  2589. setenv("PATH", PATH_DEFAULT, 1 /* Overwrite */);
  2590.  
  2591. /*
  2592. * Initialize /var/run/utmp (only works if /var is on
  2593. * root and mounted rw)
  2594. */
  2595. if ((fd = open(UTMP_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0644)) >= 0)
  2596. close(fd);
  2597.  
  2598. /*
  2599. * Say hello to the world
  2600. */
  2601. initlog(L_CO, bootmsg, "booting");
  2602.  
  2603. /*
  2604. * See if we have to start an emergency shell.
  2605. */
  2606. if (emerg_shell) {
  2607. pid_t rc;
  2608. SETSIG(sa, SIGCHLD, SIG_DFL, SA_RESTART);
  2609. if (spawn(&ch_emerg, &f) > 0) {
  2610. while((rc = wait(&st)) != f)
  2611. if (rc < 0 && errno == ECHILD)
  2612. break;
  2613. }
  2614. SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
  2615. }
  2616.  
  2617. /*
  2618. * Start normal boot procedure.
  2619. */
  2620. runlevel = '#';
  2621. read_inittab();
  2622.  
  2623. } else {
  2624. /*
  2625. * Restart: unblock signals and let the show go on
  2626. */
  2627. initlog(L_CO, bootmsg, "reloading");
  2628. sigfillset(&sgt);
  2629. sigprocmask(SIG_UNBLOCK, &sgt, NULL);
  2630.  
  2631. /*
  2632. * Set default PATH variable.
  2633. */
  2634. setenv("PATH", PATH_DEFAULT, 0 /* Don't overwrite */);
  2635. }
  2636. start_if_needed();
  2637.  
  2638. while(1) {
  2639.  
  2640. /* See if we need to make the boot transitions. */
  2641. boot_transitions();
  2642. INITDBG(L_VB, "init_main: waiting..");
  2643.  
  2644. /* Check if there are processes to be waited on. */
  2645. for(ch = family; ch; ch = ch->next)
  2646. if ((ch->flags & RUNNING) && ch->action != BOOT) break;
  2647.  
  2648. #if CHANGE_WAIT
  2649. /* Wait until we get hit by some signal. */
  2650. while (ch != NULL && got_signals == 0) {
  2651. if (ISMEMBER(got_signals, SIGHUP)) {
  2652. /* See if there are processes to be waited on. */
  2653. for(ch = family; ch; ch = ch->next)
  2654. if (ch->flags & WAITING) break;
  2655. }
  2656. if (ch != NULL) check_init_fifo();
  2657. }
  2658. #else /* CHANGE_WAIT */
  2659. if (ch != NULL && got_signals == 0) check_init_fifo();
  2660. #endif /* CHANGE_WAIT */
  2661.  
  2662. /* Check the 'failing' flags */
  2663. fail_check();
  2664.  
  2665. /* Process any signals. */
  2666. process_signals();
  2667.  
  2668. /* See what we need to start up (again) */
  2669. start_if_needed();
  2670. }
  2671. /*NOTREACHED*/
  2672. }
  2673.  
  2674. /*
  2675. * Tell the user about the syntax we expect.
  2676. */
  2677. static
  2678. void usage(char *s)
  2679. {
  2680. fprintf(stderr, "Usage: %s {-e VAR[=VAL] | [-t SECONDS] {0|1|2|3|4|5|6|S|s|Q|q|A|a|B|b|C|c|U|u}}\n", s);
  2681. exit(1);
  2682. }
  2683.  
  2684. static
  2685. int telinit(char *progname, int argc, char **argv)
  2686. {
  2687. #ifdef TELINIT_USES_INITLVL
  2688. FILE *fp;
  2689. #endif
  2690. struct init_request request;
  2691. struct sigaction sa;
  2692. int f, fd, l;
  2693. char *env = NULL;
  2694.  
  2695. memset(&request, 0, sizeof(request));
  2696. request.magic = INIT_MAGIC;
  2697.  
  2698. while ((f = getopt(argc, argv, "t:e:")) != EOF) switch(f) {
  2699. case 't':
  2700. sltime = atoi(optarg);
  2701. break;
  2702. case 'e':
  2703. if (env == NULL)
  2704. env = request.i.data;
  2705. l = strlen(optarg);
  2706. if (env + l + 2 > request.i.data + sizeof(request.i.data)) {
  2707. fprintf(stderr, "%s: -e option data "
  2708. "too large\n", progname);
  2709. exit(1);
  2710. }
  2711. memcpy(env, optarg, l);
  2712. env += l;
  2713. *env++ = 0;
  2714. break;
  2715. default:
  2716. usage(progname);
  2717. break;
  2718. }
  2719.  
  2720. if (env) *env++ = 0;
  2721.  
  2722. if (env) {
  2723. if (argc != optind)
  2724. usage(progname);
  2725. request.cmd = INIT_CMD_SETENV;
  2726. } else {
  2727. if (argc - optind != 1 || strlen(argv[optind]) != 1)
  2728. usage(progname);
  2729. if (!strchr("0123456789SsQqAaBbCcUu", argv[optind][0]))
  2730. usage(progname);
  2731. request.cmd = INIT_CMD_RUNLVL;
  2732. request.runlevel = env ? 0 : argv[optind][0];
  2733. request.sleeptime = sltime;
  2734. }
  2735.  
  2736. /* Change to the root directory. */
  2737. chdir("/");
  2738.  
  2739. /* Open the fifo and write a command. */
  2740. /* Make sure we don't hang on opening /dev/initctl */
  2741. SETSIG(sa, SIGALRM, signal_handler, 0);
  2742. alarm(3);
  2743. if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) {
  2744. ssize_t p = 0;
  2745. size_t s = sizeof(request);
  2746. void *ptr = &request;
  2747.  
  2748. while (s > 0) {
  2749. p = write(fd, ptr, s);
  2750. if (p < 0) {
  2751. if (errno == EINTR || errno == EAGAIN)
  2752. continue;
  2753. break;
  2754. }
  2755. ptr += p;
  2756. s -= p;
  2757. }
  2758. close(fd);
  2759. alarm(0);
  2760. return 0;
  2761. }
  2762.  
  2763. #ifdef TELINIT_USES_INITLVL
  2764. if (request.cmd == INIT_CMD_RUNLVL) {
  2765. /* Fallthrough to the old method. */
  2766.  
  2767. /* Now write the new runlevel. */
  2768. if ((fp = fopen(INITLVL, "w")) == NULL) {
  2769. fprintf(stderr, "%s: cannot create %s\n",
  2770. progname, INITLVL);
  2771. exit(1);
  2772. }
  2773. fprintf(fp, "%s %d", argv[optind], sltime);
  2774. fclose(fp);
  2775.  
  2776. /* And tell init about the pending runlevel change. */
  2777. if (kill(INITPID, SIGHUP) < 0) perror(progname);
  2778.  
  2779. return 0;
  2780. }
  2781. #endif
  2782.  
  2783. fprintf(stderr, "%s: ", progname);
  2784. if (ISMEMBER(got_signals, SIGALRM)) {
  2785. fprintf(stderr, "timeout opening/writing control channel %s\n",
  2786. INIT_FIFO);
  2787. } else {
  2788. perror(INIT_FIFO);
  2789. }
  2790. return 1;
  2791. }
  2792.  
  2793. /*
  2794. * Main entry for init and telinit.
  2795. */
  2796. int main(int argc, char **argv)
  2797. {
  2798. char *p;
  2799. int f;
  2800. int isinit;
  2801. #ifdef WITH_SELINUX
  2802. int enforce = 0;
  2803. #endif
  2804.  
  2805. /* Get my own name */
  2806. if ((p = strrchr(argv[0], '/')) != NULL)
  2807. p++;
  2808. else
  2809. p = argv[0];
  2810.  
  2811. /* Common umask */
  2812. umask(022);
  2813.  
  2814. /* Quick check */
  2815. if (geteuid() != 0) {
  2816. fprintf(stderr, "%s: must be superuser.\n", p);
  2817. exit(1);
  2818. }
  2819.  
  2820. /*
  2821. * Is this telinit or init ?
  2822. */
  2823. isinit = (getpid() == 1);
  2824. for (f = 1; f < argc; f++) {
  2825. if (!strcmp(argv[f], "-i") || !strcmp(argv[f], "--init")) {
  2826. isinit = 1;
  2827. break;
  2828. }
  2829. }
  2830. if (!isinit) exit(telinit(p, argc, argv));
  2831.  
  2832. /*
  2833. * Check for re-exec
  2834. */
  2835. if (check_pipe(STATE_PIPE)) {
  2836.  
  2837. receive_state(STATE_PIPE);
  2838.  
  2839. myname = istrdup(argv[0]);
  2840. argv0 = argv[0];
  2841. maxproclen = 0;
  2842. for (f = 0; f < argc; f++)
  2843. maxproclen += strlen(argv[f]) + 1;
  2844. reload = 1;
  2845. setproctitle("init [%c]", (int)runlevel);
  2846.  
  2847. init_main();
  2848. }
  2849.  
  2850. /* Check command line arguments */
  2851. maxproclen = strlen(argv[0]) + 1;
  2852. for(f = 1; f < argc; f++) {
  2853. if (!strcmp(argv[f], "single") || !strcmp(argv[f], "-s"))
  2854. dfl_level = 'S';
  2855. else if (!strcmp(argv[f], "-a") || !strcmp(argv[f], "auto"))
  2856. putenv("AUTOBOOT=YES");
  2857. else if (!strcmp(argv[f], "-b") || !strcmp(argv[f],"emergency"))
  2858. emerg_shell = 1;
  2859. else if (!strcmp(argv[f], "-z")) {
  2860. /* Ignore -z xxx */
  2861. if (argv[f + 1]) f++;
  2862. } else if (strchr("0123456789sS", argv[f][0])
  2863. && strlen(argv[f]) == 1)
  2864. dfl_level = argv[f][0];
  2865. /* "init u" in the very beginning makes no sense */
  2866. if (dfl_level == 's') dfl_level = 'S';
  2867. maxproclen += strlen(argv[f]) + 1;
  2868. }
  2869.  
  2870. #ifdef WITH_SELINUX
  2871. if (getenv("SELINUX_INIT") == NULL) {
  2872. const int rc = mount("proc", "/proc", "proc", 0, 0);
  2873. if (is_selinux_enabled() > 0) {
  2874. putenv("SELINUX_INIT=YES");
  2875. if (rc == 0) umount2("/proc", MNT_DETACH);
  2876. if (selinux_init_load_policy(&enforce) == 0) {
  2877. execv(myname, argv);
  2878. } else {
  2879. if (enforce > 0) {
  2880. /* SELinux in enforcing mode but load_policy failed */
  2881. /* At this point, we probably can't open /dev/console, so log() won't work */
  2882. fprintf(stderr,"Unable to load SELinux Policy. Machine is in enforcing mode. Halting now.\n");
  2883. exit(1);
  2884. }
  2885. }
  2886. }
  2887. if (rc == 0) umount2("/proc", MNT_DETACH);
  2888. }
  2889. #endif
  2890. /* Start booting. */
  2891. argv0 = argv[0];
  2892. argv[1] = NULL;
  2893. setproctitle("init boot");
  2894. init_main();
  2895.  
  2896. /*NOTREACHED*/
  2897. return 0;
  2898. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement