static AP_Result tcl_eval0(AP_World *w, AP_Obj interp_name, AP_Obj command, AP_Obj result,
					EvalOption option)
{
	Tcl_Interp *interp;
	Tcl_Obj *tcl_command, *eval_string;
	int r;

	interp = GetInterp(w, interp_name);
	if (!interp) return AP_EXCEPTION;
	
	tcl_command = PrologToTclObj(w, command, interp);
	Tcl_IncrRefCount(tcl_command);

	if (option == arg_list) {
		eval_string = Tcl_NewStringObj((char *)"eval", -1);
		if (!tcl_command || !eval_string) {
			return AP_SetStandardError(w, AP_RESOURCE_ERROR, AP_NewSymbolFromStr(w, "tcl_memory"));
		}
		Tcl_ListObjReplace(interp, tcl_command, 0, 0, 1, &eval_string);
	}

	r = Tcl_EvalObj(interp, tcl_command);

	Tcl_DecrRefCount(tcl_command);
	
	/* Hack to refresh result */
	PI_getan(&result.p, &result.t, 3);

	return TclToPrologResult(w, &result, interp, r);
}
Exemple #2
0
static
LDAP_SetErrorCode(LDAPTCL *ldaptcl, int code, Tcl_Interp *interp)
{
    char shortbuf[16];
    char *errp;
    int   lderrno;

    if (code == -1)
	code = ldap_get_lderrno(ldaptcl->ldap);
    if ((ldaptcl->flags & LDAPTCL_INTERRCODES) || code > LDAPTCL_MAXERR ||
      ldaptclerrorcode[code] == NULL) {
	sprintf(shortbuf, "0x%03x", code);
	errp = shortbuf;
    } else
	errp = ldaptclerrorcode[code];

    Tcl_SetErrorCode(interp, errp, NULL);
    if (ldaptcl->trapCmdObj) {
	int *i;
	Tcl_Obj *cmdObj;
	if (ldaptcl->traplist != NULL) {
	    for (i = ldaptcl->traplist; *i && *i != code; i++)
		;
	    if (*i == 0) return;
	}
	(void) Tcl_EvalObj(interp, ldaptcl->trapCmdObj);
    }
}
Exemple #3
0
/*************************************************************************
* FUNCTION      :   RPMTransaction_Set::RPM_callback                     *
* ARGUMENTS     :   none                                                 *
* RETURNS       :   TCL_OK or TCL_ERROR                                  *
* EXCEPTIONS    :   none                                                 *
* PURPOSE       :   Set or get problem mask flags                        *
*************************************************************************/
void *RPMTransaction_Set::RPM_callback( const void * h,
                                        const rpmCallbackType what,
                                        const unsigned long amount,
                                        const unsigned long total,
                                        fnpyKey key
                                      )
{
    // Build up the list of call back bits
    Tcl_Obj *bitstring = Tcl_NewObj();
    for (unsigned i = 0; i < sizeof(bits)/sizeof(bits[0]); ++i)
    {
        if (what & bits[i].bit)
        {
            Tcl_ListObjAppendElement(_interp,bitstring,Tcl_NewStringObj(bits[i].msg,-1));
        }
    }
    RPMHeader_Obj *hdr = (RPMHeader_Obj *)key;
    Tcl_Obj *cmd[] =
    {
        Tcl_NewStringObj("::RPM::Callback",-1),
        bitstring,
        Tcl_NewLongObj(amount),
        Tcl_NewLongObj(total),
        hdr?hdr->Get_obj():Tcl_NewObj()
    };
    Tcl_Obj *script = Tcl_NewListObj(sizeof(cmd)/sizeof(cmd[0]),cmd);
    Tcl_IncrRefCount(script);
    Tcl_EvalObj(_interp,script);
    Tcl_DecrRefCount(script);

    // Now, handle any special operations here
    if (what & RPMCALLBACK_INST_OPEN_FILE)
    {
        assert(hdr);
        FD_t fd = hdr->Open();
        if (!fd || Ferror(fd))
        {
            if (fd)
            {
                Fclose(fd);
                fd = 0;
            }
        }
        return (void *)fd;
    }
    if (what & RPMCALLBACK_INST_CLOSE_FILE)
    {
        assert(hdr);
        hdr->Close();
        return 0;
    }
    return 0;
}
Exemple #4
0
/*************************************************************************
* FUNCTION      :   RPMTransaction_Set::Solve                            *
* ARGUMENTS     :   transaction set, key, this in disguise               *
* RETURNS       :   -1 (retry), 0 (ignore), 1 (not found)                *
* EXCEPTIONS    :   none                                                 *
* PURPOSE       :   Solve an install problem                             *
*************************************************************************/
int RPMTransaction_Set::Solve(rpmds key)
{
    // Throw the key over to TCL.
    Tcl_Obj *cmd[] =
    {
        Tcl_NewStringObj("::RPM::Solve",-1),
        Tcl_NewStringObj(Tcl_GetCommandName(_interp, me),-1),
        RPMDependency_Obj::Create_from_ds(key)
    };
    Tcl_Obj *script = Tcl_NewListObj(sizeof(cmd)/sizeof(cmd[0]),cmd);
    Tcl_IncrRefCount(script);
    Tcl_EvalObj(_interp,script);
    Tcl_DecrRefCount(script);
    // Now get the return value
    Tcl_Obj *result = Tcl_GetObjResult(_interp);
    int rv = 0;
    Tcl_GetIntFromObj(_interp,result,&rv);
    return rv;
}
Exemple #5
0
/*
** Called for each row of the result.
**
** This version is used when either of the following is true:
**
**    (1) This version of TCL uses UTF-8 and the data in the
**        SQLite database is already in the UTF-8 format.
**
**    (2) This version of TCL uses ISO8859 and the data in the
**        SQLite database is already in the ISO8859 format.
*/
static int DbEvalCallback(
  void *clientData,      /* An instance of CallbackData */
  int nCol,              /* Number of columns in the result */
  char ** azCol,         /* Data for each column */
  char ** azN            /* Name for each column */
){
  CallbackData *cbData = (CallbackData*)clientData;
  int i, rc;
  if( azCol==0 || (cbData->once && cbData->zArray[0]) ){
    Tcl_SetVar2(cbData->interp, cbData->zArray, "*", "", 0);
    for(i=0; i<nCol; i++){
      Tcl_SetVar2(cbData->interp, cbData->zArray, "*", azN[i],
         TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
      if( azN[nCol] ){
        char *z = sqlite_mprintf("typeof:%s", azN[i]);
        Tcl_SetVar2(cbData->interp, cbData->zArray, z, azN[i+nCol],
           TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
        sqlite_freemem(z);
      }
    }
    cbData->once = 0;
  }
  if( azCol!=0 ){
    if( cbData->zArray[0] ){
      for(i=0; i<nCol; i++){
        char *z = azCol[i];
        if( z==0 ) z = "";
        Tcl_SetVar2(cbData->interp, cbData->zArray, azN[i], z, 0);
      }
    }else{
      for(i=0; i<nCol; i++){
        char *z = azCol[i];
        if( z==0 ) z = "";
        Tcl_SetVar(cbData->interp, azN[i], z, 0);
      }
    }
  }
  rc = Tcl_EvalObj(cbData->interp, cbData->pCode);
  if( rc==TCL_CONTINUE ) rc = TCL_OK;
  cbData->tcl_rc = rc;
  return rc!=TCL_OK;
}
Exemple #6
0
/*
** Called for each row of the result.
**
** This version is used when TCL expects UTF-8 data but the database
** uses the ISO8859 format.  A translation must occur from ISO8859 into
** UTF-8.
*/
static int DbEvalCallback(
  void *clientData,      /* An instance of CallbackData */
  int nCol,              /* Number of columns in the result */
  char ** azCol,         /* Data for each column */
  char ** azN            /* Name for each column */
){
  CallbackData *cbData = (CallbackData*)clientData;
  int i, rc;
  Tcl_DString dCol;
  Tcl_DStringInit(&dCol);
  if( cbData->azColName==0 ){
    assert( cbData->once );
    cbData->once = 0;
    if( cbData->zArray[0] ){
      Tcl_SetVar2(cbData->interp, cbData->zArray, "*", "", 0);
    }
    cbData->azColName = malloc( nCol*sizeof(char*) );
    if( cbData->azColName==0 ){ return 1; }
    cbData->nColName = nCol;
    for(i=0; i<nCol; i++){
      Tcl_ExternalToUtfDString(NULL, azN[i], -1, &dCol);
      cbData->azColName[i] = malloc( Tcl_DStringLength(&dCol) + 1 );
      if( cbData->azColName[i] ){
        strcpy(cbData->azColName[i], Tcl_DStringValue(&dCol));
      }else{
        return 1;
      }
      if( cbData->zArray[0] ){
        Tcl_SetVar2(cbData->interp, cbData->zArray, "*",
             Tcl_DStringValue(&dCol), TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
        if( azN[nCol]!=0 ){
          Tcl_DString dType;
          Tcl_DStringInit(&dType);
          Tcl_DStringAppend(&dType, "typeof:", -1);
          Tcl_DStringAppend(&dType, Tcl_DStringValue(&dCol), -1);
          Tcl_DStringFree(&dCol);
          Tcl_ExternalToUtfDString(NULL, azN[i+nCol], -1, &dCol);
          Tcl_SetVar2(cbData->interp, cbData->zArray, 
               Tcl_DStringValue(&dType), Tcl_DStringValue(&dCol),
               TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
          Tcl_DStringFree(&dType);
        }
      }
      
      Tcl_DStringFree(&dCol);
    }
  }
  if( azCol!=0 ){
    if( cbData->zArray[0] ){
      for(i=0; i<nCol; i++){
        char *z = azCol[i];
        if( z==0 ) z = "";
        Tcl_DStringInit(&dCol);
        Tcl_ExternalToUtfDString(NULL, z, -1, &dCol);
        Tcl_SetVar2(cbData->interp, cbData->zArray, cbData->azColName[i], 
              Tcl_DStringValue(&dCol), 0);
        Tcl_DStringFree(&dCol);
      }
    }else{
      for(i=0; i<nCol; i++){
        char *z = azCol[i];
        if( z==0 ) z = "";
        Tcl_DStringInit(&dCol);
        Tcl_ExternalToUtfDString(NULL, z, -1, &dCol);
        Tcl_SetVar(cbData->interp, cbData->azColName[i],
                   Tcl_DStringValue(&dCol), 0);
        Tcl_DStringFree(&dCol);
      }
    }
  }
  rc = Tcl_EvalObj(cbData->interp, cbData->pCode);
  if( rc==TCL_CONTINUE ) rc = TCL_OK;
  cbData->tcl_rc = rc;
  return rc!=TCL_OK;
}
void
start_tcl(void)
{
    char *id = "start_tcl";
    char buf[BUFSIZ];
    int fd;
    int tot, len;

    interp = Tcl_CreateInterp();

    if (Tcl_Init(interp) == TCL_ERROR)
    {
        sprintf(log_buffer, "Tcl_Init error: %s",
                Tcl_GetStringResult(interp));
        log_err(-1, id, log_buffer);
        die(0);
    }

#if TCLX
#if TCL_MINOR_VERSION < 5  && TCL_MAJOR_VERSION < 8
    if (TclX_Init(interp) == TCL_ERROR)
    {
#else

    if (Tclx_Init(interp) == TCL_ERROR)
    {
#endif
        sprintf(log_buffer, "Tclx_Init error: %s",
                Tcl_GetStringResult(interp));
        log_err(-1, id, log_buffer);
        die(0);
    }

#endif
    add_cmds(interp);

    if (initfil)
    {
        int  code;

        code = Tcl_EvalFile(interp, initfil);

        if (code != TCL_OK)
        {
            char *trace;

            trace = (char *)Tcl_GetVar(interp, "errorInfo", 0);

            if (trace == NULL)
                trace = (char *)Tcl_GetStringResult(interp);

            fprintf(stderr, "%s: TCL error @ line %d: %s\n",
                    initfil, interp->errorLine, trace);

            sprintf(log_buffer, "%s: TCL error @ line %d: %s",
                    initfil, interp->errorLine,
                    Tcl_GetStringResult(interp));

            log_err(-1, id, log_buffer);

            die(0);
        }

        sprintf(log_buffer, "init file %s", initfil);

        log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER,
                   id, log_buffer);
    }

    if ((fd = open(bodyfil, O_RDONLY)) == -1)
    {
        log_err(errno, id, bodyfil);
        die(0);
    }

    sprintf(log_buffer, "body file: %s", bodyfil);

    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

    if (body)
        free(body);

    if ((body = malloc(BUFSIZ)) == NULL)
    {
        log_err(errno, id, "malloc");
        die(0);
    }

    for (tot = 0; (len = read(fd, buf, sizeof(buf))) > 0; tot += len)
    {
        if ((body = realloc(body, tot + len + 1)) == NULL)
        {
            log_err(errno, id, "realloc");
            die(0);
        }

        memcpy(&body[tot], buf, len);
    }

    if (len == -1)
    {
        log_err(errno, id, bodyfil);
        die(0);
    }

    body[tot] = '\0';

    close(fd);

#if TCL_MAJOR_VERSION >= 8

    if (body_obj == NULL)
    {
        body_obj = Tcl_NewStringObj(body, tot);
        Tcl_IncrRefCount(body_obj);
    }
    else
    {
        Tcl_SetStringObj(body_obj, body, tot);
    }

#endif
}

int

addclient(name)
char *name;
{
    static char id[] = "addclient";

    struct hostent  *host, *gethostbyname();

    struct  in_addr saddr;

    if ((host = gethostbyname(name)) == NULL)
    {
        sprintf(log_buffer, "host %s not found", name);
        log_err(-1, id, log_buffer);
        return -1;
    }

    if (numclients >= START_CLIENTS)
    {
        pbs_net_t *newclients;

        newclients = realloc(okclients,
                             sizeof(pbs_net_t) * (numclients + 1));

        if (newclients == NULL)
            return -1;

        okclients = newclients;
    }

    memcpy((char *)&saddr, host->h_addr, host->h_length);

    okclients[numclients++] = saddr.s_addr;
    return 0;
}

/*
 * read_config - read and process the configuration file (see -c option)
 *
 * Currently, the only statement is $clienthost to specify which systems
 * can contact the scheduler.
 */
#define CONF_LINE_LEN 120

static
int
read_config(file)
char *file;
{
    static char *id = "read_config";
    FILE *conf;
    int i;
    char line[CONF_LINE_LEN];
    char *token;

    struct specialconfig
    {
        char *name;
        int (*handler)();
    } special[] =

    {
        {"clienthost", addclient },
        { NULL,  NULL }
    };


#if !defined(DEBUG) && !defined(NO_SECURITY_CHECK)

    if (chk_file_sec(file, 0, 0, S_IWGRP | S_IWOTH, 1, 0))
        return (-1);

#endif

    if ((conf = fopen(file, "r")) == NULL)
    {
        log_err(errno, id, "cannot open config file");
        return (-1);
    }

    while (fgets(line, CONF_LINE_LEN, conf))
    {

        if ((line[0] == '#') || (line[0] == '\n'))
            continue;  /* ignore comment & null line */
        else if (line[0] == '$')   /* special */
        {

            if ((token = strtok(line, " \t")) == NULL)
                token = "";

            for (i = 0; special[i].name; i++)
            {
                if (strcmp(token + 1, special[i].name) == 0)
                    break;
            }

            if (special[i].name == NULL)
            {
                sprintf(log_buffer, "config name %s not known",
                        token);
                log_record(PBSEVENT_ERROR,
                           PBS_EVENTCLASS_SERVER,
                           msg_daemonname, log_buffer);
                return (-1);
            }

            token = strtok(NULL, " \t");

            if (*(token + strlen(token) - 1) == '\n')
                *(token + strlen(token) - 1) = '\0';

            if (special[i].handler(token))
            {
                fclose(conf);
                return (-1);
            }

        }
        else
        {
            log_record(PBSEVENT_ERROR, PBS_EVENTCLASS_SERVER,
                       msg_daemonname,
                       "invalid line in config file");
            fclose(conf);
            return (-1);
        }
    }

    fclose(conf);

    return (0);
}

void
restart(sig)
int sig;
{
    char    *id = "restart";

    if (sig)
    {
        sprintf(log_buffer, "restart on signal %d", sig);
        log_close(1);
        log_open(logfile, path_log);
    }
    else
    {
        sprintf(log_buffer, "restart command");
    }

    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

    Tcl_DeleteInterp(interp);

    if (configfile)
    {
        if (read_config(configfile) != 0)
            die(0);
    }

    start_tcl();
}

void
badconn(msg)
char *msg;
{
    static char id[] = "badconn";

    struct in_addr addr;
    char  buf[5*sizeof(addr) + 100];

    struct hostent *phe;

    addr = saddr.sin_addr;
    phe = gethostbyaddr((void *) & addr, sizeof(addr), AF_INET);

    if (phe == NULL)
    {
        char hold[6];
        int i;
        union
        {

            struct in_addr aa;
            u_char  bb[sizeof(addr)];
        } uu;

        uu.aa = addr;
        sprintf(buf, "%u", uu.bb[0]);

        for (i = 1; i < (int)sizeof(addr); i++)
        {
            sprintf(hold, ".%u", uu.bb[i]);
            strcat(buf, hold);
        }
    }
    else
    {
        strncpy(buf, phe->h_name, sizeof(buf));
        buf[sizeof(buf)-1] = '\0';
    }

    sprintf(log_buffer, "%s on port %u %s", buf, ntohs(saddr.sin_port), msg);

    log_err(-1, id, log_buffer);
    return;
}

unsigned int
server_command()
{
    static char id[] = "server_command";
    int  new_socket;
    int  i;
    torque_socklen_t slen;
    unsigned int  cmd;
    pbs_net_t addr;

    slen = sizeof(saddr);
    new_socket = accept(server_sock,
                        (struct sockaddr *) & saddr, &slen);

    if (new_socket == -1)
    {
        log_err(errno, id, "accept");
        return SCH_ERROR;
    }

    if (ntohs(saddr.sin_port) >= IPPORT_RESERVED)
    {
        badconn("non-reserved port");
        close(new_socket);
        return SCH_ERROR;
    }

    addr = (pbs_net_t)saddr.sin_addr.s_addr;

    for (i = 0; i < numclients; i++)
    {
        if (addr == okclients[i])
            break;
    }

    if (i == numclients)
    {
        badconn("unauthorized host");
        close(new_socket);
        return SCH_ERROR;
    }

    if ((connector = socket_to_conn(new_socket)) < 0)
    {
        log_err(errno, id, "socket_to_conn");
        return SCH_ERROR;
    }

    if (get_4byte(new_socket, &cmd) != 1)
    {
        log_err(errno, id, "get4bytes");
        return SCH_ERROR;
    }

    return cmd;
}


/*
 * lock_out - lock out other daemons from this directory.
 */

static void lock_out(fds, op)
int fds;
int op;  /* F_WRLCK  or  F_UNLCK */
{

    struct flock flock;

    flock.l_type   = op;
    flock.l_whence = SEEK_SET;
    flock.l_start  = 0;
    flock.l_len    = 0; /* whole file */

    if (fcntl(fds, F_SETLK, &flock) < 0)
    {
        (void)strcpy(log_buffer, "pbs_sched: another scheduler running\n");
        log_err(errno, msg_daemonname, log_buffer);
        fprintf(stderr, log_buffer);
        exit(1);
    }
}

int main(argc, argv)
int  argc;
char *argv[];
{
    char  *id = "main";
    int  code;

    struct hostent *hp;
    int  go, c, errflg = 0;
    int  lockfds;
    int  t = 1;
    char  *ptr;
    pid_t  pid;
    char  *cp, host[100];
    char  *homedir = PBS_SERVER_HOME;
    unsigned int port;
    char  path_priv[_POSIX_PATH_MAX];
    char  *dbfile = "sched_out";
    int  alarm_time = 180;

    struct sigaction act;
    caddr_t  curr_brk = 0, next_brk;
    extern char *optarg;
    extern int optind, opterr;
    fd_set  fdset;

#ifndef DEBUG
    if (IamRoot() == 0)
    {
        return (1);
    }
#endif /* DEBUG */

    glob_argv = argv;

    if ((cp = strrchr(argv[0], '/')) == NULL)
        cp = argv[0];
    else
        cp++;

    msg_daemonname = strdup(cp);

    port = get_svrport(PBS_SCHEDULER_SERVICE_NAME, "tcp",
                       PBS_SCHEDULER_SERVICE_PORT);

    while ((c = getopt(argc, argv, "L:S:d:i:b:t:p:a:vc:")) != EOF)
    {
        switch (c)
        {

        case 'L':
            logfile = optarg;
            break;

        case 'S':
            port = (unsigned int)atoi(optarg);

            if (port == 0)
            {
                fprintf(stderr,
                        "%s: illegal port\n", optarg);
                errflg = 1;
            }

            break;

        case 'd':
            homedir = optarg;
            break;

        case 'i':  /* initialize */
            initfil = optarg;
            break;

        case 'b':
            bodyfil = optarg;
            break;

        case 't':
            termfil = optarg;
            break;

        case 'p':
            dbfile = optarg;
            break;

        case 'a':
            alarm_time = strtol(optarg, &ptr, 10);

            if (alarm_time <= 0 || *ptr != '\0')
            {
                fprintf(stderr,
                        "%s: bad alarm time\n", optarg);
                errflg = 1;
            }

            break;

        case 'c':
            configfile = optarg;
            break;

        case 'v':
            verbose = 1;
            break;

        case '?':
            errflg = 1;
            break;
        }
    }

    if (errflg || optind != argc)
    {
        static char *options[] =
        {
            "[-L logfile]",
            "[-S port]",
            "[-d home]",
            "[-i init]",
            "[-b body]",
            "[-t term]",
            "[-p output]",
            "[-a alarm]",
            "[-c configfile]",
            "[-v]",
            NULL
        };
        int i;

        fprintf(stderr, "usage: %s\n", argv[0]);

        for (i = 0; options[i]; i++)
            fprintf(stderr, "\t%s\n", options[i]);

        exit(1);
    }

    /* Save the original working directory for "restart" */
    if ((oldpath = getcwd((char *)NULL, MAXPATHLEN)) == NULL)
    {
        fprintf(stderr, "cannot get current working directory\n");
        exit(1);
    }

    (void)sprintf(path_priv, "%s/sched_priv", homedir);
#if !defined(DEBUG) && !defined(NO_SECURITY_CHECK)
    c  = chk_file_sec(path_priv, 1, 0, S_IWGRP | S_IWOTH, 1, 0);
    c |= chk_file_sec(PBS_ENVIRON, 0, 0, S_IWGRP | S_IWOTH, 0, 0);

    if (c != 0) exit(1);

#endif  /* not DEBUG and not NO_SECURITY_CHECK */
    if (chdir(path_priv) == -1)
    {
        perror(path_priv);
        exit(1);
    }

    (void)sprintf(path_log, "%s/sched_logs", homedir);
    (void)strcpy(pbs_current_user, "Scheduler");

    /* The following is code to reduce security risks                */
    /* start out with standard umask, system resource limit infinite */

    umask(022);

    if (setup_env(PBS_ENVIRON) == -1)
        exit(1);

    c = getgid();

    (void)setgroups(1, (gid_t *)&c); /* secure suppl. group ids */

    c = sysconf(_SC_OPEN_MAX);

    while (--c > 2)
        (void)close(c); /* close any file desc left open by parent */

#ifndef DEBUG
#ifdef _CRAY
    (void)limit(C_JOB,      0, L_CPROC, 0);

    (void)limit(C_JOB,      0, L_CPU,   0);

    (void)limit(C_JOBPROCS, 0, L_CPU,   0);

    (void)limit(C_PROC,     0, L_FD,  255);

    (void)limit(C_JOB,      0, L_FSBLK, 0);

    (void)limit(C_JOBPROCS, 0, L_FSBLK, 0);

    (void)limit(C_JOB,      0, L_MEM  , 0);

    (void)limit(C_JOBPROCS, 0, L_MEM  , 0);

#else /* not  _CRAY */
    {

        struct rlimit rlimit;

        rlimit.rlim_cur = RLIM_INFINITY;
        rlimit.rlim_max = RLIM_INFINITY;
        (void)setrlimit(RLIMIT_CPU,   &rlimit);
        (void)setrlimit(RLIMIT_FSIZE, &rlimit);
        (void)setrlimit(RLIMIT_DATA,  &rlimit);
        (void)setrlimit(RLIMIT_STACK, &rlimit);
#ifdef  RLIMIT_RSS
        (void)setrlimit(RLIMIT_RSS  , &rlimit);
#endif  /* RLIMIT_RSS */
#ifdef  RLIMIT_VMEM
        (void)setrlimit(RLIMIT_VMEM  , &rlimit);
#endif  /* RLIMIT_VMEM */
    }
#endif /* not _CRAY */

#if !defined(NO_SECURITY_CHECK)
    c = 0;

    if (initfil)
    {
        if (*initfil != '/')
        {
            (void)sprintf(log_buffer, "%s/%s", path_priv, initfil);
            c |= chk_file_sec(log_buffer, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
        else
        {
            c |= chk_file_sec(initfil, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
    }

    if (bodyfil)
    {
        if (*bodyfil != '/')
        {
            (void)sprintf(log_buffer, "%s/%s", path_priv, bodyfil);
            c |= chk_file_sec(log_buffer, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
        else
        {
            c |= chk_file_sec(bodyfil, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
    }

    if (termfil)
    {
        if (*termfil != '/')
        {
            (void)sprintf(log_buffer, "%s/%s", path_priv, termfil);
            c |= chk_file_sec(log_buffer, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
        else
        {
            c |= chk_file_sec(termfil, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
    }

    if (c) exit(1);

#endif /* not NO_SECURITY_CHECK */
#endif /* not DEBUG */

    if (log_open(logfile, path_log) == -1)
    {
        fprintf(stderr, "%s: logfile could not be opened\n", argv[0]);
        exit(1);
    }

    if (gethostname(host, sizeof(host)) == -1)
    {
        char *prob = "gethostname";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    if ((hp = gethostbyname(host)) == NULL)
    {
        char *prob = "gethostbyname";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        char *prob = "socket";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR,
                   (char *)&t, sizeof(t)) == -1)
    {
        char *prob = "setsockopt";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    saddr.sin_family = AF_INET;

    saddr.sin_port = htons((unsigned short)port);
    memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);

    if (bind(server_sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
    {
        char *prob = "bind";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    if (listen(server_sock, 5) < 0)
    {
        char *prob = "listen";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    okclients = (pbs_net_t *)calloc(START_CLIENTS, sizeof(pbs_net_t));

    addclient("localhost");   /* who has permission to call MOM */
    addclient(host);

    if (configfile)
    {
        if (read_config(configfile) != 0)
            die(0);
    }

    lockfds = open("sched.lock", O_CREAT | O_TRUNC | O_WRONLY, 0644);

    if (lockfds < 0)
    {
        char *prob = "lock file";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    lock_out(lockfds, F_WRLCK);

#ifndef DEBUG
    lock_out(lockfds, F_UNLCK);

    if ((pid = fork()) == -1)       /* error on fork */
    {
        char *prob = "fork";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }
    else if (pid > 0)               /* parent exits */
        exit(0);

    if ((pid = setsid()) == -1)
    {
        log_err(errno, id, "setsid");
        die(0);
    }

    lock_out(lockfds, F_WRLCK);

    freopen(dbfile, "a", stdout);
    setvbuf(stdout, NULL, _IOLBF, 0);
    dup2(fileno(stdout), fileno(stderr));
#else
    pid = getpid();
    setvbuf(stdout, NULL, _IOLBF, 0);
    setvbuf(stderr, NULL, _IOLBF, 0);
#endif
    freopen("/dev/null", "r", stdin);

    /* write schedulers pid into lockfile */
    (void)sprintf(log_buffer, "%d\n", pid);
    (void)write(lockfds, log_buffer, strlen(log_buffer) + 1);

#if (PLOCK_DAEMONS & 2)
    (void)plock(PROCLOCK); /* lock daemon into memory */
#endif

    sprintf(log_buffer, "%s startup pid %d", argv[0], pid);
    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

    sprintf(log_buffer, "%s using TCL %s (%s)", argv[0],
            TCL_VERSION, TCL_PATCH_LEVEL);
    fprintf(stderr, "%s\n", log_buffer);
    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

    fullresp(0);
    sigemptyset(&allsigs);
    act.sa_flags = 0;
    sigaddset(&allsigs, SIGHUP);    /* remember to block these */
    sigaddset(&allsigs, SIGINT);    /* during critical sections */
    sigaddset(&allsigs, SIGTERM);   /* so we don't get confused */
    act.sa_mask = allsigs;

    act.sa_handler = restart;       /* do a restart on SIGHUP */
    sigaction(SIGHUP, &act, NULL);

    act.sa_handler = toolong; /* handle an alarm call */
    sigaction(SIGALRM, &act, NULL);

    act.sa_handler = die;           /* bite the biscuit for all following */
    sigaction(SIGINT, &act, NULL);
    sigaction(SIGTERM, &act, NULL);

    start_tcl();

    FD_ZERO(&fdset);

    for (go = 1; go;)
    {
        unsigned int cmd;


        FD_SET(server_sock, &fdset);

        if (select(FD_SETSIZE, &fdset, NULL, NULL, NULL) == -1)
        {
            if (errno != EINTR)
                log_err(errno, id, "select");

            continue;
        }

        if (!FD_ISSET(server_sock, &fdset))
            continue;

        cmd = server_command();

        if (cmd == (unsigned)SCH_ERROR || cmd == (unsigned)SCH_SCHEDULE_NULL)
            continue;

        if (sigprocmask(SIG_BLOCK, &allsigs, &oldsigs) == -1)
            log_err(errno, id, "sigprocmaskSIG_BLOCK)");

        if (verbose)
        {
            sprintf(log_buffer, "command %d", cmd);
            log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER,
                       id, log_buffer);
        }

        switch (cmd)
        {

        case SCH_SCHEDULE_NEW:

        case SCH_SCHEDULE_TERM:

        case SCH_SCHEDULE_TIME:

        case SCH_SCHEDULE_RECYC:

        case SCH_SCHEDULE_CMD:

        case SCH_SCHEDULE_FIRST:
            alarm(alarm_time);

#if TCL_MAJOR_VERSION >= 8
            /* execute compiled body code for TCL-8 */
            code = Tcl_EvalObj(interp, body_obj);
#else
            code = Tcl_Eval(interp, body);
#endif
            alarm(0);

            switch (code)
            {

            case TCL_OK:

            case TCL_RETURN:
                break;

            default:
            {

                char *trace;
                char  codename[20];

                switch (code)
                {

                case TCL_BREAK:
                    strcpy(codename, "break");
                    break;

                case TCL_CONTINUE:
                    strcpy(codename, "continue");
                    break;

                default:
                    strcpy(codename, "<unknown>");
                    break;
                }

                trace = (char *)Tcl_GetVar(interp, "errorInfo", 0);

                if (trace == NULL)
                    trace = (char *)Tcl_GetStringResult(interp);

                fprintf(stderr, "%s: TCL interpreter return code %d (%s) @ line %d: %s\n",
                        bodyfil, code, codename,
                        interp->errorLine, trace);

                sprintf(log_buffer,
                        "%s: TCL error @ line %d: %s",
                        bodyfil, interp->errorLine,
                        Tcl_GetStringResult(interp));

                log_err(-1, id, log_buffer);

                die(0);
            }
            }

            break;

        case SCH_CONFIGURE:

        case SCH_RULESET:
            restart(0);
            break;

        case SCH_QUIT:
            go = 0;
            break;

        default:
            log_err(-1, id, "unknown command");
            break;
        }

        if (connector >= 0 && server_disconnect(connector))
        {
            log_err(errno, id, "server_disconnect");
            die(0);
        }

        connector = -1;

        if (verbose)
        {
            next_brk = (caddr_t)sbrk(0);

            if (next_brk > curr_brk)
            {
                sprintf(log_buffer, "brk point %p", next_brk);
                log_record(PBSEVENT_SYSTEM,
                           PBS_EVENTCLASS_SERVER,
                           id, log_buffer);
                curr_brk = next_brk;
            }
        }

        if (sigprocmask(SIG_SETMASK, &oldsigs, NULL) == -1)
            log_err(errno, id, "sigprocmask(SIG_SETMASK)");
    }

    if (termfil)
    {
        code = Tcl_EvalFile(interp, termfil);

        if (code != TCL_OK)
        {
            char *trace;

            trace = (char *)Tcl_GetVar(interp, "errorInfo", 0);

            if (trace == NULL)
                trace = (char *)Tcl_GetStringResult(interp);

            fprintf(stderr, "%s: TCL error @ line %d: %s\n",
                    termfil, interp->errorLine, trace);

            sprintf(log_buffer, "%s: TCL error @ line %d: %s",
                    termfil, interp->errorLine,
                    Tcl_GetStringResult(interp));

            log_err(-1, id, log_buffer);

            die(0);
        }

        sprintf(log_buffer, "term file: %s", termfil);

        log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER,
                   id, log_buffer);
    }

    sprintf(log_buffer, "%s normal finish pid %d", argv[0], pid);

    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

    (void)close(server_sock);
    exit(0);
}
Exemple #8
0
int
Extension::foreachCmd (
    ClientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    if (objc != 4) {
	Tcl_WrongNumArgs(
            interp, 1, objv, "varList collectionHandle script");
	return TCL_ERROR;
    }

    Tcl_Obj *pVarList = objv[1];
    Tcl_Obj *pBody = objv[3];

    Reference *pCollection = referenceHandles.find(interp, objv[2]);
    if (pCollection == 0) {
        const char *arg = Tcl_GetStringFromObj(objv[2], 0);
        Tcl_AppendResult(
            interp, "invalid interface pointer handle ", arg, 0);
        return TCL_ERROR;
    }

    // Collections should implement a _NewEnum method which returns an object
    // that enumerates the elements.
    HRESULT hr;
    PositionalArguments arguments;
    _variant_t varResult;

    hr = pCollection->invoke(
        DISPID_NEWENUM,
        DISPATCH_METHOD | DISPATCH_PROPERTYGET,
        arguments,
        &varResult);
    if (FAILED(hr) || V_VT(&varResult) != VT_UNKNOWN) {
	Tcl_AppendResult(interp, "object is not a collection", NULL);
	return TCL_ERROR;
    }
    IUnknownPtr pUnk(V_UNKNOWN(&varResult));
    
    // Get a specific kind of enumeration.
    IEnumVARIANTPtr pEnumVARIANT;
    IEnumUnknownPtr pEnumUnknown;
    enum EnumKind { ENUM_VARIANT, ENUM_UNKNOWN };
    EnumKind enumKind;

    hr = pUnk->QueryInterface(
        IID_IEnumVARIANT, reinterpret_cast<void **>(&pEnumVARIANT));
    if (SUCCEEDED(hr)) {
        enumKind = ENUM_VARIANT;
    } else {
        hr = pUnk->QueryInterface(
            IID_IEnumUnknown, reinterpret_cast<void **>(&pEnumUnknown));
        if (SUCCEEDED(hr)) {
	    enumKind = ENUM_UNKNOWN;
        }
    }
    
    if (FAILED(hr)) {
        Tcl_AppendResult(interp,
            "Unknown enumerator type: not IEnumVARIANT or IEnumUnknown", NULL);
        return TCL_ERROR;
    }

    int completionCode;

    int varc;				// number of loop variables
    completionCode = Tcl_ListObjLength(interp, pVarList, &varc);
    if (completionCode != TCL_OK) {
        return TCL_ERROR;
    }
    if (varc < 1) {
	Tcl_AppendResult(interp, "foreach varlist is empty", NULL);
	return TCL_ERROR;
    }

    while (true) {
        // If the variable list has been converted to another kind of Tcl
        // object, convert it back to a list and refetch the pointer to its
        // element array.
        Tcl_Obj **varv;
        completionCode =
            Tcl_ListObjGetElements(interp, pVarList, &varc, &varv);
        if (completionCode != TCL_OK) {
            return TCL_ERROR;
        }

        // Assign values to all loop variables.
        int v = 0;
	for (;  v < varc;  ++v) {
            TclObject value;
	    ULONG count;

	    switch (enumKind) {
	    case ENUM_VARIANT:
		{
		    _variant_t elementVar;
		    hr = pEnumVARIANT->Next(1, &elementVar, &count);
		    if (hr == S_OK && count > 0) {
			value = TclObject(&elementVar, Type::variant(), interp, 0);
		    }
		}
		break;

	    case ENUM_UNKNOWN:
		{
		    IUnknown *pElement;
		    hr = pEnumUnknown->Next(1, &pElement, &count);
		    if (hr == S_OK && count > 0) {
			value = referenceHandles.newObj(
			    interp, Reference::newReference(pElement));
		    }
		}
		break;
	    }

	    if (FAILED(hr)) {
		_com_issue_error(hr);
	    }
	    if (hr != S_OK || count == 0) {
		break;
	    }

	    Tcl_Obj *varValuePtr = Tcl_ObjSetVar2(
                interp, varv[v], NULL, value, TCL_LEAVE_ERR_MSG);
	    if (varValuePtr == NULL) {
		return TCL_ERROR;
	    }
	}

        if (v == 0) {
            completionCode = TCL_OK;
            break;
        }

        if (v < varc) {
            TclObject empty;

            for (; v < varc;  ++v) {
	        Tcl_Obj *varValuePtr = Tcl_ObjSetVar2(
                    interp, varv[v], NULL, empty, TCL_LEAVE_ERR_MSG);
	        if (varValuePtr == NULL) {
		    return TCL_ERROR;
	        }
            }
        }

        // Execute the script body.
        completionCode =
#if TCL_MINOR_VERSION >= 1
            Tcl_EvalObjEx(interp, pBody, 0);
#else
            Tcl_EvalObj(interp, pBody);
#endif

        if (completionCode == TCL_CONTINUE) {
            // do nothing
        } else if (completionCode == TCL_BREAK) {
            completionCode = TCL_OK;
            break;
        } else if (completionCode == TCL_ERROR) {
	    std::ostringstream oss;
            oss << "\n    (\"foreach\" body line %d)" << interp->errorLine;
            Tcl_AddObjErrorInfo(
                interp, const_cast<char *>(oss.str().c_str()), -1);
            break;
        } else if (completionCode != TCL_OK) {
            break;
        }
    }

    if (completionCode == TCL_OK) {
	Tcl_ResetResult(interp);
    }
    return completionCode;
}