/* * einit-feedbackd-fbsplash.c * einit-extras: feedback * * Created by Joshua Keyes on 04/04/2008. * Copyright 2008 Joshua Keyes. All rights reserved. * */#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 */struct fbspl_theme *fbsplash_theme = NULL;pid_t fbsplashd_pid = 0;pid_t fbsplashmod_pid = 0;/* ================== eINIT_WritePidFile ================== Writes a pid file for this module. @param: none*/int eINIT_WritePidFile(void){ FILE *fp = NULL; fp = fopen(PIDFILE, "w"); if(fp<0){ perror("eINIT_WritePidFile:"); return -1; } fbsplashmod_pid = getpid(); fprintf(fp,"%d", fbsplashmod_pid); fclose(fp); return 0;}/* ============== eINIT_Connect ============== Connects to the eINIT daemon. @param: argc, argv*/int eINIT_Connect( int argc, char **argv ) { char *path = getenv("PATH"); if (path) { einit_global_environment = straddtoenviron (einit_global_environment, "PATH", path); } 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"); return -1; } } return 0;}/* =============== fbsplashd_Init =============== Starts fbsplashd during boot sequence. @param: ev (struct einit_event *)*/void fbsplashd_Init(struct einit_event *ev) { pid_t child; if((fbsplash_check_sanity())<0) { return; } child = fork(); setenv("TMPDIR", "/lib/splash/tmp", 1); char *d_argv[] = { FBSPLASH_DAEMON, NULL }; if(child<0) { perror("fbsplashd_Init:"); return; } else if(child>=0) { execv( FBSPLASH_DAEMON, d_argv); _exit(EXIT_FAILURE); } return; }/* =============== fbsplashd_Init =============== Starts fbsplashd during boot sequence. @param: ev (struct einit_event *)*/void fbsplashd_UpdateProgress(struct einit_event *ev) { fbsplashr_progress_set( fbsplash_theme, ev->integer ); }/* =============== fbsplashd_SystemAtDefault =============== Kills this einit module once "default" is reached. @param: ev (struct einit_event *)*/void fbsplashd_SystemAtDefault(struct einit_event *ev) { if (strmatch(ev->string, "default")) { /* terminate the usplash daemon once we reach the default mode */ if (fbsplashmod_pid) { kill(SIGTERM, fbsplashmod_pid); } } einit_disconnect(); exit(EXIT_SUCCESS);}/* ====== main ====== Do I really need to explain it? @param: ( -.-')*/int main(int argc, char **argv) { /* daemonize and detach */ if ((daemon(0,0))<0) { perror("daemonization failed!"); return EXIT_FAILURE; } /* store pid */ if((eINIT_WritePidFile())<0) { return EXIT_FAILURE; } /* connect to einit */ if((eINIT_Connect(argc,argv))<0) { return EXIT_FAILURE; } /* At boot we listen for kernel module loading so as to know when to start fbsplashd. This is safe because einit_boot_load_kernel_extensions is only called once during the start of udev. */ event_listen(einit_boot_load_kernel_extensions, fbsplashd_Init); /* During service initalization, einit_feedback_switch_progress updates the percentage in ev->integer to represent the total system bootup completion as a 0 to 100 scale. Makes updating the progress indicator a sinch. */ event_listen(einit_feedback_switch_progress, fbsplashd_UpdateProgress); /* When the system reaches the "default" level it is said to be fully operational. Therefore, we listen for an event on einit_core_mode_switch_done for ev->string being "default". This signals us to update the progress counter to full, and nuke this daemon. */ event_listen(einit_feedback_switch_progress, fbsplashd_SystemAtDefault); einit_event_loop(); einit_disconnect(); return EXIT_SUCCESS; }/* ------------------- |ooooooooooooooooo| |ooooooooooooooooo| <------------^ |oo|===========|oo| | |oo|===========|oo| The 486 sitting |oo|===========|oo| on my desk requires |oo|===========|oo| this tribute. |oo|===========|oo| |oo|===========|oo| |ooooooooooooooooo| |ooooooooooooooooo| -------------------*/