/* * einit-feedbackd-fbsplash.c * einit-extras: feedback * * Created by Joshua Keyes on 04/04/2008. * Copyright 2008 Joshua Keyes. All rights reserved. * *//*Copyright (c) 2008, Joshua Keyes.All rights reserved.Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ANDANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FORANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ONANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/#include <unistd.h>#include <stdio.h>#include <stdbool.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <signal.h>#include <linux/kd.h>#include <linux/input.h>#include <fbsplash.h>#include <einit/einit.h>#define PIDFILE "/dev/einit-feedbackd-fbsplash.pid"/* Globals */char *fbsplash_fifo = FBSPLASH_FIFO;struct fbspl_theme *fbsplash_theme = NULL;pid_t daemon_pid = 0;/*FILE *debuglog = NULL;*//* help function */void help (char **argv) { printf ("Usage: %s [options]\n", argv[0]);}/* progress helper here V V */void fbsplash_progress (struct einit_event *ev) { fbsplashr_progress_set ( fbsplash_theme, ev->integer ); }/* default mode level handler here V V */void fbsplash_switch_done (struct einit_event *ev) { if (strmatch (ev->string, "default")) { /* terminate the usplash daemon once we reach the default mode */ if (daemon_pid) { kill (SIGTERM, daemon_pid); } } einit_disconnect(); exit (EXIT_SUCCESS);}/* fbsplashd daemon helper here V V */char invoke_daemon (const char *daemon, char **argv) { pid_t p = fork(); if(p>=0) { switch (p) { case -1: return 0; case 0: execv (daemon, argv); _exit(EXIT_FAILURE); return 0; default: daemon_pid = p; return p; } } return 0;}int invoke_fbsplash(void) { pid_t fbsplashd_pid = 0; setenv ("TMPDIR", "/lib/splash/tmp", 1); if((fbsplashr_init(true))<0) { return -1; } if((fbsplash_check_sanity())<0) { return -1; } fbsplash_check_daemon(&fbsplashd_pid); fbsplash_theme = fbsplashr_theme_load(); char *fbsplash_argv[] = { "fbsplash.static", NULL }; return invoke_daemon ( FBSPLASH_DAEMON, fbsplash_argv);}/* main */int main(int argc, char **argv, char **env) { int i = 1; for (; argv[i]; i++) { help(argv); return EXIT_FAILURE; } /* sets einit global environment */ char *path = getenv ("PATH"); if (path) { einit_global_environment = straddtoenviron (einit_global_environment, "PATH", path); } /* start fbsplash and fork */ if ((invoke_fbsplash())<0) { perror ("fbsplash invocation failed!"); return EXIT_FAILURE; } /* daemonize and detach */ if ((daemon(0,0))<0) { perror ("daemonization failed!"); return EXIT_FAILURE; } /* write pid file */ FILE *pidfile = fopen (PIDFILE, "w"); if (pidfile) { fprintf (pidfile, "%d\n", getpid()); fclose (pidfile); } /* attempt to connect to eINIT */ if ((einit_connect (&argc, argv))<0) { perror("Could not connect to eINIT"); sleep(1); if ((einit_connect (&argc, argv))<0) { perror ("Could not connect to eINIT, giving up"); exit (EXIT_FAILURE); } } event_listen (einit_feedback_switch_progress, fbsplash_progress); event_listen (einit_core_mode_switch_done, fbsplash_switch_done); fbsplashr_theme_free( fbsplash_theme ); fbsplashr_cleanup(); einit_event_loop(); einit_disconnect(); return EXIT_SUCCESS; }