140 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
		
		
			
		
	
	
			140 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| 
								 | 
							
								/* 
							 | 
						||
| 
								 | 
							
								 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
							 | 
						||
| 
								 | 
							
								 * run_svc
							 | 
						||
| 
								 | 
							
								 * part of cinit
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <unistd.h>
							 | 
						||
| 
								 | 
							
								#include <sys/types.h>
							 | 
						||
| 
								 | 
							
								#include <sys/stat.h>
							 | 
						||
| 
								 | 
							
								#include <string.h>
							 | 
						||
| 
								 | 
							
								#include <fcntl.h>
							 | 
						||
| 
								 | 
							
								#include <sys/wait.h>
							 | 
						||
| 
								 | 
							
								#include <limits.h>
							 | 
						||
| 
								 | 
							
								#include <stdlib.h>
							 | 
						||
| 
								 | 
							
								#include <errno.h>
							 | 
						||
| 
								 | 
							
								#include <dirent.h>
							 | 
						||
| 
								 | 
							
								#include <sys/socket.h>
							 | 
						||
| 
								 | 
							
								#include <sys/un.h>
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#include <fcntl.h>
							 | 
						||
| 
								 | 
							
								#include <errno.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "cinit.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Run a service */
							 | 
						||
| 
								 | 
							
								/* We _MUST_ return!!! */
							 | 
						||
| 
								 | 
							
								int run_svc(char *rpath)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   int tmp, sid;
							 | 
						||
| 
								 | 
							
								   char abspath[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp = use-it-for-all bitch*/
							 | 
						||
| 
								 | 
							
								   struct stat buf;
							 | 
						||
| 
								 | 
							
								   struct sockaddr_un addr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   D_PRINTF("starte run_svc");
							 | 
						||
| 
								 | 
							
								   D_PRINTF(rpath);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   /******************* begin socket *********************/
							 | 
						||
| 
								 | 
							
								   close(sock); /* close old socket connection, we are a fork()! */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   sock = socket(PF_UNIX,SOCK_STREAM,0);
							 | 
						||
| 
								 | 
							
								   if( sock == -1 ) {
							 | 
						||
| 
								 | 
							
								      perror("socket");
							 | 
						||
| 
								 | 
							
								      return 0;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   tmp = sizeof(addr);
							 | 
						||
| 
								 | 
							
								   memset(&addr,0,tmp);
							 | 
						||
| 
								 | 
							
								   strcpy(addr.sun_path, CINIT_SOCK);
							 | 
						||
| 
								 | 
							
								   addr.sun_family   = AF_UNIX;
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   /* FIXME: why do we need tmp????? ... tmp == 1 is wrong!*/
							 | 
						||
| 
								 | 
							
								/*   tmp = 1;
							 | 
						||
| 
								 | 
							
								   if(setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &tmp, sizeof(tmp)) == -1) {
							 | 
						||
| 
								 | 
							
								      perror("passcred");
							 | 
						||
| 
								 | 
							
								      return 0;
							 | 
						||
| 
								 | 
							
								   } */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   if(connect(sock,(struct sockaddr *)&addr,tmp) == -1) {
							 | 
						||
| 
								 | 
							
								      perror("connect");
							 | 
						||
| 
								 | 
							
								      return 0;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   /******************* absolute PATH ***************/
							 | 
						||
| 
								 | 
							
								   /* get current working dir */
							 | 
						||
| 
								 | 
							
								   if(! (int) getcwd(pathtmp,PATH_MAX)) {
							 | 
						||
| 
								 | 
							
								      perror("getcwd");
							 | 
						||
| 
								 | 
							
								      return 0;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   /* change to rpath */
							 | 
						||
| 
								 | 
							
								   if(chdir(rpath) == -1) {
							 | 
						||
| 
								 | 
							
								      perror("chdir");
							 | 
						||
| 
								 | 
							
								      return 0;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   /* get absolute name of rpath */
							 | 
						||
| 
								 | 
							
								   if(! (int) getcwd(abspath,PATH_MAX)) {
							 | 
						||
| 
								 | 
							
								      perror("getcwd2");
							 | 
						||
| 
								 | 
							
								      return 0;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   /* change back */
							 | 
						||
| 
								 | 
							
								   if(chdir(pathtmp) == -1) {
							 | 
						||
| 
								 | 
							
								      perror("chdir2");
							 | 
						||
| 
								 | 
							
								      return 0;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   /******************* REGISTER SERVICE ***************/
							 | 
						||
| 
								 | 
							
								   D_PRINTF(abspath);
							 | 
						||
| 
								 | 
							
								   tmp = msg_start_svc(abspath);    /* mark us as temporary */
							 | 
						||
| 
								 | 
							
								   if(tmp == -1) return 1;          /* already started */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   /******************* BEGIN DEPENDENCIES ***************/
							 | 
						||
| 
								 | 
							
								   D_PRINTF("Starte needs");
							 | 
						||
| 
								 | 
							
								   strcpy(pathtmp,abspath);
							 | 
						||
| 
								 | 
							
								   strcat(pathtmp,"/");
							 | 
						||
| 
								 | 
							
								   strcat(pathtmp,C_NEEDS);
							 | 
						||
| 
								 | 
							
								   if( ! run_run_svcs(pathtmp) ) {
							 | 
						||
| 
								 | 
							
								      D_PRINTF("some NEEDED services failed)");
							 | 
						||
| 
								 | 
							
								      return 0;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   D_PRINTF("Starte wants");
							 | 
						||
| 
								 | 
							
								   strcpy(pathtmp,abspath);
							 | 
						||
| 
								 | 
							
								   strcat(pathtmp,"/");
							 | 
						||
| 
								 | 
							
								   strcat(pathtmp,C_WANTS);
							 | 
						||
| 
								 | 
							
								   run_run_svcs(pathtmp);  /* don't care about what happens with the want svc */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   /******************* execute services ***************/
							 | 
						||
| 
								 | 
							
								   strcpy(pathtmp,abspath);
							 | 
						||
| 
								 | 
							
								   strcat(pathtmp,"/");
							 | 
						||
| 
								 | 
							
								   strcat(pathtmp,C_RESPAWN);
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								   tmp = ST_ONCE;
							 | 
						||
| 
								 | 
							
								   sid = 20;
							 | 
						||
| 
								 | 
							
								   D_PRINTF("Melde status");
							 | 
						||
| 
								 | 
							
								   if(!do_change_status(abspath,&tmp,&sid,sock,ACT_WRITE)) {
							 | 
						||
| 
								 | 
							
								      D_PRINTF("Status nicht gemeldet :(((((((((((");
							 | 
						||
| 
								 | 
							
								      return 0;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   D_PRINTF("Status abgesetzt");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*   if( stat(pathtmp,&buf) == 0) {
							 | 
						||
| 
								 | 
							
								      D_PRINTF("Respawn, ja das werden wir tun");
							 | 
						||
| 
								 | 
							
								      if(respawn_svc(abspath)) {
							 | 
						||
| 
								 | 
							
								         msg_change_status(sid,ST_RESPAWN);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								         D_PRINTF("error in respawn");
							 | 
						||
| 
								 | 
							
								         msg_change_status(sid,ST_FAIL);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								   } else {
							 | 
						||
| 
								 | 
							
								      D_PRINTF("einmal ausfuehren");
							 | 
						||
| 
								 | 
							
								      if(exec_svc(abspath)) {
							 | 
						||
| 
								 | 
							
								         msg_change_status(sid,ST_ONCE);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								         D_PRINTF("error einmalig");
							 | 
						||
| 
								 | 
							
								         msg_change_status(sid,ST_FAIL);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								   } */
							 | 
						||
| 
								 | 
							
								}
							 |