コード例 #1
0
ファイル: search.c プロジェクト: hww3/pexts
/* void destroy(void) */
static void f_destroy(INT32 args)
{
  int n;
  GET_PIKE_SEARCH();
  THREADS_ALLOW();
  n = avs_search_close(search->handle);
  THREADS_DISALLOW();
  if (n != AVS_OK)
    Pike_error("Search->destroy(): %s\n", avs_errmsg(n));

  pop_n_elems(args);
}
コード例 #2
0
ファイル: search.c プロジェクト: hww3/pexts
/* string get_docid() */
static void f_get_docid(INT32 args)
{
  char *docid;
  GET_PIKE_SEARCH();
  if (args)
    Pike_error("Too many arguments to Search->get_docid()\n");

  THREADS_ALLOW();
  docid = avs_search_getdocid(search->handle);
  THREADS_DISALLOW();

  push_text(docid);
}
コード例 #3
0
ファイル: search.c プロジェクト: hww3/pexts
/* float get_relevance() */
static void f_get_relevance(INT32 args)
{
  float relevance;
  GET_PIKE_SEARCH();
  if (args)
    Pike_error("Too many arguments to Search->get_relevance()\n");

  THREADS_ALLOW();
  relevance = avs_search_getrelevance(search->handle);
  THREADS_DISALLOW();

  push_float(relevance);
}
コード例 #4
0
ファイル: socket.c プロジェクト: pikelang/Pike
static void port_accept(INT32 args)
{
  PIKE_SOCKADDR addr;
  struct port *this=THIS;
  int fd, err;
  ACCEPT_SIZE_T len=0;
  int one = 1;

  if(this->box.fd < 0)
    Pike_error("port->accept(): Port not open.\n");

  /* FIXME: Race. */
  THIS->box.revents = 0;

  THREADS_ALLOW();
  len=sizeof(addr);
  do {
    fd=fd_accept(this->box.fd, (struct sockaddr *)&addr, &len);
    err = errno;
  } while (fd < 0 && err == EINTR);
  THREADS_DISALLOW();
  INVALIDATE_CURRENT_TIME();

  if(fd < 0)
  {
    this->my_errno=errno = err;
    pop_n_elems(args);
    push_int(0);
    return;
  }

  /* We don't really care if setsockopt fails, since it's just a hint. */
  while ((fd_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
			(char *)&one, sizeof(int)) < 0) &&
	 (errno == EINTR))
    one = 1;

  my_set_close_on_exec(fd,1);
  push_new_fd_object(port_fd_factory_fun_num,
		     fd, FILE_READ | FILE_WRITE, SOCKET_CAPABILITIES);

  if (this->box.backend) {
    struct object *o = Pike_sp[-1].u.object;
    struct my_file *f = (struct my_file *)
      (o->storage + o->prog->inherits[SUBTYPEOF(Pike_sp[-1])].storage_offset);
    change_backend_for_box(&f->box, this->box.backend);
  }

  stack_pop_n_elems_keep_top(args);
}
コード例 #5
0
ファイル: search.c プロジェクト: hww3/pexts
/* string get_data() */
static void f_get_data(INT32 args)
{
  char *data;
  int len;
  GET_PIKE_SEARCH();
  if (args)
    Pike_error("Too many arguments to Search->get_data()\n");
  THREADS_ALLOW();
  len  = avs_search_getdatalen(search->handle);
  data = avs_search_getdata(search->handle);
  THREADS_DISALLOW();

  push_string(make_shared_binary_string(data, len));
}
コード例 #6
0
ファイル: search.c プロジェクト: hww3/pexts
/* void get_result(int result) */
static void f_get_result(INT32 args)
{
  int n, result;
  GET_PIKE_SEARCH();
  get_all_args("Search->get_result()", args, "%i", &result);

  THREADS_ALLOW();
  n = avs_getsearchresults(search->handle, result);
  THREADS_DISALLOW();
  if (n != AVS_OK)
    Pike_error("Search->get_result(): %s\n", avs_errmsg(n));

  pop_n_elems(args);
}
コード例 #7
0
ファイル: image_ttf.c プロジェクト: ajinkya007/pike-1
static void ttf_translate_16bit(TT_CharMap charMap,
				unsigned short *what,
				int **dest,
				int len,
				int base)
{
   int i;

   dest[0]=(int*)xalloc(len*sizeof(int));

   THREADS_ALLOW();
   for (i=0; i<len; i++)
      dest[0][i] = TT_Char_Index(charMap, (TT_UShort)(what[i] + base));
   THREADS_DISALLOW();
}
コード例 #8
0
ファイル: search.c プロジェクト: hww3/pexts
/* string get_version() */
static void f_get_version(INT32 args)
{
  int n;
  char version[AVS_SEARCHVERSION_MAXLEN]; 
  GET_PIKE_SEARCH();
  if (args)
    Pike_error("Too many arguments to Search->get_version()\n");

  THREADS_ALLOW();
  n = avs_getsearchversion(search->handle, version);
  THREADS_DISALLOW();
  if (n != AVS_OK)
    Pike_error("Search->get_version(): %s\n", avs_errmsg(n));

  push_text(version);
}
コード例 #9
0
ファイル: orient.c プロジェクト: pikelang/Pike
static void _image_orient(struct image *source,
			  struct object *o[5],
			  struct image *img[5])
{
   int i;
   struct { int x,y; } or[4]={ {1,0}, {1,1}, {0,1}, {-1,1} };
   int x,y;

   for (i=0; i<5; i++)
   {
      push_int(source->xsize);
      push_int(source->ysize);
      o[i]=clone_object(image_program,2);
      img[i]=get_storage(o[i],image_program);
      push_object(o[i]);
   }

THREADS_ALLOW();
CHRONO("start");
   for (i=0; i<4; i++) /* four directions */
   {
      rgb_group *d=img[i]->img;
      rgb_group *s=source->img;
      int xz=source->xsize;
      int yz=source->ysize;
      int xd=or[i].x;
      int yd=or[i].y;

      for(x=1; x<xz-1; x++)
	 for(y=1; y<yz-1; y++)
	 {
#define FOOBAR(CO) \
  d[x+y*xz].CO \
     = \
  (COLORTYPE) \
     my_abs( s[(x+xd)+(y+yd)*xz].CO - s[(x-xd)+(y-yd)*xz].CO )

	    FOOBAR(r);
	    FOOBAR(g);
	    FOOBAR(b);

#undef FOOBAR
	 }
   }
CHRONO("end");
THREADS_DISALLOW();
}
コード例 #10
0
ファイル: search.c プロジェクト: hww3/pexts
/* array get_date() */
static void f_get_date(INT32 args)
{
  int year, month, day;
  GET_PIKE_SEARCH();
  if (args)
    Pike_error("Too many arguments to Search->get_date()\n");

  THREADS_ALLOW();
  avs_search_getdate(search->handle, &year, &month, &day);
  THREADS_DISALLOW();

  push_int(year);
  push_int(month);
  push_int(day);

  f_aggregate(3);
}
コード例 #11
0
ファイル: nb_send.c プロジェクト: Letractively/caudium
static INLINE int do_write(char *buf, int buf_len) {
  int fd, written = 0;
  fd = THIS->outp->fd;
 write_retry:
  if(fd != -1) {
    DERR(fprintf(stderr, "do_write() to real fd\n"));
    THREADS_ALLOW();
    written = fd_write(fd, buf, buf_len);
    THREADS_DISALLOW();  
  } else {
    DERR(fprintf(stderr, "do_write() to fake fd\n"));
    push_string(make_shared_binary_string(buf, buf_len));
    apply_low(THIS->outp->file, THIS->outp->write_off, 1);
    if(Pike_sp[-1].type != T_INT) {
      written = -1;
    } else {
      written = Pike_sp[-1].u.integer;
    }
    pop_stack();
  }

  if(written < 0)
  { 
    DERR(fprintf(stderr, "write returned -1...\n"));
    switch(errno)
    {      
    default:
      DERR(perror("Error while writing"));
      finished();
      return -1; /* -1 == write failed and that's it */
    case EINTR: /* interrupted by signal - try again */
      DERR(fprintf(stderr, "write -> EINTR = retry.\n"));
      goto write_retry;
    case EWOULDBLOCK:
      DERR(fprintf(stderr, "would block.\n"));
      return 0; /* Treat this as if we wrote no data */      
    }
  } else {
    DERR(fprintf(stderr, "Wrote %d bytes of %d\n", written, buf_len));
    THIS->written += written;
  }
  return written;
}
コード例 #12
0
ファイル: search.c プロジェクト: hww3/pexts
/* array get_term(int term_num) */
static void f_get_term(INT32 args)
{
  int n, term_num;
  long count;
  char *term;
  GET_PIKE_SEARCH();
  get_all_args("Search->get_term()", args, "%i", &term_num);

  THREADS_ALLOW();
  n = avs_getsearchterms(search->handle, term_num, &term, &count);
  THREADS_DISALLOW();
  if (n != AVS_OK)
    Pike_error("Search->get_term(): %s\n", avs_errmsg(n));

  pop_n_elems(args);
  push_text(term);
  push_int(count);

  f_aggregate(2);
}
コード例 #13
0
ファイル: pipe.c プロジェクト: ajinkya007/pike-1
/* This function reads some data from the file cache..
 * Called when we want some data to send.
 */
static INLINE struct pike_string* gimme_some_data(size_t pos)
{
   struct buffer *b;
   ptrdiff_t len;
   struct pipe *this = THIS;

   /* We have a file cache, read from it */
   if (this->fd!=-1)
   {
     char buffer[READ_BUFFER_SIZE];

      if (this->pos<=pos) return NULL; /* no data */
      len=this->pos-pos;
      if (len>READ_BUFFER_SIZE) len=READ_BUFFER_SIZE;
      THREADS_ALLOW();
      fd_lseek(this->fd, pos, SEEK_SET);
      THREADS_DISALLOW();
      do {
	THREADS_ALLOW();
	len = fd_read(this->fd, buffer, len);
	THREADS_DISALLOW();
	if (len < 0) {
	  if (errno != EINTR) {
	    return(NULL);
	  }
	  check_threads_etc();
	}
      } while(len < 0);
      /*
       * FIXME: What if len is 0?
       */
      return make_shared_binary_string(buffer,len);
   }

   if (pos<this->pos)
     return make_shared_string("buffer underflow"); /* shit */

   /* We want something in the next buffer */
   while (this->firstbuffer && pos>=this->pos+this->firstbuffer->s->len) 
   {
     /* Free the first buffer, and update THIS->pos */
      b=this->firstbuffer;
      this->pos+=b->s->len;
      this->bytes_in_buffer-=b->s->len;
      this->firstbuffer=b->next;
      if (!b->next)
	this->lastbuffer=NULL;
      sbuffers-=b->s->len;
      nbuffers--;
      free_string(b->s);
      free((char *)b);

      /* Wake up first input if it was sleeping and we
       * have room for more in the buffer.
       */
      if (this->sleeping &&
	  this->firstinput &&
	  this->bytes_in_buffer<MAX_BYTES_IN_BUFFER)
      {
	if (this->firstinput->type == I_BLOCKING_OBJ) {
	  if (!read_some_data()) {
	    this->sleeping = 0;
	    input_finish();
	  }
	} else {
	  this->sleeping=0;
	  push_callback(offset_input_read_callback);
	  push_int(0);
	  push_callback(offset_input_close_callback);
	  apply(this->firstinput->u.obj, "set_nonblocking", 3);
	  pop_stack();
	}
      }
   }

   while (!this->firstbuffer)
   {
     if (this->firstinput)
     {
#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP)
       if (this->firstinput->type==I_MMAP)
       {
	 char *src;
	 struct pike_string *tmp;

	 if (pos >= this->firstinput->len + this->pos) /* end of mmap */
	 {
	   this->pos += this->firstinput->len;
	   input_finish();
	   continue;
	 }
	 len = this->firstinput->len + this->pos - pos;
	 if (len > READ_BUFFER_SIZE) len=READ_BUFFER_SIZE;
	 tmp = begin_shared_string( len );
	 src = this->firstinput->u.mmap + pos - this->pos;
/* This thread_allow/deny is at the cost of one extra memory copy */
	 THREADS_ALLOW();
	 MEMCPY(tmp->str, src, len);
	 THREADS_DISALLOW();
	 return end_shared_string(tmp);
       }
       else
#endif
       if (this->firstinput->type!=I_OBJ)
       {
	 /* FIXME: What about I_BLOCKING_OBJ? */
	 input_finish();       /* shouldn't be anything else ... maybe a finished object */
       }
     }
     return NULL;		/* no data */
   } 

   if (pos==this->pos)
   {
      add_ref(this->firstbuffer->s);
      return this->firstbuffer->s;
   }
   return make_shared_binary_string(this->firstbuffer->s->str+
				    pos-this->pos,
				    this->firstbuffer->s->len-
				    pos+this->pos);
}
コード例 #14
0
ファイル: orient.c プロジェクト: pikelang/Pike
void image_orient(INT32 args)
{
  struct object *o[5];
  struct image *img[5],*this,*img1;
  int n;
  rgb_group *d,*s1,*s2,*s3,*s0;
  double mag;
  int i, w, h;

  CHECK_INIT();

  this=THIS;

  if (args)
  {
    if (TYPEOF(sp[-args]) == T_INT)
      mag=sp[-args].u.integer;
    else if (TYPEOF(sp[-args]) == T_FLOAT)
      mag=sp[-args].u.float_number;
    else {
      SIMPLE_ARG_TYPE_ERROR("orient",1,"int|float");
      UNREACHABLE(mag=0.0);
    }
  }
  else mag=1.0;

  if (args==1)
    pop_n_elems(args);

  if (args>1)
  {
    if (TYPEOF(sp[1-args]) != T_ARRAY)
      SIMPLE_ARG_TYPE_ERROR("orient",2,"array");
    if (sp[1-args].u.array->size!=4)
      Pike_error("The array given as argument 2 to orient do not have size 4\n");
    for(i=0; i<4; i++)
      if ((TYPEOF(sp[1-args].u.array->item[i]) != T_OBJECT) ||
	  (!(sp[1-args].u.array->item[i].u.object)) ||
	  (sp[1-args].u.array->item[i].u.object->prog!=image_program))
	Pike_error("The array given as argument 2 to orient do not contain images\n");
    img1=(struct image*)sp[1-args].u.array->item[0].u.object->storage;

    w=this->xsize;
    h=this->ysize;

    for(i=0; i<4; i++)
    {
      img1=(struct image*)sp[1-args].u.array->item[i].u.object->storage;
      if ((img1->xsize!=w)||
	  (img1->ysize!=h))
	Pike_error("The images in the array given as argument 2 to orient have different sizes\n");
    }
    for(i=0; i<4; i++)
        img[i]=get_storage(sp[1-args].u.array->item[i].u.object,image_program);
    pop_n_elems(args);
    push_int(this->xsize);
    push_int(this->ysize);
    o[4]=clone_object(image_program,2);
    img[4]=get_storage(o[4],image_program);
    push_object(o[4]);
    w=1;
  }
  else
  {
    _image_orient(this,o,img);
    w=0;
  }
  s0=img[0]->img;
  s1=img[1]->img;
  s2=img[2]->img;
  s3=img[3]->img;
  d=img[4]->img;

THREADS_ALLOW();
CHRONO("begin hsv...");
  n=this->xsize*this->ysize;
  while (n--)
  {
     /* Första färg, sista mörkhet */
     double j=(s0->r+s0->g+s0->b-s2->r-s2->g-s2->b)/3.0;
                /* riktning - - riktning | */

     double h=(s1->r+s1->g+s1->b-s3->r-s3->g-s3->b)/3.0;
                /* riktning \ - riktning / */

     int z,w;

     if (my_abs((int)h) > my_abs((int)j))
	if (h) {
          z = -(int)(32*(j/h)+(h>0)*128+64);
          w = my_abs((int)h);
	}
	else z=0,w=0;
     else {
	if (j) {
          z = -(int)(-32*(h/j)+(j>0)*128+128);
          w = my_abs((int)j);
	}
	else z=0,w=0;
     }

     d->r=(COLORTYPE)z;
     d->g=255;
     d->b = MINIMUM((COLORTYPE)(w*mag), 255);

     d++;
     s0++;
     s1++;
     s2++;
     s3++;
  }
CHRONO("end hsv...");
THREADS_DISALLOW();

  if (!w)
  {
    add_ref(o[4]);
    pop_n_elems(5);
    push_object(o[4]);
  }
}
コード例 #15
0
ファイル: nb_send.c プロジェクト: Letractively/caudium
/* This function reads some data from the current input (file object)
 */
static INLINE int read_data(void)
{
  int buf_size = READ_BUFFER_SIZE;
  NBIO_INT_T to_read  = 0;
  char *rd;
  input *inp;
 redo:
  DERR(fprintf(stderr, "Reading from blocking input.\n"));
  THIS->buf_pos = 0;
  inp = THIS->inputs;
  if(inp == NULL)
    return -1; /* No more inputs */
  if(inp->type != NBIO_BLOCK_OBJ)
    return -2; /* invalid input for read_data */
  if(inp->fd != -1) {
    char * ptr;
    DERR(fprintf(stderr, "Reading from real fd.\n"));
	
    if(inp->len != -1) 
      to_read = MIN(buf_size, inp->len - inp->pos);
    else
      to_read = buf_size;
    if(THIS->buf == NULL || THIS->buf_size < to_read) {
      alloc_data_buf(to_read);
    }
	
    ptr = THIS->buf;
    THREADS_ALLOW();
    to_read = fd_read(inp->fd, ptr, to_read);
    THREADS_DISALLOW();
    DERR(fprintf(stderr, "read %ld from file\n", (long)to_read));
  } else {
    DERR(fprintf(stderr, "Reading from fake fd.\n"));
    if(inp->len != -1 && inp->pos >= inp->len) {
      /* We are done reading from this one */
      DERR(fprintf(stderr, "Data done from fake fd.\n"));
      free_input(inp);
      goto redo; /* goto == ugly, but we want to read the next input
		  * if any
		  */
    }	

    to_read = READ_BUFFER_SIZE;
    push_int(to_read);
    push_int(1);
    apply_low(inp->u.file, inp->read_off, 2);
    if(Pike_sp[-1].type == T_STRING) {
      if(Pike_sp[-1].u.string->len == 0) {
	DERR(fprintf(stderr, "Read zero bytes from fake fd (EOF).\n"));
	to_read = 0;
      } else {
	new_input(Pike_sp[-1], 0, 1);
	to_read = THIS->inputs->len;
	inp->pos += to_read;
 	DERR(fprintf(stderr, "read %ld bytes from fake file\n",
		     (long)to_read));
	pop_stack();
	return -3; /* Got a string buffer appended to the input list */
      }
    } else if(Pike_sp[-1].type == T_INT && Pike_sp[-1].u.integer == 0) {
      to_read = 0;
    } else {
      Pike_error("Incorrect result from read, expected string.\n");
    }
    pop_stack();
  }
  switch(to_read) {
  case 0: /* EOF */
    DERR(fprintf(stderr, "read zero blocking bytes == EOF\n"));
    free_input(inp);
    break;

  case -1:
    if(errno != EAGAIN) {
      /* Got an error. Free input and continue */
      DERR(perror("Error while reading:"));
      free_input(inp); 
    }
    goto redo;

  default:
    inp->pos += to_read;
    if(inp->pos == inp->len) {
      DERR(fprintf(stderr, "Done reading (position == length).\n"));
      free_input(inp);
    }
    THIS->buf_len = to_read;
    break;
  }
  return to_read;
}
コード例 #16
0
ファイル: ilbm.c プロジェクト: pikelang/Pike
static void parse_body(struct BMHD *bmhd, unsigned char *body, ptrdiff_t blen,
		       struct image *img, struct image *alpha,
		       struct neo_colortable *ctable, int ham)
{
  unsigned int x, y;
  int rbyt = ((bmhd->w+15)&~15)>>3;
  int eplanes = (bmhd->masking == mskHasMask? bmhd->nPlanes+1:bmhd->nPlanes);
  unsigned char *line=0;
  unsigned INT32 *cptr, *cline = alloca((rbyt<<3)*sizeof(unsigned INT32));
  ptrdiff_t suse=0;
  rgb_group *dest = img->img;
  rgb_group *adest = (alpha==NULL? NULL : alpha->img);

  if(ctable != NULL && ctable->type != NCT_FLAT)
    ctable = NULL;

  switch(bmhd->compression) {
  case cmpNone:
    break;
  case cmpByteRun1:
    line = alloca(rbyt*eplanes);
    break;
  default:
    Pike_error("Unsupported ILBM compression %d\n", bmhd->compression);
  }

  switch(bmhd->masking) {
  case mskNone:
  case mskHasMask:
  case mskHasTransparentColor:
    break;
  case mskLasso:
    Pike_error("Lasso masking not supported\n");
  default:
    Pike_error("Unsupported ILBM masking %d\n", bmhd->masking);
  }

  THREADS_ALLOW();

  for(y=0; y<bmhd->h; y++) {
    switch(bmhd->compression) {
    case cmpNone:
      line = body;
      suse = rbyt*eplanes;
      break;
    case cmpByteRun1:
      suse = unpackByteRun1(body, blen, line, rbyt, eplanes);
      break;
    }
    body += suse;
    if((blen -= suse)<0)
      break;
    planar2chunky(line, rbyt, bmhd->nPlanes, bmhd->w, (INT32 *)(cptr=cline));
    if(alpha != NULL)
      switch(bmhd->masking) {
      case mskNone:
	memset(adest, ~0, bmhd->w*sizeof(*adest));
	adest += bmhd->w;
	break;
      case mskHasMask:
	{
	  int bit=0x80;
	  unsigned char *src = line+bmhd->nPlanes*rbyt;
	  unsigned char ss = *src++;
	  for(x=0; x<bmhd->w; x++) {
	    if(ss&bit) {
	      adest->r = adest->g = adest->b = 0xff;
	    } else {
	      adest->r = adest->g = adest->b = 0;
	    }
	    if(!(bit>>=1)) {
	      bit = 0x80;
	      ss = *src++;
	    }
	  }
	}
	break;
      case mskHasTransparentColor:
	for(x=0; x<bmhd->w; x++) {
	  if(cline[x] == bmhd->transparentColor)
	    adest->r = adest->g = adest->b = 0;
	  else
	    adest->r = adest->g = adest->b = 0xff;
	  adest++;
	}
	break;
      }
    if(ctable != NULL)
      if(ham)
	if(bmhd->nPlanes>6) {
	  /* HAM7/HAM8 */
	  rgb_group hold;
	  int clr;
	  size_t numcolors = ctable->u.flat.numentries;
	  struct nct_flat_entry *entries = ctable->u.flat.entries;
	  hold.r = hold.g = hold.b = 0;
	  for(x=0; x<bmhd->w; x++)
	    switch((*cptr)&0xc0) {
	    case 0x00:
	      if(*cptr<numcolors)
		*dest++ = hold = entries[*cptr++].color;
	      else {
		*dest++ = hold;
		cptr++;
	      }
	      break;
	    case 0x80:
	      clr = (*cptr++)&0x3f;
	      hold.r = (clr<<2)|(clr>>4);
	      *dest++ = hold;
	      break;
	    case 0xc0:
	      clr = (*cptr++)&0x3f;
	      hold.g = (clr<<2)|(clr>>4);
	      *dest++ = hold;
	      break;
	    case 0x40:
	      clr = (*cptr++)&0x3f;
	      hold.b = (clr<<2)|(clr>>4);
	      *dest++ = hold;
	      break;
	    }
	} else {
コード例 #17
0
ファイル: clf.c プロジェクト: ajinkya007/pike-1
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;
      }
    }
  }
コード例 #18
0
ファイル: log.c プロジェクト: ajinkya007/pike-1
void f_aap_log_as_commonlog_to_file(INT32 args)
{
  struct log_entry *le;
  struct log *l = LTHIS->log;
  int n = 0;
  int mfd, ot=0;
  struct object *f;
  struct tm tm;
  FILE *foo;
  static const char *month[] = {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Oct", "Sep", "Nov", "Dec",
  };

  get_all_args("log_as_commonlog_to_file", args, "%o", &f);
  f->refs++;

  pop_n_elems(args);
  apply(f, "query_fd", 0);
  mfd = fd_dup(sp[-1].u.integer);
  if(mfd < 1)Pike_error("Bad fileobject to ->log_as_commonlog_to_file\n");
  pop_stack();

  foo = fdopen( mfd, "w" );
  if(!foo)
    Pike_error("Bad fileobject to ->log_as_commonlog_to_file\n");

  THREADS_ALLOW();

  mt_lock( &l->log_lock );
  le = l->log_head; 
  l->log_head = l->log_tail = 0;
  mt_unlock( &l->log_lock );

  while(le)
  {
    int i;
    struct tm *tm_p;
    struct log_entry *l = le->next;
    /* remotehost rfc931 authuser [date] "request" status bytes */
    if(le->t != ot)
    {
      time_t t = (time_t)le->t;
#ifdef HAVE_GMTIME_R
      gmtime_r( &t, &tm );
#else
#ifdef HAVE_GMTIME
      tm_p = gmtime( &t ); /* This will break if two threads run
			    gmtime() at once. */

#else
#ifdef HAVE_LOCALTIME
      tm_p = localtime( &t ); /* This will break if two threads run
			       localtime() at once. */
#endif
#endif
      if (tm_p) tm = *tm_p;
#endif
      ot = le->t;
    }

    /* date format:  [03/Feb/1998:23:08:20 +0000]  */

    /* GET [URL] HTTP/1.0 */
    for(i=13; i<le->raw.len; i++)
      if(le->raw.str[i] == '\r')
      {
	le->raw.str[i] = 0;
	break;
      }

#ifdef HAVE_INET_NTOP
    if(SOCKADDR_FAMILY(le->from) != AF_INET) {
      char buffer[64];
      fprintf(foo,
      "%s - %s [%02d/%s/%d:%02d:%02d:%02d +0000] \"%s\" %d %ld\n",
	      inet_ntop(SOCKADDR_FAMILY(le->from), SOCKADDR_IN_ADDR(le->from),
			buffer, sizeof(buffer)), /* hostname */
	      "-",                          /* remote-user */
	      tm.tm_mday, month[tm.tm_mon], tm.tm_year+1900,
	      tm.tm_hour, tm.tm_min, tm.tm_sec, /* date */
	      le->raw.str, /* request line */
	      le->reply, /* reply code */
	      DO_NOT_WARN((long)le->sent_bytes)); /* bytes transfered */
    } else
#endif /* HAVE_INET_NTOP */
    fprintf(foo,
    "%d.%d.%d.%d - %s [%02d/%s/%d:%02d:%02d:%02d +0000] \"%s\" %d %ld\n",
	    ((unsigned char *)&le->from.ipv4.sin_addr)[ 0 ],
	    ((unsigned char *)&le->from.ipv4.sin_addr)[ 1 ],
	    ((unsigned char *)&le->from.ipv4.sin_addr)[ 2 ],
	    ((unsigned char *)&le->from.ipv4.sin_addr)[ 3 ], /* hostname */
	    "-",                          /* remote-user */
	    tm.tm_mday, month[tm.tm_mon], tm.tm_year+1900,
	    tm.tm_hour, tm.tm_min, tm.tm_sec, /* date */
	    le->raw.str, /* request line */
	    le->reply, /* reply code */
	    DO_NOT_WARN((long)le->sent_bytes)); /* bytes transfered */
    free_log_entry( le );
    n++;
    le = l;
  }
  fclose(foo);
  fd_close(mfd);
  THREADS_DISALLOW();
  push_int(n);
}