Beispiel #1
0
/*! @decl int match(string str)
 *!
 *! Returns 1 if @[str] matches the regexp bound to the regexp object.
 *! Zero otherwise.
 *!
 *! @decl array(string) match(array(string) strs)
 *!
 *! Returns an array containing strings in @[strs] that match the
 *! regexp bound to the regexp object.
 *!
 *! @bugs
 *!   The current implementation doesn't support searching
 *!   in strings containing the NUL character or any
 *!   wide character.
 *!
 *! @seealso
 *!   @[split]
 */
static void regexp_match(INT32 args)
{
  int i;
  struct regexp *regexp = THIS->regexp;

  if(args < 1)
    SIMPLE_TOO_FEW_ARGS_ERROR("Regexp.SimpleRegexp->match", 1);
  
  if(Pike_sp[-args].type == T_STRING)
  {
    if(Pike_sp[-args].u.string->size_shift)
      SIMPLE_BAD_ARG_ERROR("Regexp.SimpleRegexp->match", 1,
			   "Expected string (8bit)");
    
    i = pike_regexec(regexp, (char *)STR0(Pike_sp[-args].u.string));
    pop_n_elems(args);
    push_int(i);
    return;
  }
  else if(Pike_sp[-args].type == T_ARRAY)
  {
    struct array *arr;
    int i, n;

    arr = Pike_sp[-args].u.array;

    for(i = n = 0; i < arr->size; i++)
    {
      struct svalue *sv = ITEM(arr) + i;
      
      if(sv->type != T_STRING || sv->u.string->size_shift)
	SIMPLE_BAD_ARG_ERROR("Regexp.SimpleRegexp->match", 1,
			     "Expected string (8bit)");

      if(pike_regexec(regexp, (char *)STR0(sv->u.string)))
      {
	ref_push_string(sv->u.string);
	n++;
      }
    }
    
    f_aggregate(n);
    stack_pop_n_elems_keep_top(args);
    return;
  }
  else
    SIMPLE_BAD_ARG_ERROR("Regexp.SimpleRegexp->match", 1,
			 "string|array(string)");
}
Beispiel #2
0
void image_xbm_encode( INT32 args )
{
  struct image *img = NULL;
  struct pike_string *name = NULL, *buf;
  if (!args)
    Pike_error("Image.XBM.encode: too few arguments\n");
   
  if (Pike_sp[-args].type!=PIKE_T_OBJECT ||
      !(img=(struct image*)
        get_storage(Pike_sp[-args].u.object,image_program)))
    Pike_error("Image.XBM.encode: illegal argument 1\n");
   
  if (!img->img)
    Pike_error("Image.XBM.encode: no image\n");

  if (args>1)
  {
    if (Pike_sp[1-args].type!=PIKE_T_MAPPING)
      Pike_error("Image.XBM.encode: illegal argument 2\n");
      
    push_svalue(Pike_sp+1-args);
    ref_push_string(param_name); 
    f_index(2);
    if(Pike_sp[-1].type == PIKE_T_STRING)
    {
      if(Pike_sp[-1].u.string->size_shift)
        Pike_error("The name of the image must be a normal non-wide string (sorry, not my fault)\n");
      name = Pike_sp[-1].u.string;
    }
    pop_stack();
  }

  buf = save_xbm( img, name );
  pop_n_elems(args);
  push_string( buf );
}
Beispiel #3
0
static void f_create_process( INT32 args ) {
  struct perishables storage;
  struct array *cmd = 0;
  struct mapping *optional = 0;
  struct svalue *tmp;
  int e;
  int stds[3];
  int *fds;
  int num_fds = 3;
  int wanted_gid=0, wanted_uid=0;
  int gid_request=0, uid_request=0;
  char *tmp_cwd = NULL;
  pid_t pid=-2;

  extern char **environ;

  fds = stds;
  storage.env = NULL;
  storage.argv = NULL;
  storage.disabled = 0;
  storage.fds = NULL;
  storage.limits = NULL;

  check_all_args("create_process",args, BIT_ARRAY, BIT_MAPPING | BIT_VOID, 0);

  switch(args)
  {
    default:
      optional=Pike_sp[1-args].u.mapping;
      mapping_fix_type_field(optional);

      if(m_ind_types(optional) & ~BIT_STRING)
        Pike_error("Bad index type in argument 2 to Caudium.create_process()\n");

    case 1: cmd=Pike_sp[-args].u.array;
      if(cmd->size < 1)
        Pike_error("Too few elements in argument array.\n");

      for(e=0; e<cmd->size; e++)
        if(ITEM(cmd)[e].type!=T_STRING)
          Pike_error("Argument is not a string.\n");

      array_fix_type_field(cmd);

      if(cmd->type_field & ~BIT_STRING)
        Pike_error("Bad argument 1 to Caudium.create_process().\n");
  }

  if (optional) {

     if ((tmp = simple_mapping_string_lookup(optional, "gid"))) {
        switch(tmp->type)
	{
	  case T_INT:
	    wanted_gid = tmp->u.integer;
	    gid_request = 1;
	    break;

	  default:
	    Pike_error("Invalid argument for gid.");
	    break;
	}
     } 

     if ((tmp = simple_mapping_string_lookup(optional, "uid"))) {
        switch(tmp->type)
	{
	  case T_INT:
	    wanted_uid = tmp->u.integer;
	    uid_request = 1;
	    break;

	  default:
	    Pike_error("Invalid argument for uid.");
	    break;
	}
     } 

     if((tmp = simple_mapping_string_lookup( optional, "cwd" )) &&
	 tmp->type == T_STRING && !tmp->u.string->size_shift)
       tmp_cwd = tmp->u.string->str;

     if((tmp = simple_mapping_string_lookup( optional, "stdin" )) &&
         tmp->type == T_OBJECT)
     {
        fds[0] = fd_from_object( tmp->u.object );
        if(fds[0] == -1)
          Pike_error("Invalid stdin file\n");
     }

     if((tmp = simple_mapping_string_lookup( optional, "stdout" )) &&
         tmp->type == T_OBJECT)
     {
        fds[1] = fd_from_object( tmp->u.object );
        if(fds[1] == -1)
          Pike_error("Invalid stdout file\n");
     }

     if((tmp = simple_mapping_string_lookup( optional, "stderr" )) &&
         tmp->type == T_OBJECT)
     {
        fds[2] = fd_from_object( tmp->u.object );
        if(fds[2] == -1)
          Pike_error("Invalid stderr file\n");
     }

     if((tmp=simple_mapping_string_lookup(optional, "rlimit"))) {
        struct svalue *tmp2;
        if(tmp->type != T_MAPPING)
          Pike_error("Wrong type of argument for the 'rusage' option. "
		     "Should be mapping.\n");
#define ADD_LIMIT(X,Y,Z) internal_add_limit(&storage,X,Y,Z);
#ifdef RLIMIT_NPROC
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "nproc")))
        ADD_LIMIT( "nproc", RLIMIT_NPROC, tmp2 );
#endif        
#ifdef RLIMIT_MEMLOCK
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "memlock")))
        ADD_LIMIT( "memlock", RLIMIT_MEMLOCK, tmp2 );
#endif        
#ifdef RLIMIT_RSS
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "rss")))
        ADD_LIMIT( "rss", RLIMIT_RSS, tmp2 );
#endif        
#ifdef RLIMIT_CORE
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "core")))
        ADD_LIMIT( "core", RLIMIT_CORE, tmp2 );
#endif        
#ifdef RLIMIT_CPU
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "cpu")))
        ADD_LIMIT( "cpu", RLIMIT_CPU, tmp2 );
#endif        
#ifdef RLIMIT_DATA
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "data")))
        ADD_LIMIT( "data", RLIMIT_DATA, tmp2 );
#endif        
#ifdef RLIMIT_FSIZE
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "fsize")))
        ADD_LIMIT( "fsize", RLIMIT_FSIZE, tmp2 );
#endif        
#ifdef RLIMIT_NOFILE
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "nofile")))
        ADD_LIMIT( "nofile", RLIMIT_NOFILE, tmp2 );
#endif        
#ifdef RLIMIT_STACK
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "stack")))
        ADD_LIMIT( "stack", RLIMIT_STACK, tmp2 );
#endif        
#ifdef RLIMIT_VMEM
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "map_mem"))
         ||(tmp2=simple_mapping_string_lookup(tmp->u.mapping, "vmem")))
        ADD_LIMIT( "map_mem", RLIMIT_VMEM, tmp2 );
#endif        
#ifdef RLIMIT_AS
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "as"))
         ||(tmp2=simple_mapping_string_lookup(tmp->u.mapping, "mem")))
        ADD_LIMIT( "mem", RLIMIT_AS, tmp2 );
#endif
#undef ADD_LIMIT
     }
  }

  if((tmp=simple_mapping_string_lookup(optional, "env"))) {
    if(tmp->type == T_MAPPING) {
      struct mapping *m=tmp->u.mapping;
      struct array *i,*v;
      int ptr=0;
      i=mapping_indices(m);
      v=mapping_values(m);

      storage.env=(char **)xalloc((1+m_sizeof(m)) * sizeof(char *));
      for(e=0;e<i->size;e++)
      {
        if(ITEM(i)[e].type == T_STRING &&
           ITEM(v)[e].type == T_STRING)
        {
          check_stack(3);
          ref_push_string(ITEM(i)[e].u.string);
          push_string(make_shared_string("="));
          ref_push_string(ITEM(v)[e].u.string);
          f_add(3);
          storage.env[ptr++]=Pike_sp[-1].u.string->str;
        }
      }
      storage.env[ptr++]=0;
      free_array(i);
      free_array(v);
    }
  }

  storage.argv = (char **)xalloc((1 + cmd->size) * sizeof(char *));
  for (e = 0; e < cmd->size; e++) storage.argv[e] = ITEM(cmd)[e].u.string->str;
  storage.argv[e] = 0;
  
  th_atfork_prepare();
  
  pid = fork();

  if (pid) {
     th_atfork_parent();
  } else {
     th_atfork_child();
  }

  if (pid == -1) {
     Pike_error("Caudium.create_process() failed.");
  } else if (pid) {
    
    pop_n_elems(args);
    push_int(pid);
    return;

  } else {

    if(storage.limits) {
      struct plimit *l = storage.limits;
      while(l) {
        int tmpres = setrlimit( l->resource, &l->rlp );
        l = l->next;
      }
    }

    if(storage.env) environ = storage.env;

    chdir(tmp_cwd);

    seteuid(0);
    setegid(0);

    setgroups(0, NULL);

    if (gid_request) setgid(wanted_gid);
    if (uid_request) setuid(wanted_uid);
    
    dup2(fds[0], 0);
    dup2(fds[1], 1);
    dup2(fds[2], 2);
	  
    set_close_on_exec(0,0);
    set_close_on_exec(1,0);
    set_close_on_exec(2,0);

    execvp(storage.argv[0],storage.argv);

    exit(99);
  }

  pop_n_elems(args);
  push_int(0);
}
Beispiel #4
0
static void f_read( INT32 args )
{
  char *read_buf;
  struct svalue *logfun, *file;
  FD f = -1;
  int cls, c, my_fd=1, state=0, tzs=0;
  char *char_pointer;
  INT32 v=0, yy=0, mm=0, dd=0, h=0, m=0, s=0, tz=0;
  ptrdiff_t offs0=0, len=0;
  struct svalue *old_sp;
  /* #define DYNAMIC_BUF */
#ifdef DYNAMIC_BUF
  dynamic_buffer buf;
#else
#define BUFSET(X) do { if(bufpos == bufsize) { bufsize *= 2; buf = realloc(buf, bufsize+1); } buf[bufpos++] = c; } while(0)
#define PUSHBUF() do { push_string( make_shared_binary_string( buf,bufpos ) ); bufpos=0; } while(0)
  char *buf;
  int bufsize=CLF_BLOCK_SIZE, bufpos=0;
#endif

  if(args>2 && sp[-1].type == T_INT) {
    offs0 = sp[-1].u.integer;
    pop_n_elems(1);
    --args;
  }
  old_sp = sp;

  get_all_args("CommonLog.read", args, "%*%*", &logfun, &file);
  if(logfun->type != T_FUNCTION)
    SIMPLE_BAD_ARG_ERROR("CommonLog.read", 1, "function");

  if(file->type == T_OBJECT)
  {
    f = fd_from_object(file->u.object);
    
    if(f == -1)
      Pike_error("CommonLog.read: File is not open.\n");
    my_fd = 0;
  } else if(file->type == T_STRING &&
	    file->u.string->size_shift == 0) {
#ifdef PIKE_SECURITY
      if(!CHECK_SECURITY(SECURITY_BIT_SECURITY))
      {
	if(!CHECK_SECURITY(SECURITY_BIT_CONDITIONAL_IO))
	  Pike_error("Permission denied.\n");
	push_text("read");
	push_int(0);
	ref_push_string(file->u.string);
	push_text("r");
	push_int(00666);

	safe_apply(OBJ2CREDS(CURRENT_CREDS)->user,"valid_open",5);
	switch(Pike_sp[-1].type)
	{
	case PIKE_T_INT:
	  switch(Pike_sp[-1].u.integer)
	  {
	  case 0: /* return 0 */
	    errno=EPERM;
	    Pike_error("CommonLog.read(): Failed to open file for reading (errno=%d).\n",
		       errno);

	  case 2: /* ok */
	    pop_stack();
	    break;

	  case 3: /* permission denied */
	    Pike_error("CommonLog.read: permission denied.\n");

	  default:
	    Pike_error("Error in user->valid_open, wrong return value.\n");
	  }
	  break;

	default:
	  Pike_error("Error in user->valid_open, wrong return type.\n");

	case PIKE_T_STRING:
	  /*	  if(Pike_sp[-1].u.string->shift_size) */
	  /*	    file=Pike_sp[-1]; */
	  pop_stack();
	}

      }
#endif
    do {
      THREADS_ALLOW();
      f=fd_open((char *)STR0(file->u.string), fd_RDONLY, 0);
      THREADS_DISALLOW();
      if (f >= 0 || errno != EINTR) break;
      check_threads_etc();
    } while (1);

    if(f < 0)
      Pike_error("CommonLog.read(): Failed to open file for reading (errno=%d).\n",
	    errno);
  } else
    SIMPLE_BAD_ARG_ERROR("CommonLog.read", 2, "string|Stdio.File");

#ifdef HAVE_LSEEK64
  lseek64(f, offs0, SEEK_SET);
#else
  fd_lseek(f, offs0, SEEK_SET);
#endif
  read_buf = malloc(CLF_BLOCK_SIZE+1);
#ifndef DYNAMIC_BUF
  buf = malloc(bufsize);
#endif
  while(1) {
    do {
      THREADS_ALLOW();
      len = fd_read(f, read_buf, CLF_BLOCK_SIZE);
      THREADS_DISALLOW();
      if (len >= 0 || errno != EINTR) break;
      check_threads_etc();
    } while (1);
    if(len == 0)
      break; /* nothing more to read. */
    if(len < 0)
      break;
    char_pointer = read_buf;
    while(len--) {
      offs0++;
      c = char_pointer[0] & 0xff;
      char_pointer ++;
      cls = char_class[c];
#ifdef TRACE_DFA
      fprintf(stderr, "DFA(%d): '%c' ", state, (c<32? '.':c));
      switch(cls) {
      case CLS_WSPACE: fprintf(stderr, "CLS_WSPACE"); break;
      case CLS_CRLF: fprintf(stderr, "CLS_CRLF"); break;
      case CLS_TOKEN: fprintf(stderr, "CLS_TOKEN"); break;
      case CLS_DIGIT: fprintf(stderr, "CLS_DIGIT"); break;
      case CLS_QUOTE: fprintf(stderr, "CLS_QUOTE"); break;
      case CLS_LBRACK: fprintf(stderr, "CLS_LBRACK"); break;
      case CLS_RBRACK: fprintf(stderr, "CLS_RBRACK"); break;
      case CLS_SLASH: fprintf(stderr, "CLS_SLASH"); break;
      case CLS_COLON: fprintf(stderr, "CLS_COLON"); break;
      case CLS_HYPHEN: fprintf(stderr, "CLS_HYPHEN"); break;
      case CLS_PLUS: fprintf(stderr, "CLS_PLUS"); break;
      default: fprintf(stderr, "???");
      }
      fprintf(stderr, " %d items on stack\n", sp-old_sp);
#endif
      switch(state) {
      case 0:
	if(sp != old_sp) {
	  if(sp == old_sp+15) {
	    f_aggregate(15);
	    push_int64(offs0);
	    apply_svalue(logfun, 2);
	    pop_stack();
	  } else
	    pop_n_elems(sp-old_sp);
	}
	if(cls > CLS_CRLF) {
	  if(cls == CLS_HYPHEN) {
	    push_int(0);
	    state = 2;
	    break;
	  }
#ifdef DYNAMIC_BUF
	  buf.s.str = NULL;
	  initialize_buf( &buf );
	  low_my_putchar( c, &buf );
#else
	  bufpos = 0;
	  BUFSET(c);
#endif
	  state=1;
	}
	break;
      case 1:
	if(cls > CLS_CRLF) {
#ifdef DYNAMIC_BUF
	  low_my_putchar( c, &buf );
#else
	  BUFSET(c);
#endif
	  break;
	}
#ifdef DYNAMIC_BUF
	push_string( low_free_buf( &buf ) ); /* remotehost */
#else
	PUSHBUF();
#endif
	state = (cls == CLS_WSPACE? 2:0);
	break;
      case 2:
	if(cls > CLS_CRLF) {
	  if(cls == CLS_HYPHEN) {
	    push_int(0);
	    state = 4;
	    break;
	  }
#ifdef DYNAMIC_BUF
	  buf.s.str = NULL;
	  initialize_buf( &buf );
	  low_my_putchar( c, &buf );
#else
	  bufpos = 0;
	  BUFSET(c);
#endif

	  state=3;
	} else if(cls == CLS_CRLF)
	  state=0;
	break;
      case 3:
	if(cls > CLS_CRLF) {
#ifdef DYNAMIC_BUF
	  low_my_putchar( c, &buf );
#else
	  BUFSET(c);
#endif

	  break;
	}
#ifdef DYNAMIC_BUF
	push_string( low_free_buf( &buf ) ); /* rfc931 */
#else
	PUSHBUF(); /* rfc931 */
#endif
	state = (cls == CLS_WSPACE? 4:0);
	break;
      case 4:
	if(cls > CLS_CRLF) {
	  if(cls == CLS_HYPHEN) {
	    push_int(0);
	    state = 6;
	    break;
	  }
#ifdef DYNAMIC_BUF
	  buf.s.str = NULL;
	  initialize_buf( &buf );
	  low_my_putchar( c, &buf );
#else
	  bufpos = 0;
	  BUFSET(c);
#endif

	  state=5;
	} else if(cls == CLS_CRLF)
	  state=0;
	break;
      case 5:
	if(cls > CLS_CRLF) {
#ifdef DYNAMIC_BUF
	  low_my_putchar( c, &buf );
#else
	  BUFSET(c);
#endif

	  break;
	}
#ifdef DYNAMIC_BUF
	push_string( low_free_buf( &buf ) ); /* authuser */
#else
	PUSHBUF(); /* authuser */
#endif
	state = (cls == CLS_WSPACE? 6:0);
	break;
      case 6:
	if(cls == CLS_LBRACK)
	  state = 15;
	else if(cls == CLS_CRLF)
	  state = 0;
	else if(cls == CLS_HYPHEN) {
	  push_int(0);
	  push_int(0);
	  push_int(0);
	  state = 7;
	}
	break;
      case 7:
	if(cls == CLS_QUOTE) {
#ifdef DYNAMIC_BUF
	  buf.s.str = NULL;
	  initialize_buf( &buf );
#else
	  bufpos = 0;
#endif
	  state = 31;
	} else if(cls == CLS_CRLF)
	  state = 0;
	else if(cls == CLS_HYPHEN) {
	  push_int(0);
	  push_int(0);
	  push_int(0);
	  state = 10;
	}
	break;
      case 8:
	if(cls == CLS_QUOTE)
	  state = 9;
	else if(cls == CLS_CRLF) {
#ifdef DYNAMIC_BUF
	  push_string( low_free_buf( &buf ) );
#else
	  PUSHBUF();
#endif
	  state = 0;
	} else
#ifdef DYNAMIC_BUF
	  low_my_putchar( c, &buf );
#else
	  BUFSET(c);
#endif

	break;
      case 9:
	if(cls > CLS_CRLF) {
#ifdef DYNAMIC_BUF
	  low_my_putchar( '"', &buf);
	  low_my_putchar( c, &buf);
#else
	  BUFSET('"');
	  BUFSET(c);
#endif
	  state = 8;
	  break;
	}
#ifdef DYNAMIC_BUF
	push_string( low_free_buf( &buf ) ); /* protocol */
#else
	PUSHBUF(); /* protoocl */
#endif
	state = (cls == CLS_CRLF? 0 : 10);
	break;
      case 10:
	if(cls == CLS_DIGIT) {
	  v = c&0xf;
	  state = 11;
	} else if(cls == CLS_CRLF)
	  state = 0;
	else if(cls == CLS_HYPHEN) {
	  push_int(0);
	  state = 12;
	}
	break;
      case 11:
	if(cls == CLS_DIGIT)
	  v = v*10+(c&0xf);
	else if(cls == CLS_WSPACE) {
	  push_int(v); /* status */
	  state = 12;
	} else state = 0;
	break;
      case 12:
	if(cls == CLS_DIGIT) {
	  v = c&0xf;
	  state = 13;
	} else if(cls == CLS_CRLF)
	  state = 0;
	else if(cls == CLS_HYPHEN) {
	  push_int(0);
	  state = 14;
	}
	break;
      case 13:
	if(cls == CLS_DIGIT)
	  v = v*10+(c&0xf);
	else {
	  push_int(v); /* bytes */
	  state = (cls == CLS_CRLF? 0:14);
	}
	break;
      case 14:
	if(cls == CLS_CRLF)
	  state = 0;
	break;

      case 15:
	if(cls == CLS_DIGIT) {
	  dd = c&0xf;
	  state = 16;
	} else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 16:
	/* getting day */
	if(cls == CLS_DIGIT)
	  dd = dd*10+(c&0xf);
	else if(cls == CLS_SLASH)
	  state = 17;
	else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 17:
	if(cls == CLS_DIGIT) {
	  mm = c&0xf;
	  state = 18;
	} else if(cls == CLS_TOKEN) {
	  mm = c|0x20;
	  state = 21;
	} else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 18:
	/* getting numeric month */
	if(cls == CLS_DIGIT)
	  mm = mm*10+(c&0xf);
	else if(cls == CLS_SLASH)
	  state = 19;
	else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 19:
	if(cls == CLS_DIGIT) {
	  yy = c&0xf;
	  state = 20;
	} else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 20:
	/* getting year */
	if(cls == CLS_DIGIT)
	  yy = yy*10+(c&0xf);
	else if(cls == CLS_COLON)
	  state = 22;
	else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 21:
	/* getting textual month */
	if(cls == CLS_TOKEN)
	  mm = (mm<<8)|c|0x20;
	else if(cls == CLS_SLASH) {
	  state = 19;
	  switch(mm) {
	  case ('j'<<16)|('a'<<8)|'n': mm=1; break;
	  case ('f'<<16)|('e'<<8)|'b': mm=2; break;
	  case ('m'<<16)|('a'<<8)|'r': mm=3; break;
	  case ('a'<<16)|('p'<<8)|'r': mm=4; break;
	  case ('m'<<16)|('a'<<8)|'y': mm=5; break;
	  case ('j'<<16)|('u'<<8)|'n': mm=6; break;
	  case ('j'<<16)|('u'<<8)|'l': mm=7; break;
	  case ('a'<<16)|('u'<<8)|'g': mm=8; break;
	  case ('s'<<16)|('e'<<8)|'p': mm=9; break;
	  case ('o'<<16)|('c'<<8)|'t': mm=10; break;
	  case ('n'<<16)|('o'<<8)|'v': mm=11; break;
	  case ('d'<<16)|('e'<<8)|'c': mm=12; break;
	  default:
	    state = 14;
	  }
	}
	break;
      case 22:
	if(cls == CLS_DIGIT) {
	  h = c&0xf;
	  state = 23;
	} else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 23:
	/* getting hour */
	if(cls == CLS_DIGIT)
	  h = h*10+(c&0xf);
	else if(cls == CLS_COLON)
	  state = 24;
	else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 24:
	if(cls == CLS_DIGIT) {
	  m = c&0xf;
	  state = 25;
	} else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 25:
	/* getting minute */
	if(cls == CLS_DIGIT)
	  m = m*10+(c&0xf);
	else if(cls == CLS_COLON)
	  state = 26;
	else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 26:
	if(cls == CLS_DIGIT) {
	  s = c&0xf;
	  state = 27;
	} else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 27:
	/* getting second */
	if(cls == CLS_DIGIT)
	  s = s*10+(c&0xf);
	else if(cls == CLS_WSPACE)
	  state = 28;
	else
	  state = (cls == CLS_CRLF? 0:14);
	break;
      case 28:
	if(cls>=CLS_HYPHEN) {
	  state = 29;
	  tzs = cls!=CLS_PLUS;
	  tz = 0;
	} else if(cls == CLS_DIGIT) {
	  state = 29;
	  tzs = 0;
	  tz = c&0xf;
	} else if(cls==CLS_CRLF)
	  state = 0;
	break;
      case 29:
	/* getting timezone */
	if(cls == CLS_DIGIT)
	  tz = tz*10+(c&0xf);
	else {
	  if(tzs)
	    tz = -tz;
	  push_int(yy);
	  push_int(mm);
	  push_int(dd);
	  push_int(h);
	  push_int(m);
	  push_int(s);
	  push_int(tz);
	  if(cls == CLS_RBRACK)
	    state = 7;
	  else
	    state = (cls == CLS_CRLF? 0 : 30);
	}
	break;
      case 30:
	if(cls == CLS_RBRACK)
	  state = 7;
	else if(cls == CLS_CRLF)
	  state = 0;
	break;
      case 31:
	if(cls == CLS_QUOTE) {
#ifdef DYNAMIC_BUF
	  push_string( low_free_buf( &buf ) );
#else
	  PUSHBUF();
#endif
	  push_int(0);
	  push_int(0);
	  state = 10;
	} else if(cls >= CLS_TOKEN)
#ifdef DYNAMIC_BUF
	  low_my_putchar( c, &buf );
#else
	  BUFSET(c);
#endif

	else {
#ifdef DYNAMIC_BUF
	  push_string( low_free_buf( &buf ) ); /* method */
#else
	  PUSHBUF(); /* method */
#endif
	  state = (cls == CLS_CRLF? 0 : 32);
	}
	break;
      case 32:
	if(cls == CLS_QUOTE) {
	  push_int(0);
	  push_int(0);
	  state = 10;
	} else if(cls >= CLS_TOKEN) {
#ifdef DYNAMIC_BUF
	  buf.s.str = NULL;
	  initialize_buf( &buf );
	  low_my_putchar( c, &buf );
#else
	  bufpos = 0;
	  BUFSET(c);
#endif

	  state = 33;
	} else
	  if(cls == CLS_CRLF)
	    state = 0;
	break;
      case 33:
	if(cls == CLS_QUOTE)
	  state = 34;
	else if(cls == CLS_CRLF) {
#ifdef DYNAMIC_BUF
	  push_string( low_free_buf( &buf ) ); 
#else
	  PUSHBUF(); 
#endif
	  state = 0;
	} else if(cls == CLS_WSPACE) {
#ifdef DYNAMIC_BUF
	  push_string( low_free_buf( &buf ) );  /* path */
#else
	  PUSHBUF();  /* path */
#endif
	  state = 35;
	} else	
#ifdef DYNAMIC_BUF
	  low_my_putchar( c, &buf );
#else
	  BUFSET(c);
#endif

	break;
      case 34:
	if(cls >= CLS_TOKEN) {
#ifdef DYNAMIC_BUF
	  low_my_putchar( '"', &buf );
	  low_my_putchar( c, &buf );
#else
	  BUFSET('"');
	  BUFSET(c);
#endif

	  state = 33;
	} else if(cls == CLS_CRLF) {
#ifdef DYNAMIC_BUF
	  push_string( low_free_buf( &buf ) ); 
#else
	  PUSHBUF(); 
#endif
	  state = 0;
	} else {
#ifdef DYNAMIC_BUF
	  push_string( low_free_buf( &buf ) ); 
#else
	  PUSHBUF(); 
#endif
	  push_text("HTTP/0.9");
	  state = 10;
	}
	break;
      case 35:
	if(cls == CLS_QUOTE) {
	  push_text("HTTP/0.9");
	  state = 10;
	} else if(cls >= CLS_TOKEN) {
#ifdef DYNAMIC_BUF
	  buf.s.str = NULL;
	  initialize_buf( &buf );
	  low_my_putchar( c, &buf );
#else
	  bufpos = 0;
	  BUFSET(c);
#endif

	  state = 8;
	} else
	  if(cls == CLS_CRLF)
	    state = 0;
	break;
      }
    }
  }
Beispiel #5
0
static void image_xbm__decode( INT32 args )
{
  struct array *fg = NULL;
  struct array *bg = NULL;
  int invert=0, ele;
  struct pike_string *data;
  struct object *i=NULL, *a;
  get_all_args( "Image.XBM.decode", args, "%S", &data );


  if (args>1)
  {
    if (Pike_sp[1-args].type!=PIKE_T_MAPPING)
      Pike_error("Image.XBM._decode: illegal argument 2\n");
      
    push_svalue(Pike_sp+1-args);
    ref_push_string(param_fg); 
    f_index(2);
    if(!UNSAFE_IS_ZERO(Pike_sp-1))
    {
      if(Pike_sp[-1].type != PIKE_T_ARRAY || Pike_sp[-1].u.array->size != 3)
        Pike_error("Wrong type for foreground. Should be array(int(0..255))"
              " with 3 elements\n");
      for(ele=0; ele<3; ele++)
        if(Pike_sp[-1].u.array->item[ele].type != PIKE_T_INT
           ||Pike_sp[-1].u.array->item[ele].u.integer < 0
           ||Pike_sp[-1].u.array->item[ele].u.integer > 255)
          Pike_error("Wrong type for foreground. Should be array(int(0..255))"
                " with 3 elements\n");
      fg = Pike_sp[-1].u.array;
    }
    Pike_sp--;

    push_svalue(Pike_sp+1-args);
    ref_push_string(param_bg);
    f_index(2);
    if(!UNSAFE_IS_ZERO(Pike_sp-1))
    {
      if(Pike_sp[-1].type != PIKE_T_ARRAY || Pike_sp[-1].u.array->size != 3)
        Pike_error("Wrong type for background. Should be array(int(0..255))"
              " with 3 elements\n");
      for(ele=0; ele<3; ele++)
        if(Pike_sp[-1].u.array->item[ele].type != PIKE_T_INT
           ||Pike_sp[-1].u.array->item[ele].u.integer < 0
           ||Pike_sp[-1].u.array->item[ele].u.integer > 255)
          Pike_error("Wrong type for background. Should be array(int(0..255))"
                " with 3 elements\n");
      bg = Pike_sp[-1].u.array;
    }
    Pike_sp--;
    
    push_svalue(Pike_sp+1-args);
    ref_push_string(param_invert);
    f_index(2);
    invert = !UNSAFE_IS_ZERO(Pike_sp-1);
    Pike_sp--;
  }

  a = load_xbm( data );

  if(!fg)
  {
    if(invert)
    {
      apply(a, "invert", 0);
      i = (struct object *)debug_malloc_pass(Pike_sp[-1].u.object);
      Pike_sp--;
    }
    else
    {
      i = a;
      add_ref(a);
    }
  } else {
    if(!bg)
    {
      push_int(255);
      push_int(255);
      push_int(255);
      f_aggregate(3);
      bg = (struct array *)debug_malloc_pass(Pike_sp[-1].u.array);
      Pike_sp--;
    }
    if(invert)
    {
      struct array *tmp = fg;
      fg = bg;
      bg = fg;
    }
    apply(a, "xsize", 0);
    apply(a, "ysize", 0);
    push_int( bg->item[0].u.integer );
    push_int( bg->item[1].u.integer );
    push_int( bg->item[2].u.integer );
    i = clone_object( image_program, 5 );
    ref_push_object( i );
    push_int( fg->item[0].u.integer );
    push_int( fg->item[1].u.integer );
    push_int( fg->item[2].u.integer );

    apply( i, "paste_alpha_color", 4 );
  }
  
  pop_n_elems(args);
  push_constant_text( "alpha" );
  push_object( a );
    push_constant_text( "image" );
  if(i)
    push_object( i );
  else
    push_int( 0 );
  f_aggregate_mapping(4);
}