/* 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); }
/* 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); }
/* 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); }
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); }
/* 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)); }
/* 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); }
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(); }
/* 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); }
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(); }
/* 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); }
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; }
/* 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); }
/* 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); }
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]); } }
/* 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; }
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 {
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; } } }
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); }