linux-old/fs/binfmt_script.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/binfmt_script.c
   3 *
   4 *  Copyright (C) 1996  Martin von Löwis
   5 *  original #!-checking implemented by tytso.
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/string.h>
  10#include <linux/stat.h>
  11#include <linux/malloc.h>
  12#include <linux/binfmts.h>
  13#include <linux/init.h>
  14
  15static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
  16{
  17        char *cp, *i_name, *i_name_start, *i_arg;
  18        struct dentry * dentry;
  19        char interp[128];
  20        int retval;
  21
  22        if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) 
  23                return -ENOEXEC;
  24        /*
  25         * This section does the #! interpretation.
  26         * Sorta complicated, but hopefully it will work.  -TYT
  27         */
  28
  29        bprm->sh_bang++;
  30        dput(bprm->dentry);
  31        bprm->dentry = NULL;
  32
  33        bprm->buf[127] = '\0';
  34        if ((cp = strchr(bprm->buf, '\n')) == NULL)
  35                cp = bprm->buf+127;
  36        *cp = '\0';
  37        while (cp > bprm->buf) {
  38                cp--;
  39                if ((*cp == ' ') || (*cp == '\t'))
  40                        *cp = '\0';
  41                else
  42                        break;
  43        }
  44        for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
  45        if (*cp == '\0') 
  46                return -ENOEXEC; /* No interpreter name found */
  47        i_name_start = i_name = cp;
  48        i_arg = 0;
  49        for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
  50                if (*cp == '/')
  51                        i_name = cp+1;
  52        }
  53        while ((*cp == ' ') || (*cp == '\t'))
  54                *cp++ = '\0';
  55        if (*cp)
  56                i_arg = cp;
  57        strcpy (interp, i_name_start);
  58        /*
  59         * OK, we've parsed out the interpreter name and
  60         * (optional) argument.
  61         * Splice in (1) the interpreter's name for argv[0]
  62         *           (2) (optional) argument to interpreter
  63         *           (3) filename of shell script (replace argv[0])
  64         *
  65         * This is done in reverse order, because of how the
  66         * user environment and arguments are stored.
  67         */
  68        remove_arg_zero(bprm);
  69        bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
  70        bprm->argc++;
  71        if (i_arg) {
  72                bprm->p = copy_strings(1, &i_arg, bprm->page, bprm->p, 2);
  73                bprm->argc++;
  74        }
  75        bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
  76        bprm->argc++;
  77        if ((long)bprm->p < 0) 
  78                return (long)bprm->p;
  79        /*
  80         * OK, now restart the process with the interpreter's dentry.
  81         */
  82        dentry = open_namei(interp, 0, 0);
  83        if (IS_ERR(dentry))
  84                return PTR_ERR(dentry);
  85
  86        bprm->dentry = dentry;
  87        retval = prepare_binprm(bprm);
  88        if (retval < 0)
  89                return retval;
  90        return search_binary_handler(bprm,regs);
  91}
  92
  93struct linux_binfmt script_format = {
  94        module:         THIS_MODULE,
  95        load_binary:    load_script,
  96};
  97
  98int __init init_script_binfmt(void)
  99{
 100        return register_binfmt(&script_format);
 101}
 102
 103#ifdef MODULE
 104int init_module(void)
 105{
 106        return init_script_binfmt();
 107}
 108
 109void cleanup_module( void) {
 110        unregister_binfmt(&script_format);
 111}
 112#endif
 113
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.