/* vi: set sw=4 ts=4: */
/*
 * Mini run-parts implementation for busybox
 *
 *
 * Copyright (C) 2001 by Emanuele Aina <emanuele.aina@tiscali.it>
 *
 * Based on the Debian run-parts program, version 1.15
 *   Copyright (C) 1996 Jeff Noxon <jeff@router.patch.net>,
 *   Copyright (C) 1996-1999 Guy Maor <maor@debian.org>
 *   
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 * 02111-1307 USA
 *
 */

/* This is my first attempt to write a program in C (well, this is my first
 * attempt to write a program! :-) . */

/* This piece of code is heavily based on the original version of run-parts,
 * taken from debian-utils. I've only removed the long options and a the 
 * report mode. As the original run-parts support only long options, I've
 * broken compatibility because the BusyBox policy doesn't allow them. 
 * The supported options are: 
 * -t			test. Print the name of the files to be executed, without
 * 				execute them.
 * -a ARG		argument. Pass ARG as an argument the program executed. It can 
 * 				be repeated to pass multiple arguments.
 * -u MASK 		umask. Set the umask of the program executed to MASK. */

/* TODO 
 * done - convert calls to error in perror... and remove error()
 * done - convert malloc/realloc to their x... counterparts 
 * done - remove catch_sigchld
 * use bb's isdirectory() ? It seems that no applet use it.
 * done - use bb's concat_path_file() 
 * declare run_parts_main() as extern and any other function as static? */

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
/* #include <sys/types.h> */
#include <sys/wait.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
/* #include <signal.h>
   #include <sys/time.h> */

#include "busybox.h"

int test_mode = 0;
int verbose_mode = 0;
int exitstatus = 0;

int argcount = 0, argsize = 0;
char **args = 0;


/* set_umask */
/* Check and set the umask of the program executed. As stated in the original
 * run-parts, the octal conversion in libc is not foolproof; it will take the 
 * 8 and 9 digits under some circumstances. We'll just have to live with it.
 */

void set_umask (void)
{
  int mask, result;

  /*TODO
   * We must substitute sscanf, according to bb's style guide? */
  result = sscanf (optarg, "%o", &mask);
  if ((result != 1) || (mask > 07777) || (mask < 0)) {
	  perror_msg_and_die ("bad umask value");
  }

  umask (mask);
}

/* add_argument */
/* Add an argument to the commands that we will call. Called once for
   every argument. */
void add_argument (char *newarg)
{
  if (argcount+1 >= argsize) {
    argsize = argsize ? argsize*2 : 4;
	/*TODO if we convert to xrealloc we lose the verbose error message */
	args = realloc(args, argsize * (sizeof(char*)));
    if (!args) {
		perror_msg_and_die ("failed to reallocate memory for arguments: %s", strerror(errno));
	}
  }
  args[argcount++] = newarg;
  args[argcount] = 0;
}

/* valid_name */
/* True or false? Is this a valid filename (upper/lower alpha, digits,
 * underscores, and hyphens only?)
 */

int valid_name (const struct dirent *d)
{
	char *c = d->d_name;
	while (*c) {
		if (!isalnum(*c) && *c!='_' && *c!='-') {
			return 0;
		}
		++c;
	}
	return 1;
}


/* run_part */
/* Execute a file */

void run_part (char *progname)
{
  int result;
  int pid;

  
  if ((pid=fork()) < 0) {
    perror_msg_and_die ("failed to fork: %s", strerror(errno));
  }
  else if (!pid) {
    args[0] = progname;
    execv (progname, args);
    perror_msg_and_die ("failed to exec %s: %s", progname, strerror (errno));
  }

  if (0) {
		  
  } else {
		  
		  waitpid(pid, &result, 0);
  }

  if (WIFEXITED (result) && WEXITSTATUS(result)) {
		  perror_msg ("%s exited with return code %d", progname, WEXITSTATUS(result));
		  exitstatus = 1;
  }
  else if (WIFSIGNALED (result)) {
		  perror_msg ("%s exited because of uncaught signal %d", progname,
						  WTERMSIG(result));
		  exitstatus = 1;
  }
}

/* run_parts */
/* Find the parts to run & call run_part() */

void run_parts (char *dir_name)
{
  struct dirent **namelist;
  char *filename = NULL;
  size_t filename_length, dir_name_length;
  int entries, i, result;
  struct stat st;

  /* dir_name + "/" */
  dir_name_length = strlen(dir_name) + 1;
  
  /* dir_name + "/" + ".." + "\0" (This will save one realloc.) */
  filename_length = dir_name_length + 2 + 1;

  /* --
   * Removed this part because I want try to use concat_path_file() */
  
/*  if (! (filename = malloc(filename_length))) {
    error ("failed to allocate memory for path: %s", strerror(errno));
    exit (1);
  } */

  /* -- */
  
  /* scandir() isn't POSIX, but it makes things easy. */
  entries = scandir (dir_name, &namelist, valid_name, alphasort);

  if (entries < 0) {
    perror_msg_and_die ("failed to open directory %s: %s", dir_name, strerror (errno));
  }
  
  for (i = 0; i < entries; i++) {

	  /* -- 
	   * Removed this part because I want try to use concat_path_file() */
	  
	  /* if (filename_length < dir_name_length + strlen(namelist[i]->d_name) + 1) {
		  filename_length = dir_name_length + strlen(namelist[i]->d_name) + 1;
		  if (!(filename = realloc(filename, filename_length))) {
			  error ("failed to reallocate memory for path: %s", strerror(errno));
			  exit (1);
			  }
		  }
		  
		*/

	  /* -- */
	  
	  
	  /* --
	   * Removed for concat_path_file() */
	  
/*	  strcpy (filename, dir_name); 
	  strcat (filename, "/"); 
	  strcat (filename, namelist[i]->d_name); */

	  /* -- */

	  filename = concat_path_file (dir_name, namelist[i]->d_name);
	  
	  result = stat (filename, &st);
	  if (result < 0) {
		  perror_msg_and_die ("failed to stat component %s: %s", filename,
				  strerror (errno));
	  }
	  if (S_ISREG(st.st_mode) && !access (filename, X_OK)) {
		  if (test_mode)
			  printf ("run-parts would run %s\n", filename);
		  else {
			  run_part (filename);
		  }
	  }
	  /*TODO convert to isdirectory() */
	  else if (!S_ISDIR(st.st_mode)) {
		  printf ("run-parts: component %s is not an executable plain file\n",
				  filename);
		  exitstatus = 1;
	  }
	  
	  free (namelist[i]);
  }
  free (namelist);
  free (filename);
}

/* run_parts_main */
/* Process options */
int run_parts_main (int argc, char *argv[])
{
  umask (022);
  add_argument(0);
  
  for (;;) {
    int c;

    opterr = 0;
    c = getopt(argc, argv, "tu:a:");
	
    if (c == EOF)
      break;
    switch (c) {
	case 't':               /* Enable test mode */
		test_mode = 1;
		break;			
	case 'u':               /* Set the umask of the programs executed */
		set_umask ();
		break;
    case 'a':               /* Pass an argument to the programs */
		add_argument (optarg);
		break;
    default:
		show_usage();
    }
  }
  
  /* We require exactly one argument: the directory name */
  if (optind != (argc - 1)) {
	  show_usage();
  }

  run_parts (argv[optind]);

  return exitstatus;
}
