Beispiel #1
0
env_h env_make( char **env_strings )
{
   env_s *ep ;
   char **pp ;

   for ( pp = env_strings ; *pp ; pp++ ) ;

   ep = alloc_env( (unsigned) (pp-env_strings) ) ;
   if ( ep == NULL )
   {
      env_errno = ENV_ENOMEM ;
      return( ENV_NULL ) ;
   }

   for ( pp = env_strings ; *pp ; pp++ )
   {
      char *p = new_string( *pp ) ;

      if ( p == NULL )
      {
         env_destroy( ep ) ;
         env_errno = ENV_ENOMEM ;
         return( ENV_NULL ) ;
      }
      ep->vars[ ep->n_vars++ ] = p ;
   }
   return( ep ) ;
}
Beispiel #2
0
env_h env_create( const env_h init_env )
{
   unsigned u ;
   env_s *ep ;
   unsigned max_vars ;

   if ( init_env == ENV_NULL )
      max_vars = INITIAL_VARS ;
   else
      max_vars = init_env->n_vars + 5 ;
   
   ep = alloc_env( max_vars ) ;
   if ( ep == NULL )
   {
      env_errno = ENV_ENOMEM ;
      return( ENV_NULL ) ;
   }

   if ( init_env == ENV_NULL )
      return( ep ) ;

   for ( u = 0, ep->n_vars = 0 ; u < init_env->n_vars ; u++, ep->n_vars++ )
   {
      ep->vars[ ep->n_vars ] = new_string( init_env->vars[ u ] ) ;
      if ( ep->vars[ ep->n_vars ] == NULL )
      {
         env_destroy( ep ) ;
         env_errno = ENV_ENOMEM ;
         return( ENV_NULL ) ;
      }
   }
   return( ep ) ;
}
static
dumb_ptr<env_t> clone_env(dumb_ptr<env_t> src)
{
    dumb_ptr<env_t> retval = alloc_env(src->base_env);

    for (int i = 0; i < src->base_env->varv.size(); i++)
        magic_copy_var(&retval->varu[i], &src->varu[i]);

    return retval;
}
Beispiel #4
0
struct global_state *new_global_state(struct machine_specification *machine)
/* Returns: A new global state for a motlle interpreter for machine
*/
{
  struct global_state *gstate;

  GCPRO1(machine);
  gstate = (struct global_state *)allocate_record(type_vector, 5);
  GCPRO1(gstate);
  gstate->modules = alloc_table(DEF_TABLE_SIZE);
  gstate->mvars = alloc_vector(GLOBAL_SIZE);
  gstate->global = alloc_table(GLOBAL_SIZE);
  gstate->environment = alloc_env(GLOBAL_SIZE);
  gstate->machine = machine;
  GCPOP(2);

  return gstate;
}
Beispiel #5
0
/**
 * Choose what action should be taken according to passed settings.
 *
 * @1 Hotplug settings
 * @2 Event structure
 *
 * Returns: void
 *
 */
void action_perform(struct settings_t *settings, struct uevent_t *event) {
	int i;
	char **env;

	env = xmalloc(sizeof(char *) * event->env_vars_c);

	for (i = 0; i < event->env_vars_c; i++) {
		env[i] = alloc_env(event->env_vars[i].key, event->env_vars[i].value);
		putenv(env[i]);
	}

	if (settings->dumb == 0) {
		ruleset_execute(&settings->rules, event, settings);
	} else {
		action_dumb(settings, event);
	}

	for (i = 0; i < event->env_vars_c; i++) {
		unsetenv(event->env_vars[i].key);
		free(env[i]);
	}

	free(env);
}
dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell,
        dumb_ptr<map_session_data> caster, int spellpower, XString param)
{
    dumb_ptr<env_t> env = alloc_env(conf);

    switch (spell->spellarg_ty)
    {

        case SPELLARG::STRING:
            set_env_string(spell->arg, dumb_string::copys(param));
            break;

        case SPELLARG::PC:
        {
            CharName name = stringish<CharName>(param);
            dumb_ptr<map_session_data> subject = map_nick2sd(name);
            if (!subject)
                subject = caster;
            set_env_entity(spell->arg, subject);
            break;
        }

        case SPELLARG::NONE:
            break;

        default:
            FPRINTF(stderr, "Unexpected spellarg type %d\n",
                     spell->spellarg_ty);
    }

    set_env_entity(VAR_CASTER, caster);
    set_env_int(VAR_SPELLPOWER, spellpower);
    set_env_spell(VAR_SPELL, spell);

    return env;
}
Beispiel #7
0
long xexec(WORD flag, char *path, char *tail, char *env)
{
    PD *p;
    PGMHDR01 hdr;
    MD *m, *env_md;
    LONG rc;
    long max, needed;
    FH fh;

    KDEBUG(("BDOS xexec: flag or mode = %d\n",flag));

    /* first branch - actions that do not require loading files */
    switch(flag) {
#if DETECT_NATIVE_FEATURES
    case PE_RELOCATE:   /* internal use only, see bootstrap() in bios/bios.c */
        p = (PD *) tail;
        rc = kpgm_relocate(p, (long)path);
        if (rc) {
            KDEBUG(("BDOS xexec: kpgm_reloc returned %ld (0x%lx)\n",rc,rc));
            return rc;
        }

        /* invalidate instruction cache for the TEXT segment only
         * programs that jump into their DATA, BSS or HEAP are kindly invited
         * to do their cache management themselves.
         */
        invalidate_instruction_cache( p+1, p->p_tlen);

        return (long)p;
#endif
    case PE_BASEPAGE:           /* just create a basepage */
        path = (char *) 0L;     /* (same as basepage+flags with flags set to zero) */
    /* drop thru */
    case PE_BASEPAGEFLAGS:      /* create a basepage, respecting the flags */
        env_md = alloc_env(env);
        if (env_md == NULL) {
            KDEBUG(("BDOS xexec: not enough memory!\n"));
            return ENSMEM;
        }
        m = alloc_tpa((ULONG)path,sizeof(PD),&max);

        if (m == NULL) {    /* not even enough memory for basepage */
            freeit(env_md, &pmd);
            KDEBUG(("BDOS xexec: No memory for basepage\n"));
            return ENSMEM;
        }

        p = (PD *) m->m_start;

        /* memory ownership */
        m->m_own = env_md->m_own = run;

        /* initialize the PD */
        init_pd_fields(p, tail, max, env_md);
        p->p_flags = (ULONG)path;   /* set the flags */
        init_pd_files(p);

        return (long)p;
    case PE_GOTHENFREE:
        /* set the owner of the memory to be this process */
        p = (PD *) tail;
        set_owner(p, p, find_mpb(p));
        set_owner(p->p_env, p, find_mpb(p->p_env));
    /* fall through */
    case PE_GO:
        p = (PD *) tail;
        proc_go(p);
        /* should not return ? */
        return (long)p;
    case PE_LOADGO:
    case PE_LOAD:
        break;
    default:
        return EINVFN;
    }

    /* we now need to load a file */
    KDEBUG(("BDOS xexec: trying to find the command ...\n"));
    if (ixsfirst(path,0,0L)) {
        KDEBUG(("BDOS xexec: command %s not found!!!\n",path));
        return EFILNF;      /*  file not found      */
    }

    /* load the header - if I/O error occurs now, the longjmp in rwabs will
     * jump directly back to bdosmain.c, which is not a problem because
     * we haven't allocated anything yet.
     */
    rc = kpgmhdrld(path, &hdr, &fh);
    if (rc) {
        KDEBUG(("BDOS xexec: kpgmhdrld returned %ld (0x%lx)\n",rc,rc));
        return rc;
    }

    /* allocate the environment first, always in ST RAM */
    env_md = alloc_env(env);
    if (env_md == NULL) {
        KDEBUG(("BDOS xexec: not enough memory!\n"));
        return ENSMEM;
    }

    /* allocate the basepage depending on memory policy */
    needed = hdr.h01_tlen + hdr.h01_dlen + hdr.h01_blen + sizeof(PD);
    m = alloc_tpa(hdr.h01_flags,needed,&max);

    /* if failed, free env_md and return */
    if (m == NULL) {
        KDEBUG(("BDOS xexec: no memory for TPA\n"));
        freeit(env_md, &pmd);
        return ENSMEM;
    }

    p = (PD *) m->m_start;

    /* memory ownership - the owner is either the new process being created,
     * or the parent
     */
    if (flag == PE_LOADGO) {
        m->m_own = env_md->m_own = p;
    } else {
        m->m_own = env_md->m_own = run;
    }

    /* initialize the fields in the PD structure */
    init_pd_fields(p, tail, max, env_md);

    /* set the flags (must be done after init_pd) */
    p->p_flags = hdr.h01_flags;

    /* use static variable to avoid the obscure longjmp warning */
    cur_p = p;
    cur_m = m;
    cur_env_md = env_md;

    /* we have now allocated memory, so we need to intercept longjmp. */
    memcpy(bakbuf, errbuf, sizeof(errbuf));
    if (setjmp(errbuf)) {

        KDEBUG(("Error and longjmp in xexec()!\n"));

        /* free any memory allocated yet */
        freeit(cur_env_md, &pmd);
        freeit(cur_m, find_mpb(cur_m->m_start));

        /* we still have to jump back to bdosmain.c so that the proper error
         * handling can occur.
         */
        longjmp(bakbuf, 1);
    }

    /* now, load the rest of the program and perform relocation */
    rc = kpgmld(cur_p, fh, &hdr);
    if (rc) {
        KDEBUG(("BDOS xexec: kpgmld returned %ld (0x%lx)\n",rc,rc));
        /* free any memory allocated yet */
        freeit(cur_env_md, &pmd);
        freeit(cur_m, find_mpb(cur_m->m_start));

        return rc;
    }

    /* at this point the program has been correctly loaded in memory, and
     * more I/O errors cannot occur, so it is safe now to finish initializing
     * the new process.
     */
    init_pd_files(cur_p);

    /* invalidate instruction cache for the TEXT segment only
     * programs that jump into their DATA, BSS or HEAP are kindly invited
     * to do their cache management themselves.
     */
    invalidate_instruction_cache(((char *)cur_p) + sizeof(PD), hdr.h01_tlen);

    if (flag != PE_LOAD)
        proc_go(cur_p);
    return (long)cur_p;
}
Beispiel #8
0
int main() {
    /* using NAME_MAX prevents EINVAL on read() (twice for UTF-16 on NTFS) */
    char   buf[sizeof(struct inotify_event) + NAME_MAX*2 + 1];
    char   *crtpath, *qpath, *rqpath, *looppath, *lsthost, *lstport;
    int    sz, offset, rereg, evqok, retryid;
    struct inotify_event *iev;
    double retrytmout, lastclock;


    /* init logging */
    syslog_init();


    /* extract environment */
    crtpath  = alloc_env(CABLE_CERTS,  "/" CERTS_NAME);
    qpath    = alloc_env(CABLE_QUEUES, "/" QUEUE_NAME);
    rqpath   = alloc_env(CABLE_QUEUES, "/" RQUEUE_NAME);
    looppath = alloc_env(CABLE_HOME,   "/" LOOP_NAME);
    lsthost  = alloc_env(CABLE_HOST,   "");
    lstport  = alloc_env(CABLE_PORT,   "");


    /* initialize rng */
    if (!rand_init())
        warning("failed to initialize RNG");


    /* initialize process accounting */
    if (!init_process_acc())
        warning("failed to initialize process accounting");


    /* initialize webserver */
    if (!init_server(crtpath, qpath, rqpath, lsthost, lstport)) {
        flog(LOG_ERR, "failed to initialize webserver");
        return EXIT_FAILURE;
    }


    /* try to reregister watches as long as no signal caught */
    for (lastclock = getmontime(), retryid = 0;  !stop_requested(); ) {
        /* support empty CABLE_NOLOOP when testing, to act as pure server */
#ifdef TESTING
        if (getenv("CABLE_NOLOOP")) {
            sleepsec(RETRY_TMOUT);
            continue;
        }
#endif

        wait_reg_watches(qpath, rqpath);

        /* read events as long as no signal caught and no unmount / move_self / etc. events read */
        for (rereg = evqok = 0;  !stop_requested()  &&  !rereg; ) {
            /* wait for an event, or timeout (later blocking read() results in error) */
            retrytmout = RETRY_TMOUT + RETRY_TMOUT * (rand_shift() / 2);

            if (wait_read(inotfd, retrytmout - (getmontime() - lastclock))) {
                /* read events (non-blocking), taking care to handle interrupts due to signals */
                if ((sz = read(inotfd, buf, sizeof(buf))) == -1  &&  errno != EINTR) {
                    /* happens buffer is too small (e.g., NTFS + 255 unicode chars) */
                    warning("error while reading from inotify queue");
                    rereg = 1;
                }

                /* process all events in buffer, sz = -1 and 0 are automatically ignored */
                for (offset = 0;  offset < sz  &&  !stop_requested()  &&  !rereg;  evqok = 1) {
                    /* get handler to next event in read buffer, and update offset */
                    iev     = (struct inotify_event*) (buf + offset);
                    offset += sizeof(struct inotify_event) + iev->len;

                    /*
                      IN_IGNORED is triggered by watched directory removal / fs unmount
                      IN_MOVE_SELF is only triggered by move of actual watched directory
                      (i.e., not its parent)
                    */
                    if ((iev->mask & (IN_IGNORED | IN_UNMOUNT | IN_Q_OVERFLOW | IN_MOVE_SELF)))
                        rereg = 1;

                    /* ignore non-subdirectory events, and events with incorrect name */
                    else if (iev->len > 0  &&  (iev->mask & IN_ISDIR)  &&  is_msgdir(iev->name)) {
                        assert(iev->wd == inotqwd  ||  iev->wd == inotrqwd);
                        if (iev->wd == inotqwd  ||  iev->wd == inotrqwd) {
                            /* stop can be indicated here (while waiting for less processes) */
                            const char *qtype = (iev->wd == inotqwd) ? QUEUE_NAME : RQUEUE_NAME;
                            run_loop(qtype, iev->name, looppath);
                        }
                        else
                            flog(LOG_WARNING, "unknown watch descriptor");
                    }
                }
            }

            /*
              if sufficient time passed since last retries, retry again
            */
            if (!stop_requested()  &&  getmontime() - lastclock >= retrytmout) {
                /* alternate between queue dirs to prevent lock starvation on self-send */
                if ((retryid ^= 1))
                    retry_dir(QUEUE_NAME,  qpath,  looppath);
                else
                    retry_dir(RQUEUE_NAME, rqpath, looppath);

                lastclock = getmontime();

                /* inotify is apparently unreliable on fuse, so reregister when no events */
                if (!evqok)
                    rereg = 1;
                evqok = 0;
            }
        }
    }


    unreg_watches();

    if (!shutdown_server())
        flog(LOG_WARNING, "failed to shutdown webserver");

    dealloc_env(lstport);
    dealloc_env(lsthost);
    dealloc_env(looppath);
    dealloc_env(rqpath);
    dealloc_env(qpath);
    dealloc_env(crtpath);

    flog(LOG_INFO, "exiting");
    closelog();

    return EXIT_SUCCESS;
}
Beispiel #9
0
/**
 * Executes a rule. Contains evaluation of all conditions prior
 * to execution.
 *
 * @1 Hotplug event structure
 * @2 The rule to be executed
 *
 * Returns: 0 if success, -1 if the whole event is to be 
 * discared, 1 if bail out of this particular rule was required
 */
int rule_execute(struct hotplug2_event_t *event, struct rule_t *rule) {
	int i, last_rv, res;
	char **env;
	
	for (i = 0; i < rule->conditions_c; i++) {
		if (rule_condition_eval(event, &(rule->conditions[i])) != EVAL_MATCH)
			return 0;
	}
	
	res = 0;
	last_rv = 0;
	
	env = xmalloc(sizeof(char *) * event->env_vars_c);
	for (i = 0; i < event->env_vars_c; i++) {
		env[i] = alloc_env(event->env_vars[i].key, event->env_vars[i].value);
		putenv(env[i]);
	}
	
	for (i = 0; i < rule->actions_c; i++) {
		switch (rule->actions[i].type) {
			case ACT_STOP_PROCESSING:
				res = 1;
				break;
			case ACT_STOP_IF_FAILED:
				if (last_rv != 0)
					res = 1;
				break;
			case ACT_NEXT_EVENT:
				res = -1;
				break;
			case ACT_NEXT_IF_FAILED:
				if (last_rv != 0)
					res = -1;
				break;
			case ACT_MAKE_DEVICE:
				last_rv = make_dev_from_event(event, rule->actions[i].parameter[0], strtoul(rule->actions[i].parameter[1], NULL, 0));
				break;
			case ACT_CHMOD:
				last_rv = chmod_file(event, rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
				break;
			case ACT_CHOWN:
			case ACT_CHGRP:
				last_rv = chown_chgrp(event, rule->actions[i].type, rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
				break;
			case ACT_SYMLINK:
				last_rv = make_symlink(event, rule->actions[i].parameter[0], rule->actions[i].parameter[1]);
				break;
			case ACT_RUN_SHELL:
				last_rv = exec_shell(event, rule->actions[i].parameter[0]);
				break;
			case ACT_RUN_NOSHELL:
				last_rv = exec_noshell(event, rule->actions[i].parameter[0], rule->actions[i].parameter);
				break;
			case ACT_SETENV:
				last_rv = setenv(rule->actions[i].parameter[0], rule->actions[i].parameter[1], 1);
				break;
			case ACT_REMOVE:
				last_rv = unlink(rule->actions[i].parameter[0]);
				rmdir_p(rule->actions[i].parameter[0]);
				break;
			case ACT_DEBUG:
				print_debug(event);
				last_rv = 0;
				break;
		}
		if (res != 0)
			break;
	}
	
	for (i = 0; i < event->env_vars_c; i++) {
		unsetenv(event->env_vars[i].key);
		free(env[i]);
	}
	free(env);
	
	return res;
}
Beispiel #10
0
long xexec(WORD flag, char *path, char *tail, char *env)
{
    PD *p;
    PGMHDR01 hdr;
    MD *m, *env_md;
    LONG rc;
    long max, needed;
    FH fh;

    D(("BDOS: xexec - flag or mode = %d\n", flag));

    /* first branch - actions that do not require loading files */
    switch(flag) {
    case PE_RELOCATE: 
        p = (PD *) tail;
        rc = kpgm_relocate(p, (long)path);
        if(rc) {
            D(("BDOS: xexec - kpgm_relloc returned %ld (0x%lx)\n", rc, rc));
            return(rc);
        }

        /* invalidate instruction cache for the TEXT segment only
         * programs that jump into their DATA, BSS or HEAP are kindly invited 
         * to do their cache management themselves.
         */
        invalidate_icache( p+1, p->p_tlen);

        return (long) p;
    case PE_BASEPAGE:        
        /* just create a basepage */
        env_md = alloc_env(env);
        if(env_md == NULL) {
            D(("xexec: Not Enough Memory!\n"));
            return(ENSMEM);
        }
        max = (long) ffit(-1L, &pmd); 
        if(max >= sizeof(PD)) {
            m = ffit(max, &pmd);
            p = (PD *) m->m_start;
        } else {
            /* not even enough memory for basepage */
            freeit(env_md, &pmd);
            D(("xexec: No memory for TPA\n"));
            return(ENSMEM);
        }
        /* memory ownership */
        m->m_own = env_md->m_own = run;

        /* initialize the PD */
        init_pd_fields(p, tail, max, env_md);
        init_pd_files(p);

        return (long) p;
    case PE_GOTHENFREE:
        /* set the owner of the memory to be this process */
        p = (PD *) tail;
        set_owner(p, p, find_mpb(p));
        set_owner(p->p_env, p, find_mpb(p->p_env));
        /* fall through */
    case PE_GO:
        p = (PD *) tail;
        proc_go(p);
        /* should not return ? */
        return (long)p;
    case PE_LOADGO:
    case PE_LOAD:
        break;
    default:
        return EINVFN;
    }
    
    /* we now need to load a file */
    D(("BDOS: xexec - trying to find the command ...\n"));
    if (ixsfirst(path,0,0L)) {
        D(("BDOS: Command %s not found!!!\n", path));
        return(EFILNF);     /*  file not found      */
    }

    /* load the header - if IO error occurs now, the longjmp in rwabs will
     * jump directly back to bdosmain.c, which is not a problem because
     * we haven't allocated anything yet.
     */
    rc = kpgmhdrld(path, &hdr, &fh);
    if(rc) {
        D(("BDOS: xexec - kpgmhdrld returned %ld (0x%lx)\n", rc, rc));
        return(rc);
    }

    /* allocate the environment first, always in ST RAM */
    env_md = alloc_env(env);
    if ( env_md == NULL ) {
        D(("xexec: Not Enough Memory!\n"));
        return(ENSMEM);
    }
    
    /* allocate the basepage depending on memory policy */
    needed = hdr.h01_tlen + hdr.h01_dlen + hdr.h01_blen + sizeof(PD);
    max = 0;
        
    /* first try */
    p = NULL;
    m = NULL;
#if CONF_WITH_ALT_RAM
    if(has_alt_ram && (hdr.h01_flags & PF_TTRAMLOAD)) {
        /* use alternate ram preferably */
        max = (long) ffit(-1L, &pmdalt); 
        if(max >= needed) {
            m = ffit(max, &pmdalt);
            p = (PD *) m->m_start;
        } 
    }
#endif
    /* second try */
    if(p == NULL) {
        max = (long) ffit(-1L, &pmd); 
        if(max >= needed) {
            m = ffit(max, &pmd);
            p = (PD *) m->m_start;
        } 
    }
    /* still failed? free env_md and return */
    if(p == NULL) {
        D(("xexec: No memory for TPA\n"));
        freeit(env_md, &pmd);
        return(ENSMEM);
    }
    assert(m != NULL);

    /* memory ownership - the owner is either the new process being created,
     * or the parent 
     */
    if(flag == PE_LOADGO) {
        m->m_own = env_md->m_own = p;
    } else {
        m->m_own = env_md->m_own = run;
    }   

    /* initialize the fields in the PD structure */
    init_pd_fields(p, tail, max, env_md);
    
    /* set the flags (must be done after init_pd) */
    p->p_flags = hdr.h01_flags;

    /* use static variable to avoid the obscure longjmp warning */
    cur_p = p;
    cur_m = m;
    cur_env_md = env_md;

    /* we have now allocated memory, so we need to intercept longjmp. */
    memcpy(bakbuf, errbuf, sizeof(errbuf));
    if ( setjmp(errbuf) ) {

        kprintf("Error and longjmp in xexec()!\n");

        /* free any memory allocated yet */
        freeit(cur_env_md, &pmd);
        freeit(cur_m, find_mpb((void *)cur_m->m_start));
        
        /* we still have to jump back to bdosmain.c so that the proper error
         * handling can occur.
         */
        longjmp(bakbuf, 1);
    }

    /* now, load the rest of the program and perform relocation */
    rc = kpgmld(cur_p, fh, &hdr);
    if ( rc ) {
        D(("BDOS: xexec - kpgmld returned %ld (0x%lx)\n", rc, rc));
        /* free any memory allocated yet */
        freeit(cur_env_md, &pmd);
        freeit(cur_m, find_mpb((void *)cur_m->m_start));
    
        return rc;
    }

    /* at this point the program has been correctly loaded in memory, and 
     * more IO errors cannot occur, so it is safe now to finish initializing
     * the new process.
     */
    init_pd_files(cur_p);
    
    /* invalidate instruction cache for the TEXT segment only
     * programs that jump into their DATA, BSS or HEAP are kindly invited 
     * to do their cache management themselves.
     */
    invalidate_icache(((char *)cur_p) + sizeof(PD), hdr.h01_tlen);

    if(flag != PE_LOAD)
        proc_go(cur_p);
    return (long) cur_p;
}