/* Komentarze po polsku - Marcin Mędelski-Guz */
/*

 *  linux/fs/binfmt_script.c

 *

 *  Copyright (C) 1996  Martin von Löwis

 *  original #!-checking implemented by tytso.

 */
 
 

#include <linux/module.h>

#include <linux/string.h>

#include <linux/stat.h>

#include <linux/malloc.h>

#include <linux/binfmts.h>
 
 
 
 
 

static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)

{

 char *cp, *interp, *i_name, *i_arg;

 int retval;

 if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang))

  return -ENOEXEC;

// Koniec gdy brak #! lub gdy uruchamiany proces sam ma być interpreterem dla innego (sh_bang)

 /*

  * This section does the #! interpretation.

  * Sorta complicated, but hopefully it will work.  -TYT

  */
 
 

 bprm->sh_bang++;

 iput(bprm->inode);

 bprm->dont_iput=1;
 

 /* Buf zawiera poczštek pliku. Przerabiamy go na null-term. string. */
 bprm->buf[127] = '\0';

 /* jeśli buf zawiera znak końca wiersza, to jest skracany.  */
                /*(wybieramy pierwszy wiersz z pliku) */
 /* jeśli nie, to wstawiamy NULL na koniec bufora */
 
 if ((cp = strchr(bprm->buf, '\n')) == NULL)

  cp = bprm->buf+127;

 *cp = '\0';

 while (cp > bprm->buf) { /*ucinamy spacje i znaki "tab" z końća wiersza */

  cp--;

  if ((*cp == ' ') || (*cp == '\t'))

   *cp = '\0';

  else

   break;

 }

 /*ucięcie spacji i znaków "tab" z poczštku wiersza */
 for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);

 if (!cp || *cp == '\0')

  return -ENOEXEC; /* No interpreter name found */
                /*cišg pusty => powróć z błędem */
 
 interp = i_name = cp; /*zapamiętaj nazwę interpretatora */

 i_arg = 0;

 for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {

   if (*cp == '/') /*teraz ucinamy scieżkę dostępu  z nazwy */

   i_name = cp+1;

 }

 while ((*cp == ' ') || (*cp == '\t')) /*teraz znowu wycinamy spacje na poczštku */

  *cp++ = '\0';

 if (*cp) /*jeśli coś zostało, to jest to argument dla interpretatora */

  i_arg = cp;

 /*

  * OK, we've parsed out the interpreter name and

  * (optional) argument.

  * Splice in (1) the interpreter's name for argv[0]

  *           (2) (optional) argument to interpreter

  *           (3) filename of shell script (replace argv[0])

  *

  * This is done in reverse order, because of how the

  * user environment and arguments are stored.

  */

 remove_arg_zero(bprm); /*wyrzucamy starš nazwę programu */
               /*na liście "p" sš przechowywane kolejno - środowisko, parametry (w odwrotnej   kolejności) i argv[0] */

 bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
                /* dodajemy nazwę naszego pliku jako argument dla interpretatora */
 /* dwójka przy copy_strings oznacza, że kopiowanie jest w obszarze jšdra */
 bprm->argc++;

 if (i_arg) { /* teraz pozostałe parametry */

  bprm->p = copy_strings(1, &i_arg, bprm->page, bprm->p, 2);

  bprm->argc++;

 }

 bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);

 bprm->argc++;/* na końcu nazwa interpretatora */

 if (!bprm->p)

  return -E2BIG;

 /*

  * OK, now restart the process with the interpreter's inode.

  * Note that we use open_namei() as the name is now in kernel

  * space, and we don't need to copy it.

  */

 retval = open_namei(interp, 0, 0, &bprm->inode, NULL); /* otwieramy nowy i-węzeł */

 if (retval)

  return retval;

 bprm->dont_iput=0;

 retval=prepare_binprm(bprm); /* dokańczamy budowanie nowej struktury bprm */

 if(retval<0)

  return retval;

 return search_binary_handler(bprm,regs); /* próbujemy uruchomić interpretator (rekursja) */

}
 
 
 
 
 

static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)

{

 int retval;

 MOD_INC_USE_COUNT;

 retval = do_load_script(bprm,regs);

 MOD_DEC_USE_COUNT;

 return retval;

}
 
 
 
 
 

struct linux_binfmt script_format = {

#ifndef MODULE

 NULL, 0, load_script, NULL, NULL

#else

 NULL, &mod_use_count_, load_script, NULL, NULL

#endif

};
 
 
 
 
 

int init_script_binfmt(void) {

 return register_binfmt(&script_format);

}
 
 
 
 
 

#ifdef MODULE

int init_module(void)

{

 return init_script_binfmt();

}
 
 
 
 
 

void cleanup_module( void) {

 unregister_binfmt(&script_format);

}

#endif