Пример #1
0
/* {{{ expand_filepath_use_realpath
 */
PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int realpath_mode)
{
	cwd_state new_state;
	char cwd[MAXPATHLEN];
	int copy_len;
	int path_len;

	if (!filepath[0]) {
		return NULL;
	}

	path_len = (int)strlen(filepath);

	if (IS_ABSOLUTE_PATH(filepath, path_len)) {
		cwd[0] = '\0';
	} else {
		const char *iam = SG(request_info).path_translated;
		const char *result;
		if (relative_to) {
			if (relative_to_len > MAXPATHLEN-1U) {
				return NULL;
			}
			result = relative_to;
			memcpy(cwd, relative_to, relative_to_len+1U);
		} else {
			result = VCWD_GETCWD(cwd, MAXPATHLEN);
		}

		if (!result && (iam != filepath)) {
			int fdtest = -1;

			fdtest = VCWD_OPEN(filepath, O_RDONLY);
			if (fdtest != -1) {
				/* return a relative file path if for any reason
				 * we cannot cannot getcwd() and the requested,
				 * relatively referenced file is accessible */
				copy_len = path_len > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : path_len;
				if (real_path) {
					memcpy(real_path, filepath, copy_len);
					real_path[copy_len] = '\0';
				} else {
					real_path = estrndup(filepath, copy_len);
				}
				close(fdtest);
				return real_path;
			} else {
				cwd[0] = '\0';
			}
		} else if (!result) {
			cwd[0] = '\0';
		}
	}

	new_state.cwd = estrdup(cwd);
	new_state.cwd_length = (int)strlen(cwd);

	if (virtual_file_ex(&new_state, filepath, NULL, realpath_mode)) {
		efree(new_state.cwd);
		return NULL;
	}

	if (real_path) {
		copy_len = new_state.cwd_length > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : new_state.cwd_length;
		memcpy(real_path, new_state.cwd, copy_len);
		real_path[copy_len] = '\0';
	} else {
		real_path = estrndup(new_state.cwd, new_state.cwd_length);
	}
	efree(new_state.cwd);

	return real_path;
}
Пример #2
0
void
ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
{
	int32 ipc;
	Prog *p;
	Sym *h[NSYM], *s;
	int v, o, r, skip;
	uint32 sig;
	char *name;
	int ntext;
	int32 eof;
	char src[1024], *x;
	Prog *lastp;

	lastp = nil;
	ntext = 0;
	eof = Boffset(f) + len;
	src[0] = 0;
	pn = estrdup(pn); // we keep it in Sym* references

newloop:
	memset(h, 0, sizeof(h));
	version++;
	histfrogp = 0;
	ipc = pc;
	skip = 0;

loop:
	if(f->state == Bracteof || Boffset(f) >= eof)
		goto eof;
	o = BGETC(f);
	if(o == Beof)
		goto eof;

	if(o <= AXXX || o >= ALAST) {
		diag("%s:#%lld: opcode out of range: %#ux", pn, Boffset(f), o);
		print("	probably not a .5 file\n");
		errorexit();
	}
	if(o == ANAME || o == ASIGNAME) {
		sig = 0;
		if(o == ASIGNAME)
			sig = Bget4(f);
		v = BGETC(f); /* type */
		o = BGETC(f); /* sym */
		r = 0;
		if(v == D_STATIC)
			r = version;
		name = Brdline(f, '\0');
		if(name == nil) {
			if(Blinelen(f) > 0) {
				fprint(2, "%s: name too long\n", pn);
				errorexit();
			}
			goto eof;
		}
		x = expandpkg(name, pkg);
		s = lookup(x, r);
		if(x != name)
			free(x);

		if(sig != 0){
			if(s->sig != 0 && s->sig != sig)
				diag("incompatible type signatures %ux(%s) and %ux(%s) for %s", s->sig, s->file, sig, pn, s->name);
			s->sig = sig;
			s->file = pn;
		}

		if(debug['W'])
			print("	ANAME	%s\n", s->name);
		if(o < 0 || o >= nelem(h)) {
			fprint(2, "%s: mangled input file\n", pn);
			errorexit();
		}
		h[o] = s;
		if((v == D_EXTERN || v == D_STATIC) && s->type == 0)
			s->type = SXREF;
		if(v == D_FILE) {
			if(s->type != SFILE) {
				histgen++;
				s->type = SFILE;
				s->value = histgen;
			}
			if(histfrogp < MAXHIST) {
				histfrog[histfrogp] = s;
				histfrogp++;
			} else
				collapsefrog(s);
			dwarfaddfrag(s->value, s->name);
		}
		goto loop;
	}

	p = mal(sizeof(Prog));
	p->as = o;
	p->scond = BGETC(f);
	p->reg = BGETC(f);
	p->line = Bget4(f);

	zaddr(pn, f, &p->from, h);
	fromgotype = adrgotype;
	zaddr(pn, f, &p->to, h);

	if(p->as != ATEXT && p->as != AGLOBL && p->reg > NREG)
		diag("register out of range %A %d", p->as, p->reg);

	p->link = P;
	p->cond = P;

	if(debug['W'])
		print("%P\n", p);

	switch(o) {
	case AHISTORY:
		if(p->to.offset == -1) {
			addlib(src, pn);
			histfrogp = 0;
			goto loop;
		}
		if(src[0] == '\0')
			copyhistfrog(src, sizeof src);
		addhist(p->line, D_FILE);		/* 'z' */
		if(p->to.offset)
			addhist(p->to.offset, D_FILE1);	/* 'Z' */
		histfrogp = 0;
		goto loop;

	case AEND:
		histtoauto();
		if(cursym != nil && cursym->text)
			cursym->autom = curauto;
		curauto = 0;
		cursym = nil;
		if(Boffset(f) == eof)
			return;
		goto newloop;

	case AGLOBL:
		s = p->from.sym;
		if(s == S) {
			diag("GLOBL must have a name\n%P", p);
			errorexit();
		}
		if(s->type == 0 || s->type == SXREF) {
			s->type = SBSS;
			s->value = 0;
		}
		if(s->type != SBSS && s->type != SNOPTRBSS && !s->dupok) {
			diag("redefinition: %s\n%P", s->name, p);
			s->type = SBSS;
			s->value = 0;
		}
		if(p->to.offset > s->size)
			s->size = p->to.offset;
		if(p->reg & DUPOK)
			s->dupok = 1;
		if(p->reg & RODATA)
			s->type = SRODATA;
		else if(p->reg & NOPTR)
			s->type = SNOPTRBSS;
		break;

	case ADATA:
		// Assume that AGLOBL comes after ADATA.
		// If we've seen an AGLOBL that said this sym was DUPOK,
		// ignore any more ADATA we see, which must be
		// redefinitions.
		s = p->from.sym;
		if(s->dupok) {
//			if(debug['v'])
//				Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn);
			goto loop;
		}
		if(s->file == nil)
			s->file = pn;
		else if(s->file != pn) {
			diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
			errorexit();
		}
		savedata(s, p, pn);
		unmal(p, sizeof *p);
		break;

	case AGOK:
		diag("unknown opcode\n%P", p);
		p->pc = pc;
		pc++;
		break;

	case ALOCALS:
		if(skip)
			goto casedef;
		cursym->locals = p->to.offset;
		pc++;
		break;

	case ATYPE:
		if(skip)
			goto casedef;
		pc++;
		goto loop;

	case ANPTRS:
		if(skip)
			goto casedef;
		if(cursym->nptrs != -1) {
			diag("ldobj1: multiple pointer maps defined for %s", cursym->name);
			errorexit();
		}
		if(p->to.offset > cursym->args/PtrSize) {
			diag("ldobj1: pointer map definition for %s exceeds its argument size", cursym->name);
			errorexit();
		}
		cursym->nptrs = p->to.offset;
		if(cursym->nptrs != 0)
			cursym->ptrs = mal((rnd(cursym->nptrs, 32) / 32) * sizeof(*cursym->ptrs));
		pc++;
		goto loop;

	case APTRS:
		if(skip)
			goto casedef;
		if(cursym->nptrs == -1 || cursym->ptrs == nil) {
			diag("ldobj1: pointer map data provided for %s without a definition", cursym->name);
			errorexit();
		}
		if(p->from.offset*32 >= rnd(cursym->nptrs, 32)) {
			diag("ldobj1: excessive pointer map data provided for %s", cursym->name);
			errorexit();
		}
		cursym->ptrs[p->from.offset] = p->to.offset;
		pc++;
		goto loop;

	case ATEXT:
		if(cursym != nil && cursym->text) {
			histtoauto();
			cursym->autom = curauto;
			curauto = 0;
		}
		s = p->from.sym;
		if(s == S) {
			diag("TEXT must have a name\n%P", p);
			errorexit();
		}
		cursym = s;
		if(s->type != 0 && s->type != SXREF && (p->reg & DUPOK)) {
			skip = 1;
			goto casedef;
		}
		if(ntext++ == 0 && s->type != 0 && s->type != SXREF) {
			/* redefinition, so file has probably been seen before */
			if(debug['v'])
				Bprint(&bso, "skipping: %s: redefinition: %s", pn, s->name);
			return;
		}
		skip = 0;
		if(s->type != 0 && s->type != SXREF)
			diag("redefinition: %s\n%P", s->name, p);
		if(etextp)
			etextp->next = s;
		else
			textp = s;
		if(fromgotype) {
			if(s->gotype && s->gotype != fromgotype)
				diag("%s: type mismatch for %s", pn, s->name);
			s->gotype = fromgotype;
		}
		etextp = s;
		p->align = 4;
		autosize = (p->to.offset+3L) & ~3L;
		p->to.offset = autosize;
		autosize += 4;
		s->type = STEXT;
		s->text = p;
		s->value = pc;
		s->args = p->to.offset2;
		s->nptrs = -1;
		lastp = p;
		p->pc = pc;
		pc++;
		break;

	case ASUB:
		if(p->from.type == D_CONST)
		if(p->from.name == D_NONE)
		if(p->from.offset < 0) {
			p->from.offset = -p->from.offset;
			p->as = AADD;
		}
		goto casedef;

	case AADD:
		if(p->from.type == D_CONST)
		if(p->from.name == D_NONE)
		if(p->from.offset < 0) {
			p->from.offset = -p->from.offset;
			p->as = ASUB;
		}
		goto casedef;

	case AMOVWD:
	case AMOVWF:
	case AMOVDW:
	case AMOVFW:
	case AMOVFD:
	case AMOVDF:
	// case AMOVF:
	// case AMOVD:
	case ACMPF:
	case ACMPD:
	case AADDF:
	case AADDD:
	case ASUBF:
	case ASUBD:
	case AMULF:
	case AMULD:
	case ADIVF:
	case ADIVD:
		goto casedef;

	case AMOVF:
		if(skip)
			goto casedef;

		if(p->from.type == D_FCONST && chipfloat(&p->from.ieee) < 0 &&
		   (chipzero(&p->from.ieee) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
			/* size sb 9 max */
			sprint(literal, "$%ux", ieeedtof(&p->from.ieee));
			s = lookup(literal, 0);
			if(s->type == 0) {
				s->type = SRODATA;
				adduint32(s, ieeedtof(&p->from.ieee));
				s->reachable = 0;
			}
			p->from.type = D_OREG;
			p->from.sym = s;
			p->from.name = D_EXTERN;
			p->from.offset = 0;
		}
		goto casedef;

	case AMOVD:
		if(skip)
			goto casedef;

		if(p->from.type == D_FCONST && chipfloat(&p->from.ieee) < 0 &&
		   (chipzero(&p->from.ieee) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
			/* size sb 18 max */
			sprint(literal, "$%ux.%ux",
				p->from.ieee.l, p->from.ieee.h);
			s = lookup(literal, 0);
			if(s->type == 0) {
				s->type = SRODATA;
				adduint32(s, p->from.ieee.l);
				adduint32(s, p->from.ieee.h);
				s->reachable = 0;
			}
			p->from.type = D_OREG;
			p->from.sym = s;
			p->from.name = D_EXTERN;
			p->from.offset = 0;
		}
		goto casedef;

	default:
	casedef:
		if(skip)
			nopout(p);
		p->pc = pc;
		pc++;
		if(p->to.type == D_BRANCH)
			p->to.offset += ipc;
		if(lastp == nil) {
			if(p->as != ANOP)
				diag("unexpected instruction: %P", p);
			break;
		}
		lastp->link = p;
		lastp = p;
		break;
	}
	goto loop;

eof:
	diag("truncated object file: %s", pn);
}
Пример #3
0
static int
php_apache_sapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers)
{
	php_struct *ctx;
	char *val, *ptr;

	ctx = SG(server_context);

	switch (op) {
		case SAPI_HEADER_DELETE:
			apr_table_unset(ctx->r->headers_out, sapi_header->header);
			return 0;

		case SAPI_HEADER_DELETE_ALL:
			apr_table_clear(ctx->r->headers_out);
			return 0;

		case SAPI_HEADER_ADD:
		case SAPI_HEADER_REPLACE:
			val = strchr(sapi_header->header, ':');

			if (!val) {
				return 0;
			}
			ptr = val;

			*val = '\0';

			do {
				val++;
			} while (*val == ' ');

			if (!strcasecmp(sapi_header->header, "content-type")) {
				if (ctx->content_type) {
					efree(ctx->content_type);
				}
				ctx->content_type = estrdup(val);
			} else if (!strcasecmp(sapi_header->header, "content-length")) {
#ifdef PHP_WIN32
# ifdef APR_HAS_LARGE_FILES
				ap_set_content_length(ctx->r, (apr_off_t) _strtoui64(val, (char **)NULL, 10));
# else
				ap_set_content_length(ctx->r, (apr_off_t) strtol(val, (char **)NULL, 10));
# endif
#else
				ap_set_content_length(ctx->r, (apr_off_t) strtol(val, (char **)NULL, 10));
#endif
			} else if (op == SAPI_HEADER_REPLACE) {
				apr_table_set(ctx->r->headers_out, sapi_header->header, val);
			} else {
				apr_table_add(ctx->r->headers_out, sapi_header->header, val);
			}

			*ptr = ':';

			return SAPI_HEADER_ADD;

		default:
			return 0;
	}
}
Пример #4
0
/*
    Run the request. This is invoked when all the input data has been received and buffered.
    This routine completely services the request.
 */
static void readyPhp(HttpQueue *q)
{
    HttpConn            *conn;
    HttpRx              *rx;
    HttpTx              *tx;
    MaPhp               *php;
    FILE                *fp;
    cchar               *value;
    char                shebang[MPR_MAX_STRING];
    zend_file_handle    file_handle;

    TSRMLS_FETCH();

    conn = q->conn;
    rx = conn->rx;
    tx = conn->tx;
    if ((php = q->queueData) == 0) {
        return;
    }
    /*
        Set the request context
     */
    zend_first_try {
        php->var_array = 0;
        SG(server_context) = conn;
        if (conn->username) {
            SG(request_info).auth_user = estrdup(conn->username);
        }
        if (conn->password) {
            SG(request_info).auth_password = estrdup(conn->password);
        }
        if ((value = httpGetHeader(conn, "Authorization")) != 0) {
            SG(request_info).auth_digest = estrdup(value);
        }
        SG(request_info).content_type = rx->mimeType;
        SG(request_info).path_translated = tx->filename;
        SG(request_info).content_length = (long) (ssize) rx->length;
        SG(sapi_headers).http_response_code = HTTP_CODE_OK;
        SG(request_info).query_string = rx->parsedUri->query;
        SG(request_info).request_method = rx->method;
        SG(request_info).request_uri = rx->uri;

        /*
            Workaround on MAC OS X where the SIGPROF is given to the wrong thread
         */
        PG(max_input_time) = -1;
        EG(timeout_seconds) = 0;

        /* The readBodyData callback may be invoked during startup */
        php_request_startup(TSRMLS_C);
        CG(zend_lineno) = 0;

    } zend_catch {
        mprError("Cannot start PHP request");
        zend_try {
            php_request_shutdown(0);
        } zend_end_try();
        httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "PHP initialization failed");
        return;
    } zend_end_try();

    /*
        Execute the script file
     */
    file_handle.filename = tx->filename;
    file_handle.free_filename = 0;
    file_handle.opened_path = 0;

#if LOAD_FROM_FILE
    file_handle.type = ZEND_HANDLE_FILENAME;
#else
    file_handle.type = ZEND_HANDLE_FP;
    if ((fp = fopen(tx->filename, "r")) == NULL) {
        if (rx->referrer) {
            httpError(conn, HTTP_CODE_NOT_FOUND, "Cannot open document: %s from %s", tx->filename, rx->referrer);
        } else {
            httpError(conn, HTTP_CODE_NOT_FOUND, "Cannot open document: %s", tx->filename);
        }
        return;
    }
    /*
        Check for shebang and skip
     */
    file_handle.handle.fp = fp;
    shebang[0] = '\0';
    if (fgets(shebang, sizeof(shebang), file_handle.handle.fp)) {}
    if (shebang[0] != '#' || shebang[1] != '!') {
        fseek(fp, 0L, SEEK_SET);
    }
#endif
    zend_try {
        php_execute_script(&file_handle TSRMLS_CC);
        if (!SG(headers_sent)) {
            sapi_send_headers(TSRMLS_C);
        }
    } zend_catch {
        php_request_shutdown(NULL);
        httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR,  "PHP script execution failed");
        return;
    } zend_end_try();

    zend_try {
        php_request_shutdown(NULL);
        SG(server_context) = NULL;
    } zend_catch {
        httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR,  "PHP script shutdown failed");
    } zend_end_try();

    httpFinalize(conn);
}
Пример #5
0
int main(int argc, char *argv[])
{
    int sock;
    struct sockaddr_in fingerServAddr;
    const unsigned short servPort = 79;
    char *servIP;
    char *userName;

    char fingerBuffer[RCVBUFSIZE];
    unsigned int userNameLen;
    int bytesRcvd, totalBytesRcvd;

	int count=0;
	char *SEPARATOR = "@";
	char *param;
	char *word;

	//파라메터 형식을 체크
    if ((argc !=2 )) {
		fprintf(stderr, "Usage: %s username@hostname\n", argv[0]);
		exit(1);
    }

	//userName과 servIP를 분석해서 얻어온다
	param = estrdup(argv[1]);
	for(word = strtok(param, SEPARATOR); word!= NULL; word=strtok(NULL, SEPARATOR) ){
		if( count==0 )
			userName = estrdup(word);
		else if(count==1)
			servIP = estrdup(word);
		else
			DieWithError("Illegal input");
		count++; 
	}

	//소켓 생성
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
		DieWithError("socket() failed");

	//핑거 서버 포트 79로 주소 정보 입력
    memset(&fingerServAddr, 0, sizeof(fingerServAddr));
    fingerServAddr.sin_family = AF_INET;
    fingerServAddr.sin_addr.s_addr = resolveName(servIP);//Internet Address이건 호스트 네임이건 알아서 변환해서 넣음.
    fingerServAddr.sin_port = htons(servPort);

	//핑거 서버에 소켓 연결
    if (connect(sock, (struct sockaddr *) &fingerServAddr, sizeof(fingerServAddr)) < 0)
		DieWithError("connect() failed");

	//핑거 쿼리 - userName과 new line
    userNameLen = strlen(userName);
    if (send(sock, userName, userNameLen, 0) != userNameLen)
		DieWithError("send() sent a different number of bytes than expected");
    if (send(sock, "\n", 1, 0) != 1)
		DieWithError("send() sent a different number of bytes than expected");

	//핑거 결과 받아옴
    memset(fingerBuffer, 0, sizeof(fingerBuffer));
    totalBytesRcvd = 0;
    do {
		if ((bytesRcvd = recv(sock, fingerBuffer, RCVBUFSIZE-1, 0)) < 0)
			DieWithError("recv() failed or connection closed prematurely");
		totalBytesRcvd += bytesRcvd;
		fingerBuffer[bytesRcvd] = '\0';
		printf("%s", fingerBuffer);
    } while (bytesRcvd != 0 );

	//소켓 종료
    close(sock);

    return 0;
}
Пример #6
0
/* {{{ MBSTRING_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data)
 * http input processing */
MBSTRING_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data)
{
	char *res = NULL, *separator=NULL;
	const char *c_var;
	zval *array_ptr;
	int free_buffer=0;
	const mbfl_encoding *detected;
	php_mb_encoding_handler_info_t info;

	if (arg != PARSE_STRING) {
		char *value = MBSTRG(internal_encoding_name);
		_php_mb_ini_mbstring_internal_encoding_set(value, value ? strlen(value): 0 TSRMLS_CC);
	}

	if (!MBSTRG(encoding_translation)) {
		php_default_treat_data(arg, str, destArray TSRMLS_CC);
		return;
	}

	switch (arg) {
		case PARSE_POST:
		case PARSE_GET:
		case PARSE_COOKIE:
			ALLOC_ZVAL(array_ptr);
			array_init(array_ptr);
			INIT_PZVAL(array_ptr);
			switch (arg) {
				case PARSE_POST:
					PG(http_globals)[TRACK_VARS_POST] = array_ptr;
					break;
				case PARSE_GET:
					PG(http_globals)[TRACK_VARS_GET] = array_ptr;
					break;
				case PARSE_COOKIE:
					PG(http_globals)[TRACK_VARS_COOKIE] = array_ptr;
					break;
			}
			break;
		default:
			array_ptr=destArray;
			break;
	}

	if (arg==PARSE_POST) { 
		sapi_handle_post(array_ptr TSRMLS_CC);
		return;
	}

	if (arg == PARSE_GET) {		/* GET data */
		c_var = SG(request_info).query_string;
		if (c_var && *c_var) {
			res = (char *) estrdup(c_var);
			free_buffer = 1;
		} else {
			free_buffer = 0;
		}
	} else if (arg == PARSE_COOKIE) {		/* Cookie data */
		c_var = SG(request_info).cookie_data;
		if (c_var && *c_var) {
			res = (char *) estrdup(c_var);
			free_buffer = 1;
		} else {
			free_buffer = 0;
		}
	} else if (arg == PARSE_STRING) {		/* String data */
		res = str;
		free_buffer = 1;
	}

	if (!res) {
		return;
	}

	switch (arg) {
	case PARSE_POST:
	case PARSE_GET:
	case PARSE_STRING:
		separator = (char *) estrdup(PG(arg_separator).input);
		break;
	case PARSE_COOKIE:
		separator = ";\0";
		break;
	}
	
	switch(arg) {
	case PARSE_POST:
		MBSTRG(http_input_identify_post) = NULL;
		break;
	case PARSE_GET:
		MBSTRG(http_input_identify_get) = NULL;
		break;
	case PARSE_COOKIE:
		MBSTRG(http_input_identify_cookie) = NULL;
		break;
	case PARSE_STRING:
		MBSTRG(http_input_identify_string) = NULL;
		break;
	}

	info.data_type              = arg;
	info.separator              = separator; 
	info.report_errors          = 0;
	info.to_encoding            = MBSTRG(internal_encoding);
	info.to_language            = MBSTRG(language);
	info.from_encodings         = MBSTRG(http_input_list);
	info.num_from_encodings     = MBSTRG(http_input_list_size); 
	info.from_language          = MBSTRG(language);

	MBSTRG(illegalchars) = 0;

	detected = _php_mb_encoding_handler_ex(&info, array_ptr, res TSRMLS_CC);
	MBSTRG(http_input_identify) = detected;

	if (detected) {
		switch(arg){
		case PARSE_POST:
			MBSTRG(http_input_identify_post) = detected;
			break;
		case PARSE_GET:
			MBSTRG(http_input_identify_get) = detected;
			break;
		case PARSE_COOKIE:
			MBSTRG(http_input_identify_cookie) = detected;
			break;
		case PARSE_STRING:
			MBSTRG(http_input_identify_string) = detected;
			break;
		}
	}

	if (arg != PARSE_COOKIE) {
		efree(separator);
	}

	if (free_buffer) {
		efree(res);
	}
}
Пример #7
0
/*********************************************************************
// Name:  SendText
// Input:       1) RPath:   return path of the message
//                                  Is used to fill the "Return-Path" and the
//                                  "X-Sender" fields of the message.
//                  2) Subject: Subject field of the message. If NULL is given
//                                  the subject is set to "No Subject"
//                  3) mailTo:  Destination address
//                  4) data:        Null terminated string containing the data to be send.
//                  5,6) headers of the message. Note that the second
//                  parameter, headers_lc, is actually a lowercased version of
//                  headers. The should match exactly (in terms of length),
//                  only differ in case
// Output:      Error code or SUCCESS
// Description:
// Author/Date:  jcar 20/9/96
// History:
//*******************************************************************/
static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char *mailBcc, char *data, 
			 char *headers, char *headers_lc, char **error_message)
{
	int res;
	char *p;
	char *tempMailTo, *token, *pos1, *pos2;
	char *server_response = NULL;
	char *stripped_header  = NULL;
	zend_string *data_cln;

	/* check for NULL parameters */
	if (data == NULL)
		return (BAD_MSG_CONTENTS);
	if (mailTo == NULL)
		return (BAD_MSG_DESTINATION);
	if (RPath == NULL)
		return (BAD_MSG_RPATH);

	/* simple checks for the mailto address */
	/* have ampersand ? */
	/* mfischer, 20020514: I commented this out because it really
	   seems bogus. Only a username for example may still be a
	   valid address at the destination system.
	if (strchr(mailTo, '@') == NULL)
		return (BAD_MSG_DESTINATION);
	*/

	snprintf(Buffer, sizeof(Buffer), "HELO %s\r\n", LocalHost);

	/* in the beginning of the dialog */
	/* attempt reconnect if the first Post fail */
	if ((res = Post(Buffer)) != SUCCESS) {
		MailConnect();
		if ((res = Post(Buffer)) != SUCCESS) {
			return (res);
		}
	}
	if ((res = Ack(&server_response)) != SUCCESS) {
		SMTP_ERROR_RESPONSE(server_response);
		return (res);
	}

	SMTP_SKIP_SPACE(RPath);
	FormatEmailAddress(Buffer, RPath, "MAIL FROM:<%s>\r\n");
	if ((res = Post(Buffer)) != SUCCESS) {
		return (res);
	}
	if ((res = Ack(&server_response)) != SUCCESS) {
		SMTP_ERROR_RESPONSE(server_response);
		return W32_SM_SENDMAIL_FROM_MALFORMED;
	}

	tempMailTo = estrdup(mailTo);
	/* Send mail to all rcpt's */
	token = strtok(tempMailTo, ",");
	while (token != NULL)
	{
		SMTP_SKIP_SPACE(token);
		FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
		if ((res = Post(Buffer)) != SUCCESS) {
			efree(tempMailTo);
			return (res);
		}
		if ((res = Ack(&server_response)) != SUCCESS) {
			SMTP_ERROR_RESPONSE(server_response);
			efree(tempMailTo);
			return (res);
		}
		token = strtok(NULL, ",");
	}
	efree(tempMailTo);

	if (mailCc && *mailCc) {
		tempMailTo = estrdup(mailCc);
		/* Send mail to all rcpt's */
		token = strtok(tempMailTo, ",");
		while (token != NULL)
		{
			SMTP_SKIP_SPACE(token);
			FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
			if ((res = Post(Buffer)) != SUCCESS) {
				efree(tempMailTo);
				return (res);
			}
			if ((res = Ack(&server_response)) != SUCCESS) {
				SMTP_ERROR_RESPONSE(server_response);
				efree(tempMailTo);
				return (res);
			}
			token = strtok(NULL, ",");
		}
		efree(tempMailTo);
	}
	/* Send mail to all Cc rcpt's */
	else if (headers && (pos1 = strstr(headers_lc, "cc:")) && ((pos1 == headers_lc) || (*(pos1-1) == '\n'))) {
		/* Real offset is memaddress from the original headers + difference of
		 * string found in the lowercase headrs + 3 characters to jump over
		 * the cc: */
		pos1 = headers + (pos1 - headers_lc) + 3;
		if (NULL == (pos2 = strstr(pos1, "\r\n"))) {
			tempMailTo = estrndup(pos1, strlen(pos1));
		} else {
			tempMailTo = estrndup(pos1, pos2 - pos1);
		}

		token = strtok(tempMailTo, ",");
		while (token != NULL)
		{
			SMTP_SKIP_SPACE(token);
			FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
			if ((res = Post(Buffer)) != SUCCESS) {
				efree(tempMailTo);
				return (res);
			}
			if ((res = Ack(&server_response)) != SUCCESS) {
				SMTP_ERROR_RESPONSE(server_response);
				efree(tempMailTo);
				return (res);
			}
			token = strtok(NULL, ",");
		}
		efree(tempMailTo);
	}

	/* Send mail to all Bcc rcpt's
	   This is basically a rip of the Cc code above.
	   Just don't forget to remove the Bcc: from the header afterwards. */
	if (mailBcc && *mailBcc) {
		tempMailTo = estrdup(mailBcc);
		/* Send mail to all rcpt's */
		token = strtok(tempMailTo, ",");
		while (token != NULL)
		{
			SMTP_SKIP_SPACE(token);
			FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
			if ((res = Post(Buffer)) != SUCCESS) {
				efree(tempMailTo);
				return (res);
			}
			if ((res = Ack(&server_response)) != SUCCESS) {
				SMTP_ERROR_RESPONSE(server_response);
				efree(tempMailTo);
				return (res);
			}
			token = strtok(NULL, ",");
		}
		efree(tempMailTo);
	}
	else if (headers) {
		if (pos1 = strstr(headers_lc, "bcc:")) {
			/* Real offset is memaddress from the original headers + difference of
			 * string found in the lowercase headrs + 4 characters to jump over
			 * the bcc: */
			pos1 = headers + (pos1 - headers_lc) + 4;
			if (NULL == (pos2 = strstr(pos1, "\r\n"))) {
				tempMailTo = estrndup(pos1, strlen(pos1));
				/* Later, when we remove the Bcc: out of the
				   header we know it was the last thing. */
				pos2 = pos1;
			} else {
				tempMailTo = estrndup(pos1, pos2 - pos1);
			}

			token = strtok(tempMailTo, ",");
			while (token != NULL)
			{
				SMTP_SKIP_SPACE(token);
				FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n");
				if ((res = Post(Buffer)) != SUCCESS) {
					efree(tempMailTo);
					return (res);
				}
				if ((res = Ack(&server_response)) != SUCCESS) {
					SMTP_ERROR_RESPONSE(server_response);
					efree(tempMailTo);
					return (res);
				}
				token = strtok(NULL, ",");
			}
			efree(tempMailTo);

			/* Now that we've identified that we've a Bcc list,
			   remove it from the current header. */
			if (NULL == (stripped_header = ecalloc(1, strlen(headers)))) {
				return OUT_OF_MEMORY;
			}
			/* headers = point to string start of header
			   pos1    = pointer IN headers where the Bcc starts
			   '4'     = Length of the characters 'bcc:'
			   Because we've added +4 above for parsing the Emails
			   we've to subtract them here. */
			memcpy(stripped_header, headers, pos1 - headers - 4);
			if (pos1 != pos2) {
				/* if pos1 != pos2 , pos2 points to the rest of the headers.
				   Since pos1 != pos2 if "\r\n" was found, we know those characters
				   are there and so we jump over them (else we would generate a new header
				   which would look like "\r\n\r\n". */
				memcpy(stripped_header + (pos1 - headers - 4), pos2 + 2, strlen(pos2) - 2);
			}
		}
	}

	/* Simplify the code that we create a copy of stripped_header no matter if
	   we actually strip something or not. So we've a single efree() later. */
	if (headers && !stripped_header) {
		if (NULL == (stripped_header = estrndup(headers, strlen(headers)))) {
			return OUT_OF_MEMORY;
		}
	}

	if ((res = Post("DATA\r\n")) != SUCCESS) {
		if (stripped_header) {
			efree(stripped_header);
		}
		return (res);
	}
	if ((res = Ack(&server_response)) != SUCCESS) {
		SMTP_ERROR_RESPONSE(server_response);
		if (stripped_header) {
			efree(stripped_header);
		}
		return (res);
	}

	/* send message header */
	if (Subject == NULL) {
		res = PostHeader(RPath, "No Subject", mailTo, stripped_header);
	} else {
		res = PostHeader(RPath, Subject, mailTo, stripped_header);
	}
	if (stripped_header) {
		efree(stripped_header);
	}
	if (res != SUCCESS) {
		return (res);
	}

	/* Escape \n. sequences
	 * We use php_str_to_str() and not php_str_replace_in_subject(), since the latter
	 * uses ZVAL as it's parameters */
	data_cln = php_str_to_str(data, strlen(data), PHP_WIN32_MAIL_DOT_PATTERN, sizeof(PHP_WIN32_MAIL_DOT_PATTERN) - 1,
					PHP_WIN32_MAIL_DOT_REPLACE, sizeof(PHP_WIN32_MAIL_DOT_REPLACE) - 1);
	if (!data_cln) {
		data_cln = STR_EMPTY_ALLOC();
	}

	/* send message contents in 1024 chunks */
	{
		char c, *e2, *e = data_cln->val + data_cln->len;
		p = data_cln->val;

		while (e - p > 1024) {
			e2 = p + 1024;
			c = *e2;
			*e2 = '\0';
			if ((res = Post(p)) != SUCCESS) {
				zend_string_free(data_cln);
				return(res);
			}
			*e2 = c;
			p = e2;
		}
		if ((res = Post(p)) != SUCCESS) {
			zend_string_free(data_cln);
			return(res);
		}
	}

	zend_string_free(data_cln);

	/*send termination dot */
	if ((res = Post("\r\n.\r\n")) != SUCCESS)
		return (res);
	if ((res = Ack(&server_response)) != SUCCESS) {
		SMTP_ERROR_RESPONSE(server_response);
		return (res);
	}

	return (SUCCESS);
}
Пример #8
0
Файл: cs.c Проект: brho/akaros
static char *rwalk(struct job *job, struct mfile *mf)
{
	char *err;
	char **elems;
	int nelems;
	int i;
	struct mfile *nmf;
	struct qid qid;

	err = 0;
	nmf = NULL;
	elems = job->request.wname;
	nelems = job->request.nwname;
	job->reply.nwqid = 0;

	if (job->request.newfid != job->request.fid) {
		/* clone fid */
		nmf = newfid(job->request.newfid);
		if (nmf->busy) {
			nmf = NULL;
			err = "clone to used channel";
			goto send;
		}
		*nmf = *mf;
		nmf->user = estrdup(mf->user);
		nmf->fid = job->request.newfid;
		nmf->qid.vers = vers++;
		mf = nmf;
	}
	/* else nmf will be nil */

	qid = mf->qid;
	if (nelems > 0) {
		/* walk fid */
		for (i = 0; i < nelems && i < MAXWELEM; i++) {
			if ((qid.type & QTDIR) == 0) {
				err = "not a directory";
				break;
			}
			if (strcmp(elems[i], "..") == 0
			    || strcmp(elems[i], ".") == 0) {
				qid.type = QTDIR;
				qid.path = Qdir;
Found:
				job->reply.wqid[i] = qid;
				job->reply.nwqid++;
				continue;
			}
			if (strcmp(elems[i], "cs") == 0) {
				qid.type = QTFILE;
				qid.path = Qcs;
				goto Found;
			}
			err = "file does not exist";
			break;
		}
	}

send:
	if (nmf != NULL && (err != NULL || job->reply.nwqid < nelems)) {
		cleanmf(nmf);
		free(nmf->user);
		nmf->user = 0;
		nmf->busy = 0;
		nmf->fid = 0;
	}
	if (err == NULL)
		mf->qid = qid;
	sendmsg(job, err);
	return err;
}
Пример #9
0
void
xcmd(Biobuf *b)
{
	char *p, *fld[16], buf[1024];

	int i, nfld;

	p = getline(b);
	if(p == nil)
		sysfatal("xcmd error: %r");
	if(debug)
		fprint(2, "x command '%s'\n", p);
	nfld = tokenize(p, fld, nelem(fld));
	if(nfld == 0)
		return;
	switch(fld[0][0]){
	case 'f':
		/* mount font */
		if(nfld != 3)
			break;
		i = atoi(fld[1]);
		if(i<0 || Nfont<=i)
			sysfatal("font %d out of range at %s:#%d", i, filename, cno);
		mountfont(i, fld[2]);
		return;
	case 'i':
		/* init */
		return;
	case 'r':
		if(nfld<2 || atoi(fld[1])!=res)
			sysfatal("typesetter has unexpected resolution %s", fld[1]? fld[1] : "<unspecified>");
		return;
	case 's':
		/* stop */
		return;
	case 't':
		/* trailer */
		return;
	case 'T':
		if(nfld!=2 || strcmp(fld[1], "utf")!=0)
			sysfatal("output for unknown typesetter type %s", fld[1]);
		return;
	case 'X':
		if(nfld<3 || strcmp(fld[1], "html")!=0)
			break;
		/* is it a man reference of the form cp(1)? */
		/* X manref start/end cp (1) */
		if(nfld==6 && strcmp(fld[2], "manref")==0){
			/* was the right macro; is it the right form? */
			if(strlen(fld[5])>=3 &&
			   fld[5][0]=='(' && fld[5][2]==')' &&
			   '0'<=fld[5][1] && fld[5][1]<='9'){
				if(strcmp(fld[3], "start") == 0){
					/* set anchor attribute and remember string */
					attr |= (1<<Anchor);
					snprint(buf, sizeof buf,
						"<a href=\"/magic/man2html/%c/%s\">",
						fld[5][1], fld[4]);
					nanchors++;
					anchors = erealloc(anchors, nanchors*sizeof(char*));
					anchors[nanchors-1] = estrdup(buf);
				}else if(strcmp(fld[3], "end") == 0)
					attr &= ~(1<<Anchor);
			}
		}else if(strcmp(fld[2], "manPP") == 0){
			didP = 1;
			emitchar(Epp);
		}else if(nfld<4 || strcmp(fld[2], "manref")!=0){
			if(nfld>2 && strcmp(fld[2], "<P>")==0){	/* avoid triggering extra <br> */
				didP = 1;
				/* clear all font attributes before paragraph */
				emitchar(' ' | (attr & ~(0xFFFF|((1<<Italic)|(1<<Bold)|(1<<CW)))));
				emitstr("<P>");
				/* next emittec char will turn font attributes back on */
			}else if(nfld>2 && strcmp(fld[2], "<H4>")==0)
				attr |= (1<<Heading);
			else if(nfld>2 && strcmp(fld[2], "</H4>")==0)
				attr &= ~(1<<Heading);
			else if(debug)
				fprint(2, "unknown in-line html %s... at %s:%#d\n",
					fld[2], filename, cno);
		}
		return;
	}
	if(debug)
		fprint(2, "unknown or badly formatted x command %s\n", fld[0]);
}
Пример #10
0
void
look3(Text *t, uint q0, uint q1, int external)
{
	int n, c, f, expanded;
	Text *ct;
	Expand e;
	Rune *r;
	uint p;
	Plumbmsg *m;
	Runestr dir;
	char buf[32];

	ct = seltext;
	if(ct == nil)
		seltext = t;
	expanded = expand(t, q0, q1, &e);
	if(!external && t->w!=nil && t->w->nopen[QWevent]>0){
		/* send alphanumeric expansion to external client */
		if(expanded == FALSE)
			return;
		f = 0;
		if((e.u.at!=nil && t->w!=nil) || (e.nname>0 && lookfile(e.name, e.nname)!=nil))
			f = 1;		/* acme can do it without loading a file */
		if(q0!=e.q0 || q1!=e.q1)
			f |= 2;	/* second (post-expand) message follows */
		if(e.nname)
			f |= 4;	/* it's a file name */
		c = 'l';
		if(t->what == Body)
			c = 'L';
		n = q1-q0;
		if(n <= EVENTSIZE){
			r = runemalloc(n);
			bufread(&t->file->b, q0, r, n);
			winevent(t->w, "%c%d %d %d %d %.*S\n", c, q0, q1, f, n, n, r);
			free(r);
		}else
			winevent(t->w, "%c%d %d %d 0 \n", c, q0, q1, f, n);
		if(q0==e.q0 && q1==e.q1)
			return;
		if(e.nname){
			n = e.nname;
			if(e.a1 > e.a0)
				n += 1+(e.a1-e.a0);
			r = runemalloc(n);
			runemove(r, e.name, e.nname);
			if(e.a1 > e.a0){
				r[e.nname] = ':';
				bufread(&e.u.at->file->b, e.a0, r+e.nname+1, e.a1-e.a0);
			}
		}else{
			n = e.q1 - e.q0;
			r = runemalloc(n);
			bufread(&t->file->b, e.q0, r, n);
		}
		f &= ~2;
		if(n <= EVENTSIZE)
			winevent(t->w, "%c%d %d %d %d %.*S\n", c, e.q0, e.q1, f, n, n, r);
		else
			winevent(t->w, "%c%d %d %d 0 \n", c, e.q0, e.q1, f, n);
		free(r);
		goto Return;
	}
	if(plumbsendfid != nil){
		/* send whitespace-delimited word to plumber */
		m = emalloc(sizeof(Plumbmsg));
		m->src = estrdup("acme");
		m->dst = nil;
		dir = dirname(t, nil, 0);
		if(dir.nr==1 && dir.r[0]=='.'){	/* sigh */
			free(dir.r);
			dir.r = nil;
			dir.nr = 0;
		}
		if(dir.nr == 0)
			m->wdir = estrdup(wdir);
		else
			m->wdir = runetobyte(dir.r, dir.nr);
		free(dir.r);
		m->type = estrdup("text");
		m->attr = nil;
		buf[0] = '\0';
		if(q1 == q0){
			if(t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){
				q0 = t->q0;
				q1 = t->q1;
			}else{
				p = q0;
				while(q0>0 && (c=tgetc(t, q0-1))!=' ' && c!='\t' && c!='\n')
					q0--;
				while(q1<t->file->b.nc && (c=tgetc(t, q1))!=' ' && c!='\t' && c!='\n')
					q1++;
				if(q1 == q0){
					plumbfree(m);
					goto Return;
				}
				sprint(buf, "click=%d", p-q0);
				m->attr = plumbunpackattr(buf);
			}
		}
		r = runemalloc(q1-q0);
		bufread(&t->file->b, q0, r, q1-q0);
		m->data = runetobyte(r, q1-q0);
		m->ndata = strlen(m->data);
		free(r);
		if(m->ndata<messagesize-1024 && plumbsendtofid(plumbsendfid, m) >= 0){
			plumbfree(m);
			goto Return;
		}
		plumbfree(m);
		/* plumber failed to match; fall through */
	}

	/* interpret alphanumeric string ourselves */
	if(expanded == FALSE)
		return;
	if(e.name || e.u.at)
		openfile(t, &e);
	else{
		if(t->w == nil)
			return;
		ct = &t->w->body;
		if(t->w != ct->w)
			winlock(ct->w, 'M');
		if(t == ct)
			textsetselect(ct, e.q1, e.q1);
		n = e.q1 - e.q0;
		r = runemalloc(n);
		bufread(&t->file->b, e.q0, r, n);
		if(search(ct, r, n) && e.jump)
			moveto(mousectl, addpt(frptofchar(&ct->fr, ct->fr.p0), Pt(4, ct->fr.font->height-4)));
		if(t->w != ct->w)
			winunlock(ct->w);
		free(r);
	}

   Return:
	free(e.name);
	free(e.bname);
}
Пример #11
0
int
main(int argc, char **argv)
{
    int ret;
    const char *file;
    const char *name = NULL;
    int optidx = 0;
    char **arg = NULL;
    int len = 0, i;

    setprogname(argv[0]);
    if(getarg(args, num_args, argc, argv, &optidx))
	usage(1);
    if(help_flag)
	usage(0);
    if(version_flag) {
	print_version(NULL);
	exit(0);
    }
    if (argc == optidx) {
	file = "stdin";
	name = "stdin";
	yyin = stdin;
    } else {
	file = argv[optidx];
	yyin = fopen (file, "r");
	if (yyin == NULL)
	    err (1, "open %s", file);
	if (argc == optidx + 1) {
	    char *p;
	    name = estrdup(file);
	    p = strrchr(name, '.');
	    if (p)
		*p = '\0';
	} else
	    name = argv[optidx + 1];
    }

    /*
     * Parse extra options file
     */
    if (option_file) {
	char buf[1024];
	FILE *opt;

	opt = fopen(option_file, "r");
	if (opt == NULL) {
	    perror("open");
	    exit(1);
	}

	arg = calloc(2, sizeof(arg[0]));
	if (arg == NULL) {
	    perror("calloc");
	    exit(1);
	}
	arg[0] = option_file;
	arg[1] = NULL;
	len = 1;

	while (fgets(buf, sizeof(buf), opt) != NULL) {
	    buf[strcspn(buf, "\n\r")] = '\0';

	    arg = realloc(arg, (len + 2) * sizeof(arg[0]));
	    if (arg == NULL) {
		perror("malloc");
		exit(1);
	    }
	    arg[len] = strdup(buf);
	    if (arg[len] == NULL) {
		perror("strdup");
		exit(1);
	    }
	    arg[len + 1] = NULL;
	    len++;
	}
	fclose(opt);

	optidx = 0;
	if(getarg(args, num_args, len, arg, &optidx))
	    usage(1);

	if (len != optidx) {
	    fprintf(stderr, "extra args");
	    exit(1);
	}
    }

    if (fuzzer_flag) {
	if (!template_flag) {
	    printf("can't do fuzzer w/o --template");
	    exit(1);
	}
#ifdef ASN1_FUZZER
	fuzzer_string = "_fuzzer";
#endif
    }


    init_generate (file, name);

    if (one_code_file)
	generate_header_of_codefile(name);

    initsym ();
    ret = yyparse ();
    if(ret != 0 || error_flag != 0)
	exit(1);
    close_generate ();
    if (argc != optidx)
	fclose(yyin);

    if (one_code_file)
	close_codefile();

    if (arg) {
	for (i = 1; i < len; i++)
	    free(arg[i]);
	free(arg);
    }

    return 0;
}
Пример #12
0
//
// INStatsManager::recordStats
//
// Add stats for a particular level.
//
void INStatsManager::recordStats(const wbstartstruct_t *wbstats)
{
   qstring levelkey;
   int   scores[INSTAT_NUMTYPES];
   int   maxscores[INSTAT_NUMTYPES];
   const wbplayerstruct_t *playerData = &wbstats->plyr[wbstats->pnum];

   getLevelKey(levelkey);

   // really shouldn't happen
   if(levelkey == "")
      return;

   // not playing??
   if(!playerData->in)
      return;

   // cheated?
   if(players[wbstats->pnum].cheats & CF_CHEATED)
      return;

   // demo?
   if(demoplayback)
      return;

   // copy data from wbstats/playerData to scores array
   scores[INSTAT_KILLS  ] = playerData->skills;
   scores[INSTAT_ITEMS  ] = playerData->sitems;
   scores[INSTAT_SECRETS] = playerData->ssecret;
   scores[INSTAT_TIME   ] = playerData->stime;
   scores[INSTAT_FRAGS  ] = players[wbstats->pnum].totalfrags;

   // Setup the maxscores array too
   maxscores[INSTAT_KILLS  ] = wbstats->maxkills;
   maxscores[INSTAT_ITEMS  ] = wbstats->maxitems;
   maxscores[INSTAT_SECRETS] = wbstats->maxsecret;
   maxscores[INSTAT_TIME   ] = wbstats->partime;   // Actually a minimum, of sorts.
   maxscores[INSTAT_FRAGS  ] = -1;                 // There's no max for frags.


   for(int i = 0; i < INSTAT_NUMTYPES; i++)
   {
      in_stat_t *instat;

      if((instat = findScore(levelkey, i)))
      {
         // If we're not playing on the same or a better skill level, this
         // score can't replace the old one.
         if(gameskill < instat->skill)
            continue;

         // * For most categories, a higher score wins. Time is an exception.
         // * A tie wins if it is achieved on a higher skill level.
         if((gameskill > instat->skill && scores[i] == instat->value) ||
            (i == INSTAT_TIME ? 
             scores[i] < instat->value : scores[i] > instat->value))
         {
            // This player has the new high score!
            instat->skill    = gameskill;
            instat->value    = scores[i];
            instat->maxValue = maxscores[i];
            E_ReplaceString(instat->playername, 
                            estrdup(players[wbstats->pnum].name));
         }
      }
      else
         addScore(levelkey.constPtr(), scores[i], maxscores[i], i, wbstats->pnum);
   }
}
Пример #13
0
static void symbol2string(Register result, Register symbol)
{
    regMakeString(result, estrdup(regGetSymbol(symbol)));
}
Пример #14
0
struct einit_cron_job *einit_cron_parse_attrs_to_cron_job (char **attributes) {
 if (!attributes) return NULL;

 struct einit_cron_job *cj = emalloc (sizeof (struct einit_cron_job));
 uint32_t i = 0;
 memset (cj, 0, sizeof (struct einit_cron_job));

 for (; attributes[i]; i+=2) {
  if (strmatch (attributes[i], "command")) {
   cj->command = estrdup(attributes[i+1]);
  } else if (strmatch (attributes[i], "id")) {
   cj->id = estrdup(attributes[i+1]);
  } else if (strmatch (attributes[i], "years") || strmatch (attributes[i], "year")) {
   char **x = str2set (':', attributes[i+1]);
   uint32_t j = 0;

   for (; x[j]; j++) {
    uintptr_t num = parse_integer (x[j]);

    if (num) {
     cj->years = (uintptr_t *)setadd ((void **)cj->years, (void *)num, SET_NOALLOC);
	}
   }

   free (x);
  } else if (strmatch (attributes[i], "months") || strmatch (attributes[i], "month")) {
   char **x = str2set (':', attributes[i+1]);
   uint32_t j = 0;

   for (; x[j]; j++) {
    uintptr_t num = parse_integer (x[j]);

    if (num) {
     cj->months = (uintptr_t *)setadd ((void **)cj->months, (void *)num, SET_NOALLOC);
	}
   }

   free (x);
  } else if (strmatch (attributes[i], "days") || strmatch (attributes[i], "day")) {
   char **x = str2set (':', attributes[i+1]);
   uint32_t j = 0;

   for (; x[j]; j++) {
    uintptr_t num = parse_integer (x[j]);

    if (num) {
     cj->days = (uintptr_t *)setadd ((void **)cj->days, (void *)num, SET_NOALLOC);
	}
   }

   free (x);
  } else if (strmatch (attributes[i], "hours") || strmatch (attributes[i], "hour")) {
   char **x = str2set (':', attributes[i+1]);
   uint32_t j = 0;

   for (; x[j]; j++) {
    uintptr_t num = parse_integer (x[j]);

    if (num) {
     cj->hours = (uintptr_t *)setadd ((void **)cj->hours, (void *)num, SET_NOALLOC);
	}
   }

   free (x);
  } else if (strmatch (attributes[i], "minutes") || strmatch (attributes[i], "minute")) {
   char **x = str2set (':', attributes[i+1]);
   uint32_t j = 0;

   for (; x[j]; j++) {
    uintptr_t num = parse_integer (x[j]);

    if (num) {
     cj->minutes = (uintptr_t *)setadd ((void **)cj->minutes, (void *)num, SET_NOALLOC);
	}
   }

   free (x);
  } else if (strmatch (attributes[i], "seconds") || strmatch (attributes[i], "second")) {
   char **x = str2set (':', attributes[i+1]);
   uint32_t j = 0;

   for (; x[j]; j++) {
    uintptr_t num = parse_integer (x[j]);

    if (num) {
     cj->seconds = (uintptr_t *)setadd ((void **)cj->seconds, (void *)num, SET_NOALLOC);
	}
   }

   free (x);
  } else if (strmatch (attributes[i], "weekdays") || strmatch (attributes[i], "weekday")) {
   char **x = str2set (':', attributes[i+1]);
   uint32_t j = 0;

   for (; x[j]; j++) {
    if (strmatch (x[j], "sunday")) {
     cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)0, SET_NOALLOC);
	} else if (strmatch (x[j], "monday")) {
     cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)1, SET_NOALLOC);
	} else if (strmatch (x[j], "tuesday")) {
     cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)2, SET_NOALLOC);
	} else if (strmatch (x[j], "wednesday")) {
     cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)3, SET_NOALLOC);
	} else if (strmatch (x[j], "thursday")) {
     cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)4, SET_NOALLOC);
	} else if (strmatch (x[j], "friday")) {
     cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)5, SET_NOALLOC);
	} else if (strmatch (x[j], "saturday")) {
     cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)6, SET_NOALLOC);
	}
   }

   free (x);
  }
 }

 return cj;
}
Пример #15
0
Файл: options.c Проект: 12qu/feh
static void feh_parse_option_array(int argc, char **argv, int finalrun)
{
	int discard;
	static char stropts[] =
		"a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqrR:sS:tT:uUvVwW:xXy:YzZ"
		".@:^:~:):|:+:<:>:";

	/* (*name, has_arg, *flag, val) See: struct option in getopts.h */
	static struct option lopts[] = {
		{"menu-bg"       , 1, 0, ')'},
		{"debug"         , 0, 0, '+'},
		{"scale-down"    , 0, 0, '.'},
		{"max-dimension" , 1, 0, '<'},
		{"min-dimension" , 1, 0, '>'},
		{"title-font"    , 1, 0, '@'},
		{"action"        , 1, 0, 'A'},
		{"image-bg"      , 1, 0, 'B'},
		{"fontpath"      , 1, 0, 'C'},
		{"slideshow-delay",1, 0, 'D'},
		{"thumb-height"  , 1, 0, 'E'},
		{"full-screen"   , 0, 0, 'F'}, /* deprecated */
		{"fullscreen"    , 0, 0, 'F'},
		{"draw-actions"  , 0, 0, 'G'},
		{"limit-height"  , 1, 0, 'H'},
		{"fullindex"     , 0, 0, 'I'},
		{"thumb-redraw"  , 1, 0, 'J'},
		{"caption-path"  , 1, 0, 'K'},
		{"customlist"    , 1, 0, 'L'},
		{"menu-font"     , 1, 0, 'M'},
		{"no-menus"      , 0, 0, 'N'},
		{"output-only"   , 1, 0, 'O'},
		{"cache-thumbnails", 0, 0, 'P'},
		{"reload"        , 1, 0, 'R'},
		{"sort"          , 1, 0, 'S'},
		{"theme"         , 1, 0, 'T'},
		{"loadable"      , 0, 0, 'U'},
		{"verbose"       , 0, 0, 'V'},
		{"limit-width"   , 1, 0, 'W'},
		{"ignore-aspect" , 0, 0, 'X'},
		{"hide-pointer"  , 0, 0, 'Y'},
		{"auto-zoom"     , 0, 0, 'Z'},
		{"title"         , 1, 0, '^'},
		{"alpha"         , 1, 0, 'a'},
		{"bg"            , 1, 0, 'b'},
		{"collage"       , 0, 0, 'c'},
		{"draw-filename" , 0, 0, 'd'},
		{"font"          , 1, 0, 'e'},
		{"filelist"      , 1, 0, 'f'},
		{"geometry"      , 1, 0, 'g'},
		{"help"          , 0, 0, 'h'},
		{"index"         , 0, 0, 'i'},
		{"output-dir"    , 1, 0, 'j'},
		{"keep-http"     , 0, 0, 'k'},
		{"list"          , 0, 0, 'l'},
		{"montage"       , 0, 0, 'm'},
		{"reverse"       , 0, 0, 'n'},
		{"output"        , 1, 0, 'o'},
		{"preload"       , 0, 0, 'p'},
		{"quiet"         , 0, 0, 'q'},
		{"recursive"     , 0, 0, 'r'},
		{"stretch"       , 0, 0, 's'},
		{"thumbnails"    , 0, 0, 't'},
		{"unloadable"    , 0, 0, 'u'},
		{"version"       , 0, 0, 'v'},
		{"multiwindow"   , 0, 0, 'w'},
		{"borderless"    , 0, 0, 'x'},
		{"thumb-width"   , 1, 0, 'y'},
		{"randomize"     , 0, 0, 'z'},
		{"start-at"      , 1, 0, '|'},
		{"thumb-title"   , 1, 0, '~'},
		{"bg-tile"       , 0, 0, 200},
		{"bg-center"     , 0, 0, 201},
		{"bg-scale"      , 0, 0, 202},
		{"zoom"          , 1, 0, 205},
		{"no-screen-clip", 0, 0, 206},
		{"index-info"    , 1, 0, 207},
		{"magick-timeout", 1, 0, 208},
		{"action1"       , 1, 0, 209},
		{"action2"       , 1, 0, 210},
		{"action3"       , 1, 0, 211},
		{"action4"       , 1, 0, 212},
		{"action5"       , 1, 0, 213},
		{"action6"       , 1, 0, 214},
		{"action7"       , 1, 0, 215},
		{"action8"       , 1, 0, 216},
		{"action9"       , 1, 0, 217},
		{"bg-fill"       , 0, 0, 218},
		{"bg-max"        , 0, 0, 219},
		{"no-jump-on-resort", 0, 0, 220},
#ifdef HAVE_LIBEXIF
		{"draw-exif"     , 0, 0, 223},
#endif
		{"cycle-once"    , 0, 0, 224},
		{"no-xinerama"   , 0, 0, 225},
		{"draw-tinted"   , 0, 0, 229},
		{"info"          , 1, 0, 234},
		{"force-aliasing", 0, 0, 235},
		{"no-fehbg"      , 0, 0, 236},

		{0, 0, 0, 0}
	};
	int optch = 0, cmdx = 0;

	while ((optch = getopt_long(argc, argv, stropts, lopts, &cmdx)) != EOF) {
		D(("Got option, getopt calls it %d, or %c\n", optch, optch));
		switch (optch) {
		case 0:
			break;
		case ')':
			free(opt.menu_bg);
			opt.menu_bg = estrdup(optarg);
			weprintf("The --menu-bg option is deprecated and will be removed by 2012");
			break;
		case '+':
			opt.debug = 1;
			break;
		case '<':
			XParseGeometry(optarg, &discard, &discard, &opt.max_width, &opt.max_height);
			break;
		case '>':
			XParseGeometry(optarg, &discard, &discard, &opt.min_width, &opt.min_height);
			break;
		case '.':
			opt.scale_down = 1;
			break;
		case '@':
			opt.title_font = estrdup(optarg);
			break;
		case 'A':
			opt.actions[0] = estrdup(optarg);
			break;
		case 'B':
			if (!strcmp(optarg, "checks"))
				opt.image_bg = IMAGE_BG_CHECKS;
			else if (!strcmp(optarg, "white"))
				opt.image_bg = IMAGE_BG_WHITE;
			else if (!strcmp(optarg, "black"))
				opt.image_bg = IMAGE_BG_BLACK;
			else
				weprintf("Unknown argument to --image-bg: %s", optarg);
			break;
		case 'C':
			D(("adding fontpath %s\n", optarg));
			imlib_add_path_to_font_path(optarg);
			break;
		case 'D':
			opt.slideshow_delay = atof(optarg);
			if (opt.slideshow_delay < 0.0) {
				opt.slideshow_delay *= (-1);
				opt.paused = 1;
			}
			break;
		case 'E':
			opt.thumb_h = atoi(optarg);
			break;
		case 'F':
			opt.full_screen = 1;
			break;
		case 'G':
			opt.draw_actions = 1;
			break;
		case 'H':
			opt.limit_h = atoi(optarg);
			break;
		case 'I':
			opt.index = 1;
			opt.index_info = estrdup("%n\n%S\n%wx%h");
			break;
		case 'J':
			opt.thumb_redraw = atoi(optarg);
			break;
		case 'K':
			opt.caption_path = estrdup(optarg);
			break;
		case 'L':
			opt.customlist = estrdup(optarg);
			opt.display = 0;
			break;
		case 'M':
			free(opt.menu_font);
			opt.menu_font = estrdup(optarg);
			break;
		case 'N':
			opt.no_menus = 1;
			break;
		case 'O':
			opt.output = 1;
			opt.output_file = estrdup(optarg);
			opt.display = 0;
			break;
		case 'P':
			opt.cache_thumbnails = 1;
			break;
		case 'R':
			opt.reload = atof(optarg);
			break;
		case 'S':
			if (!strcasecmp(optarg, "name"))
				opt.sort = SORT_NAME;
			else if (!strcasecmp(optarg, "filename"))
				opt.sort = SORT_FILENAME;
			else if (!strcasecmp(optarg, "width"))
				opt.sort = SORT_WIDTH;
			else if (!strcasecmp(optarg, "height"))
				opt.sort = SORT_HEIGHT;
			else if (!strcasecmp(optarg, "pixels"))
				opt.sort = SORT_PIXELS;
			else if (!strcasecmp(optarg, "size"))
				opt.sort = SORT_SIZE;
			else if (!strcasecmp(optarg, "format"))
				opt.sort = SORT_FORMAT;
			else {
				weprintf("Unrecognised sort mode \"%s\". Defaulting to "
						"sort by filename", optarg);
				opt.sort = SORT_FILENAME;
			}
			break;
		case 'T':
			theme = estrdup(optarg);
			break;
		case 'U':
			opt.loadables = 1;
			opt.display = 0;
			break;
		case 'V':
			opt.verbose = 1;
			break;
		case 'W':
			opt.limit_w = atoi(optarg);
			break;
		case 'X':
			opt.aspect = 0;
			break;
		case 'Y':
			opt.hide_pointer = 1;
			break;
		case 'Z':
			opt.zoom_mode = ZOOM_MODE_MAX;
			break;
		case '^':
			opt.title = estrdup(optarg);
			break;
		case 'a':
			opt.alpha = 1;
			opt.alpha_level = 255 - atoi(optarg);
			break;
		case 'b':
			opt.bg = 1;
			opt.bg_file = estrdup(optarg);
			break;
		case 'c':
			opt.collage = 1;
			break;
		case 'd':
			opt.draw_filename = 1;
			break;
		case 'e':
			opt.font = estrdup(optarg);
			break;
		case 'f':
			if (!strcmp(optarg, "-"))
				opt.filelistfile = estrdup("/dev/stdin");
			else
				opt.filelistfile = estrdup(optarg);
			break;
		case 'g':
			opt.geom_flags = XParseGeometry(optarg, &opt.geom_x,
					&opt.geom_y, &opt.geom_w, &opt.geom_h);
			break;
		case 'h':
			show_usage();
			break;
		case 'i':
			opt.index = 1;
			opt.index_info = estrdup("%n");
			break;
		case 'j':
			opt.output_dir = estrdup(optarg);
			break;
		case 'k':
			opt.keep_http = 1;
			break;
		case 'l':
			opt.list = 1;
			opt.display = 0;
			break;
		case 'm':
			opt.index = 1;
			break;
		case 'n':
			opt.reverse = 1;
			break;
		case 'o':
			opt.output = 1;
			opt.output_file = estrdup(optarg);
			break;
		case 'p':
			opt.preload = 1;
			break;
		case 'q':
			opt.quiet = 1;
			break;
		case 'r':
			opt.recursive = 1;
			break;
		case 's':
			opt.stretch = 1;
			break;
		case 't':
			opt.thumbs = 1;
			opt.index_info = estrdup("%n");
			break;
		case 'u':
			opt.unloadables = 1;
			opt.display = 0;
			break;
		case 'v':
			show_version();
			break;
		case 'w':
			opt.multiwindow = 1;
			break;
		case 'x':
			opt.borderless = 1;
			break;
		case 'y':
			opt.thumb_w = atoi(optarg);
			break;
		case 'z':
			opt.randomize = 1;
			break;
		case '|':
			opt.start_list_at = estrdup(optarg);
			break;
		case '~':
			opt.thumb_title = estrdup(optarg);
			break;
		case 200:
			opt.bgmode = BG_MODE_TILE;
			break;
		case 201:
			opt.bgmode = BG_MODE_CENTER;
			break;
		case 202:
			opt.bgmode = BG_MODE_SCALE;
			break;
		case 205:
			if (!strcmp("fill", optarg))
				opt.zoom_mode = ZOOM_MODE_FILL;
			else if (!strcmp("max", optarg))
				opt.zoom_mode = ZOOM_MODE_MAX;
			else
				opt.default_zoom = atoi(optarg);
			break;
		case 206:
			opt.screen_clip = 0;
			break;
		case 207:
			opt.index_info = estrdup(optarg);
			break;
		case 208:
			opt.magick_timeout = atoi(optarg);
			break;
		case 209:
			opt.actions[1] = estrdup(optarg);
			break;
		case 210:
			opt.actions[2] = estrdup(optarg);
			break;
		case 211:
			opt.actions[3] = estrdup(optarg);
			break;
		case 212:
			opt.actions[4] = estrdup(optarg);
			break;
		case 213:
			opt.actions[5] = estrdup(optarg);
			break;
		case 214:
			opt.actions[6] = estrdup(optarg);
			break;
		case 215:
			opt.actions[7] = estrdup(optarg);
			break;
		case 216:
			opt.actions[8] = estrdup(optarg);
			break;
		case 217:
			opt.actions[9] = estrdup(optarg);
			break;
		case 218:
			opt.bgmode = BG_MODE_FILL;
			break;
		case 219:
			opt.bgmode = BG_MODE_MAX;
			break;
		case 220:
			opt.jump_on_resort = 0;
			break;
#ifdef HAVE_LIBEXIF
		case 223:
			opt.draw_exif = 1;
			break;
#endif
		case 224:
			opt.cycle_once = 1;
			break;
		case 225:
			opt.xinerama = 0;
			break;
		case 229:
			opt.text_bg = TEXT_BG_TINTED;
			break;
		case 234:
			opt.info_cmd = estrdup(optarg);
			opt.draw_info = 1;
			break;
		case 235:
			opt.force_aliasing = 1;
			break;
		case 236:
			opt.no_fehbg = 1;
			break;
		default:
			break;
		}
	}

	/* Now the leftovers, which must be files */
	if (optind < argc) {
		while (optind < argc) {
			if (opt.reload)
				original_file_items = gib_list_add_front(original_file_items, estrdup(argv[optind]));
			/* If recursive is NOT set, but the only argument is a directory
			   name, we grab all the files in there, but not subdirs */
			add_file_to_filelist_recursively(argv[optind++], FILELIST_FIRST);
		}
	}
	else if (finalrun && !opt.filelistfile && !opt.bgmode)
		add_file_to_filelist_recursively(".", FILELIST_FIRST);

	/* So that we can safely be called again */
	optind = 0;
	return;
}
Пример #16
0
xml_element* DANDARPC_to_xml_element_worker(XMLRPC_REQUEST request, XMLRPC_VALUE node) {
#define BUF_SIZE 512
   xml_element* root = NULL;
   if(node) {
      char buf[BUF_SIZE];
      const char* id = XMLRPC_GetValueID(node);
      XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(node);
      XMLRPC_REQUEST_OUTPUT_OPTIONS output = XMLRPC_RequestGetOutputOptions(request);
      int bNoAddType = (type == xmlrpc_string && request && output && output->xml_elem_opts.verbosity == xml_elem_no_white_space);
      xml_element* elem_val = xml_elem_new();
      const char* pAttrType = NULL;

      xml_element_attr* attr_type = bNoAddType ? NULL : emalloc(sizeof(xml_element_attr));

      if(attr_type) {
         attr_type->key = estrdup(ATTR_TYPE);
         attr_type->val = 0;
         Q_PushTail(&elem_val->attrs, attr_type);
      }

      elem_val->name = (type == xmlrpc_vector) ? estrdup(ATTR_VECTOR) : estrdup(ATTR_SCALAR);

      if(id && *id) {
         xml_element_attr* attr_id = emalloc(sizeof(xml_element_attr));
         if(attr_id) {
            attr_id->key = estrdup(ATTR_ID);
            attr_id->val = estrdup(id);
            Q_PushTail(&elem_val->attrs, attr_id);
         }
      }

      switch(type) {
         case xmlrpc_string:
            pAttrType = ATTR_STRING;
            simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node));
            break;
         case xmlrpc_int:
            pAttrType = ATTR_INT;
            snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node));
            simplestring_add(&elem_val->text, buf);
            break;
         case xmlrpc_boolean:
            pAttrType = ATTR_BOOLEAN;
            snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node));
            simplestring_add(&elem_val->text, buf);
            break;
         case xmlrpc_double:
            pAttrType = ATTR_DOUBLE;
            snprintf(buf, BUF_SIZE, "%f", XMLRPC_GetValueDouble(node));
            simplestring_add(&elem_val->text, buf);
            break;
         case xmlrpc_datetime:
            pAttrType = ATTR_DATETIME;
            simplestring_add(&elem_val->text, XMLRPC_GetValueDateTime_ISO8601(node));
            break;
         case xmlrpc_base64:
            {
               struct buffer_st buf;
               pAttrType = ATTR_BASE64;
               base64_encode_xmlrpc(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node));
               simplestring_addn(&elem_val->text, buf.data, buf.offset );
               buffer_delete(&buf);
            }
            break;
         case xmlrpc_vector:
            {
               XMLRPC_VECTOR_TYPE my_type = XMLRPC_GetVectorType(node);
               XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node);

               switch(my_type) {
                  case xmlrpc_vector_array:
                     pAttrType = ATTR_ARRAY;
                     break;
                  case xmlrpc_vector_mixed:
                     pAttrType = ATTR_MIXED;
                     break;
                  case xmlrpc_vector_struct:
                     pAttrType = ATTR_STRUCT;
                     break;
                  default:
                     break;
               }

               /* recurse through sub-elements */
               while( xIter ) {
                  xml_element* next_el = DANDARPC_to_xml_element_worker(request, xIter);
                  if(next_el) {
                     Q_PushTail(&elem_val->children, next_el);
                  }
                  xIter = XMLRPC_VectorNext(node);
               }
            }
            break;
         default:
            break;
      }
      if(pAttrType && attr_type && !bNoAddType) {
         attr_type->val = estrdup(pAttrType);
      }
      root = elem_val;
   }
   return root;
}
Пример #17
0
void
ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
{
	int32 ipc;
	Prog *p;
	int v, o, r, skip;
	Sym *h[NSYM], *s;
	uint32 sig;
	int ntext;
	int32 eof;
	char *name, *x;
	char src[1024];
	Prog *lastp;

	lastp = nil;
	ntext = 0;
	eof = Boffset(f) + len;
	src[0] = 0;
	pn = estrdup(pn); // we keep it in Sym* references

newloop:
	memset(h, 0, sizeof(h));
	version++;
	histfrogp = 0;
	ipc = pc;
	skip = 0;

loop:
	if(f->state == Bracteof || Boffset(f) >= eof)
		goto eof;
	o = BGETC(f);
	if(o == Beof)
		goto eof;
	o |= BGETC(f) << 8;
	if(o <= AXXX || o >= ALAST) {
		if(o < 0)
			goto eof;
		diag("%s:#%lld: opcode out of range: %#ux", pn, Boffset(f), o);
		print("	probably not a .%c file\n", thechar);
		errorexit();
	}

	if(o == ANAME || o == ASIGNAME) {
		sig = 0;
		if(o == ASIGNAME)
			sig = Bget4(f);
		v = BGETC(f);	/* type */
		o = BGETC(f);	/* sym */
		r = 0;
		if(v == D_STATIC)
			r = version;
		name = Brdline(f, '\0');
		if(name == nil) {
			if(Blinelen(f) > 0) {
				fprint(2, "%s: name too long\n", pn);
				errorexit();
			}
			goto eof;
		}
		x = expandpkg(name, pkg);
		s = lookup(x, r);
		if(x != name)
			free(x);

		if(debug['S'] && r == 0)
			sig = 1729;
		if(sig != 0){
			if(s->sig != 0 && s->sig != sig)
				diag("incompatible type signatures "
					"%ux(%s) and %ux(%s) for %s",
					s->sig, s->file, sig, pn, s->name);
			s->sig = sig;
			s->file = pn;
		}

		if(debug['W'])
			print("	ANAME	%s\n", s->name);
		if(o < 0 || o >= nelem(h))
			mangle(pn);
		h[o] = s;
		if((v == D_EXTERN || v == D_STATIC) && s->type == 0)
			s->type = SXREF;
		if(v == D_FILE) {
			if(s->type != SFILE) {
				histgen++;
				s->type = SFILE;
				s->value = histgen;
			}
			if(histfrogp < MAXHIST) {
				histfrog[histfrogp] = s;
				histfrogp++;
			} else
				collapsefrog(s);
			dwarfaddfrag(s->value, s->name);
		}
		goto loop;
	}

	p = mal(sizeof(*p));
	p->as = o;
	p->line = Bget4(f);
	p->back = 2;
	zaddr(pn, f, &p->from, h);
	fromgotype = adrgotype;
	zaddr(pn, f, &p->to, h);

	if(debug['W'])
		print("%P\n", p);

	switch(p->as) {
	case AHISTORY:
		if(p->to.offset == -1) {
			addlib(src, pn);
			histfrogp = 0;
			goto loop;
		}
		if(src[0] == '\0')
			copyhistfrog(src, sizeof src);
		addhist(p->line, D_FILE);		/* 'z' */
		if(p->to.offset)
			addhist(p->to.offset, D_FILE1);	/* 'Z' */
		histfrogp = 0;
		goto loop;

	case AEND:
		histtoauto();
		if(cursym != nil && cursym->text)
			cursym->autom = curauto;
		curauto = 0;
		cursym = nil;
		if(Boffset(f) == eof)
			return;
		goto newloop;

	case AGLOBL:
		s = p->from.sym;
		if(s->type == 0 || s->type == SXREF) {
			s->type = SBSS;
			s->size = 0;
		}
		if(s->type != SBSS && s->type != SNOPTRBSS && !s->dupok) {
			diag("%s: redefinition: %s in %s",
				pn, s->name, TNAME);
			s->type = SBSS;
			s->size = 0;
		}
		if(p->to.offset > s->size)
			s->size = p->to.offset;
		if(p->from.scale & DUPOK)
			s->dupok = 1;
		if(p->from.scale & RODATA)
			s->type = SRODATA;
		else if(p->from.scale & NOPTR)
			s->type = SNOPTRBSS;
		goto loop;

	case ADATA:
		// Assume that AGLOBL comes after ADATA.
		// If we've seen an AGLOBL that said this sym was DUPOK,
		// ignore any more ADATA we see, which must be
		// redefinitions.
		s = p->from.sym;
		if(s->dupok) {
//			if(debug['v'])
//				Bprint(&bso, "skipping %s in %s: dupok\n", s->name, pn);
			goto loop;
		}
		if(s->file == nil)
			s->file = pn;
		else if(s->file != pn) {
			diag("multiple initialization for %s: in both %s and %s", s->name, s->file, pn);
			errorexit();
		}
		savedata(s, p, pn);
		unmal(p, sizeof *p);
		goto loop;

	case AGOK:
		diag("%s: GOK opcode in %s", pn, TNAME);
		pc++;
		goto loop;

	case ALOCALS:
		cursym->locals = p->to.offset;
		pc++;
		goto loop;

	case ATYPE:
		pc++;
		goto loop;

	case ATEXT:
		s = p->from.sym;
		if(s->text != nil) {
			if(p->from.scale & DUPOK) {
				skip = 1;
				goto casdef;
			}
			diag("%s: %s: redefinition", pn, s->name);
			return;
		}
		if(ntext++ == 0 && s->type != 0 && s->type != SXREF) {
			/* redefinition, so file has probably been seen before */
			if(debug['v'])
				diag("skipping: %s: redefinition: %s", pn, s->name);
			return;
		}
		if(cursym != nil && cursym->text) {
			histtoauto();
			cursym->autom = curauto;
			curauto = 0;
		}
		skip = 0;
		if(etextp)
			etextp->next = s;
		else
			textp = s;
		etextp = s;
		s->text = p;
		cursym = s;
		if(s->type != 0 && s->type != SXREF) {
			if(p->from.scale & DUPOK) {
				skip = 1;
				goto casdef;
			}
			diag("%s: redefinition: %s\n%P", pn, s->name, p);
		}
		s->type = STEXT;
		s->value = pc;
		s->args = p->to.offset2;
		lastp = p;
		p->pc = pc++;
		goto loop;

	case AFMOVF:
	case AFADDF:
	case AFSUBF:
	case AFSUBRF:
	case AFMULF:
	case AFDIVF:
	case AFDIVRF:
	case AFCOMF:
	case AFCOMFP:
	case AMOVSS:
	case AADDSS:
	case ASUBSS:
	case AMULSS:
	case ADIVSS:
	case ACOMISS:
	case AUCOMISS:
		if(skip)
			goto casdef;
		if(p->from.type == D_FCONST) {
			/* size sb 9 max */
			sprint(literal, "$%ux", ieeedtof(&p->from.ieee));
			s = lookup(literal, 0);
			if(s->type == 0) {
				s->type = SRODATA;
				adduint32(s, ieeedtof(&p->from.ieee));
				s->reachable = 0;
			}
			p->from.type = D_EXTERN;
			p->from.sym = s;
			p->from.offset = 0;
		}
		goto casdef;

	case AFMOVD:
	case AFADDD:
	case AFSUBD:
	case AFSUBRD:
	case AFMULD:
	case AFDIVD:
	case AFDIVRD:
	case AFCOMD:
	case AFCOMDP:
	case AMOVSD:
	case AADDSD:
	case ASUBSD:
	case AMULSD:
	case ADIVSD:
	case ACOMISD:
	case AUCOMISD:
		if(skip)
			goto casdef;
		if(p->from.type == D_FCONST) {
			/* size sb 18 max */
			sprint(literal, "$%ux.%ux",
				p->from.ieee.l, p->from.ieee.h);
			s = lookup(literal, 0);
			if(s->type == 0) {
				s->type = SRODATA;
				adduint32(s, p->from.ieee.l);
				adduint32(s, p->from.ieee.h);
				s->reachable = 0;
			}
			p->from.type = D_EXTERN;
			p->from.sym = s;
			p->from.offset = 0;
		}
		goto casdef;

	casdef:
	default:
		if(skip)
			nopout(p);
		p->pc = pc;
		pc++;

		if(p->to.type == D_BRANCH)
			p->to.offset += ipc;
		if(lastp == nil) {
			if(p->as != ANOP)
				diag("unexpected instruction: %P", p);
			goto loop;
		}
		lastp->link = p;
		lastp = p;
		goto loop;
	}

eof:
	diag("truncated object file: %s", pn);
}
php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context, int redirect_max, int flags STREAMS_DC TSRMLS_DC) /* {{{ */
{
	php_stream *stream = NULL;
	php_url *resource = NULL;
	int use_ssl;
	int use_proxy = 0;
	char *scratch = NULL;
	char *tmp = NULL;
	char *ua_str = NULL;
	zval **ua_zval = NULL, **tmpzval = NULL;
	int scratch_len = 0;
	int body = 0;
	char location[HTTP_HEADER_BLOCK_SIZE];
	zval *response_header = NULL;
	int reqok = 0;
	char *http_header_line = NULL;
	char tmp_line[128];
	size_t chunk_size = 0, file_size = 0;
	int eol_detect = 0;
	char *transport_string, *errstr = NULL;
	int transport_len, have_header = 0, request_fulluri = 0, ignore_errors = 0;
	char *protocol_version = NULL;
	int protocol_version_len = 3; /* Default: "1.0" */
	struct timeval timeout;
	char *user_headers = NULL;
	int header_init = ((flags & HTTP_WRAPPER_HEADER_INIT) != 0);
	int redirected = ((flags & HTTP_WRAPPER_REDIRECTED) != 0);
	int follow_location = 1;
	php_stream_filter *transfer_encoding = NULL;

	tmp_line[0] = '\0';

	if (redirect_max < 1) {
		php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Redirection limit reached, aborting");
		return NULL;
	}

	resource = php_url_parse(path);
	if (resource == NULL) {
		return NULL;
	}

	if (strncasecmp(resource->scheme, "http", sizeof("http")) && strncasecmp(resource->scheme, "https", sizeof("https"))) {
		if (!context || 
			php_stream_context_get_option(context, wrapper->wops->label, "proxy", &tmpzval) == FAILURE ||
			Z_TYPE_PP(tmpzval) != IS_STRING ||
			Z_STRLEN_PP(tmpzval) <= 0) {
			php_url_free(resource);
			return php_stream_open_wrapper_ex(path, mode, ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
		}
		/* Called from a non-http wrapper with http proxying requested (i.e. ftp) */
		request_fulluri = 1;
		use_ssl = 0;
		use_proxy = 1;

		transport_len = Z_STRLEN_PP(tmpzval);
		transport_string = estrndup(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval));
	} else {
		/* Normal http request (possibly with proxy) */
	
		if (strpbrk(mode, "awx+")) {
			php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP wrapper does not support writeable connections");
			php_url_free(resource);
			return NULL;
		}

		use_ssl = resource->scheme && (strlen(resource->scheme) > 4) && resource->scheme[4] == 's';
		/* choose default ports */
		if (use_ssl && resource->port == 0)
			resource->port = 443;
		else if (resource->port == 0)
			resource->port = 80;

		if (context &&
			php_stream_context_get_option(context, wrapper->wops->label, "proxy", &tmpzval) == SUCCESS &&
			Z_TYPE_PP(tmpzval) == IS_STRING &&
			Z_STRLEN_PP(tmpzval) > 0) {
			use_proxy = 1;
			transport_len = Z_STRLEN_PP(tmpzval);
			transport_string = estrndup(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval));
		} else {
			transport_len = spprintf(&transport_string, 0, "%s://%s:%d", use_ssl ? "ssl" : "tcp", resource->host, resource->port);
		}
	}

	if (context && php_stream_context_get_option(context, wrapper->wops->label, "timeout", &tmpzval) == SUCCESS) {
		SEPARATE_ZVAL(tmpzval);
		convert_to_double_ex(tmpzval);
		timeout.tv_sec = (time_t) Z_DVAL_PP(tmpzval);
		timeout.tv_usec = (size_t) ((Z_DVAL_PP(tmpzval) - timeout.tv_sec) * 1000000);
	} else {
		timeout.tv_sec = FG(default_socket_timeout);
		timeout.tv_usec = 0;
	}

	stream = php_stream_xport_create(transport_string, transport_len, options,
			STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT,
			NULL, &timeout, context, &errstr, NULL);
    
	if (stream) {
		php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &timeout);
	}
			
	if (errstr) {
		php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "%s", errstr);
		efree(errstr);
		errstr = NULL;
	}

	efree(transport_string);

	if (stream && use_proxy && use_ssl) {
		smart_str header = {0};

		smart_str_appendl(&header, "CONNECT ", sizeof("CONNECT ")-1);
		smart_str_appends(&header, resource->host);
		smart_str_appendc(&header, ':');
		smart_str_append_unsigned(&header, resource->port);
		smart_str_appendl(&header, " HTTP/1.0\r\n", sizeof(" HTTP/1.0\r\n")-1);

	    /* check if we have Proxy-Authorization header */
		if (context && php_stream_context_get_option(context, "http", "header", &tmpzval) == SUCCESS) {
			char *s, *p;

			if (Z_TYPE_PP(tmpzval) == IS_ARRAY) {
				HashPosition pos;
				zval **tmpheader = NULL;

				for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(tmpzval), &pos);
					SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(tmpzval), (void *)&tmpheader, &pos);
					zend_hash_move_forward_ex(Z_ARRVAL_PP(tmpzval), &pos)) {
					if (Z_TYPE_PP(tmpheader) == IS_STRING) {
						s = Z_STRVAL_PP(tmpheader);
						do {
							while (*s == ' ' || *s == '\t') s++;
							p = s;
							while (*p != 0 && *p != ':' && *p != '\r' && *p !='\n') p++;
							if (*p == ':') {
								p++;
								if (p - s == sizeof("Proxy-Authorization:") - 1 &&
								    zend_binary_strcasecmp(s, sizeof("Proxy-Authorization:") - 1,
								        "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) {
									while (*p != 0 && *p != '\r' && *p !='\n') p++;
									smart_str_appendl(&header, s, p - s);
									smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1);
									goto finish;
								} else {
									while (*p != 0 && *p != '\r' && *p !='\n') p++;
								}
							}
							s = p;
							while (*s == '\r' || *s == '\n') s++;
						} while (*s != 0);
					}
				}
			} else if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) {
				s = Z_STRVAL_PP(tmpzval);
				do {
					while (*s == ' ' || *s == '\t') s++;
					p = s;
					while (*p != 0 && *p != ':' && *p != '\r' && *p !='\n') p++;
					if (*p == ':') {
						p++;
						if (p - s == sizeof("Proxy-Authorization:") - 1 &&
						    zend_binary_strcasecmp(s, sizeof("Proxy-Authorization:") - 1,
						        "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) {
							while (*p != 0 && *p != '\r' && *p !='\n') p++;
							smart_str_appendl(&header, s, p - s);
							smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1);
							goto finish;
						} else {
							while (*p != 0 && *p != '\r' && *p !='\n') p++;
						}
					}
					s = p;
					while (*s == '\r' || *s == '\n') s++;
				} while (*s != 0);
			}
		}
finish:
		smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1);

		if (php_stream_write(stream, header.c, header.len) != header.len) {
			php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Cannot connect to HTTPS server through proxy");
			php_stream_close(stream);
			stream = NULL;
		}
 	 	smart_str_free(&header);

 	 	if (stream) {
 	 		char header_line[HTTP_HEADER_BLOCK_SIZE];

			/* get response header */
			while (php_stream_gets(stream, header_line, HTTP_HEADER_BLOCK_SIZE-1) != NULL) {
				if (header_line[0] == '\n' ||
				    header_line[0] == '\r' ||
				    header_line[0] == '\0') {
				  break;
				}
			}
		}

		/* enable SSL transport layer */
		if (stream) {
			if (php_stream_xport_crypto_setup(stream, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL TSRMLS_CC) < 0 ||
			    php_stream_xport_crypto_enable(stream, 1 TSRMLS_CC) < 0) {
				php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Cannot connect to HTTPS server through proxy");
				php_stream_close(stream);
				stream = NULL;
			}
		}
	}

	if (stream == NULL)
		goto out;

	/* avoid buffering issues while reading header */
	if (options & STREAM_WILL_CAST)
		chunk_size = php_stream_set_chunk_size(stream, 1);
	
	/* avoid problems with auto-detecting when reading the headers -> the headers
	 * are always in canonical \r\n format */
	eol_detect = stream->flags & (PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC);
	stream->flags &= ~(PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC);

	php_stream_context_set(stream, context);

	php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0);

	if (header_init && context && php_stream_context_get_option(context, "http", "max_redirects", &tmpzval) == SUCCESS) {
		SEPARATE_ZVAL(tmpzval);
		convert_to_long_ex(tmpzval);
		redirect_max = Z_LVAL_PP(tmpzval);
	}

	if (context && php_stream_context_get_option(context, "http", "method", &tmpzval) == SUCCESS) {
		if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) {
			/* As per the RFC, automatically redirected requests MUST NOT use other methods than
			 * GET and HEAD unless it can be confirmed by the user */
			if (!redirected
				|| (Z_STRLEN_PP(tmpzval) == 3 && memcmp("GET", Z_STRVAL_PP(tmpzval), 3) == 0)
				|| (Z_STRLEN_PP(tmpzval) == 4 && memcmp("HEAD",Z_STRVAL_PP(tmpzval), 4) == 0)
			) {
				scratch_len = strlen(path) + 29 + Z_STRLEN_PP(tmpzval);
				scratch = emalloc(scratch_len);
				strlcpy(scratch, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval) + 1);
				strncat(scratch, " ", 1);
			}
		}
	}
 
	if (context && php_stream_context_get_option(context, "http", "protocol_version", &tmpzval) == SUCCESS) {
		SEPARATE_ZVAL(tmpzval);
		convert_to_double_ex(tmpzval);
		protocol_version_len = spprintf(&protocol_version, 0, "%.1F", Z_DVAL_PP(tmpzval));
	}

	if (!scratch) {
		scratch_len = strlen(path) + 29 + protocol_version_len;
		scratch = emalloc(scratch_len);
		strncpy(scratch, "GET ", scratch_len);
	}

	/* Should we send the entire path in the request line, default to no. */
	if (!request_fulluri &&
		context &&
		php_stream_context_get_option(context, "http", "request_fulluri", &tmpzval) == SUCCESS) {
		zval ztmp = **tmpzval;

		zval_copy_ctor(&ztmp);
		convert_to_boolean(&ztmp);
		request_fulluri = Z_BVAL(ztmp) ? 1 : 0;
		zval_dtor(&ztmp);
	}

	if (request_fulluri) {
		/* Ask for everything */
		strcat(scratch, path);
	} else {
		/* Send the traditional /path/to/file?query_string */

		/* file */
		if (resource->path && *resource->path) {
			strlcat(scratch, resource->path, scratch_len);
		} else {
			strlcat(scratch, "/", scratch_len);
		}

		/* query string */
		if (resource->query) {
			strlcat(scratch, "?", scratch_len);
			strlcat(scratch, resource->query, scratch_len);
		}
	}

	/* protocol version we are speaking */
	if (protocol_version) {
		strlcat(scratch, " HTTP/", scratch_len);
		strlcat(scratch, protocol_version, scratch_len);
		strlcat(scratch, "\r\n", scratch_len);
		efree(protocol_version);
		protocol_version = NULL;
	} else {
		strlcat(scratch, " HTTP/1.0\r\n", scratch_len);
	}

	/* send it */
	php_stream_write(stream, scratch, strlen(scratch));

	if (context && php_stream_context_get_option(context, "http", "header", &tmpzval) == SUCCESS) {
		tmp = NULL;
		
		if (Z_TYPE_PP(tmpzval) == IS_ARRAY) {
			HashPosition pos;
			zval **tmpheader = NULL;
			smart_str tmpstr = {0};

			for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(tmpzval), &pos);
				SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(tmpzval), (void *)&tmpheader, &pos);
				zend_hash_move_forward_ex(Z_ARRVAL_PP(tmpzval), &pos)
			) {
				if (Z_TYPE_PP(tmpheader) == IS_STRING) {
					smart_str_appendl(&tmpstr, Z_STRVAL_PP(tmpheader), Z_STRLEN_PP(tmpheader));
					smart_str_appendl(&tmpstr, "\r\n", sizeof("\r\n") - 1);
				}
			}
			smart_str_0(&tmpstr);
			/* Remove newlines and spaces from start and end. there's at least one extra \r\n at the end that needs to go. */
			if (tmpstr.c) {
				tmp = php_trim(tmpstr.c, strlen(tmpstr.c), NULL, 0, NULL, 3 TSRMLS_CC);
				smart_str_free(&tmpstr);
			}
		}
		if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) {
			/* Remove newlines and spaces from start and end php_trim will estrndup() */
			tmp = php_trim(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval), NULL, 0, NULL, 3 TSRMLS_CC);
		}
		if (tmp && strlen(tmp) > 0) {
			char *s;

			if (!header_init) { /* Remove post headers for redirects */
				int l = strlen(tmp);
				char *s2, *tmp_c = estrdup(tmp);
				
				php_strtolower(tmp_c, l);
				if ((s = strstr(tmp_c, "content-length:"))) {
					if ((s2 = memchr(s, '\n', tmp_c + l - s))) {
						int b = tmp_c + l - 1 - s2;
						memmove(tmp, tmp + (s2 + 1 - tmp_c), b);
						memmove(tmp_c, s2 + 1, b);
						
					} else {
						tmp[s - tmp_c] = *s = '\0';
					}
					l = strlen(tmp_c);
				}
				if ((s = strstr(tmp_c, "content-type:"))) {
					if ((s2 = memchr(s, '\n', tmp_c + l - s))) {
						memmove(tmp, tmp + (s2 + 1 - tmp_c), tmp_c + l - 1 - s2);
					} else {
						tmp[s - tmp_c] = '\0';
					}
				}

				efree(tmp_c);
				tmp_c = php_trim(tmp, strlen(tmp), NULL, 0, NULL, 3 TSRMLS_CC);
				efree(tmp);
				tmp = tmp_c;
			}

			user_headers = estrdup(tmp);

			/* Make lowercase for easy comparison against 'standard' headers */
			php_strtolower(tmp, strlen(tmp));
			if ((s = strstr(tmp, "user-agent:")) && 
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_USER_AGENT;
			}
			if ((s = strstr(tmp, "host:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_HOST;
			}
			if ((s = strstr(tmp, "from:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_FROM;
				}
			if ((s = strstr(tmp, "authorization:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_AUTH;
			}
			if ((s = strstr(tmp, "content-length:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_CONTENT_LENGTH;
			}
			if ((s = strstr(tmp, "content-type:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_TYPE;
			}
			/* remove Proxy-Authorization header */
			if (use_proxy && use_ssl && (s = strstr(tmp, "proxy-authorization:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				char *p = s + sizeof("proxy-authorization:") - 1;
				
				while (s > tmp && (*(s-1) == ' ' || *(s-1) == '\t')) s--;
				while (*p != 0 && *p != '\r' && *p != '\n') p++;
				while (*p == '\r' || *p == '\n') p++;
				if (*p == 0) {
					if (s == tmp) {
						efree(user_headers);
						user_headers = NULL;
					} else {
						while (s > tmp && (*(s-1) == '\r' || *(s-1) == '\n')) s--;
						user_headers[s - tmp] = 0;
					}
				} else {
					memmove(user_headers + (s - tmp), user_headers + (p - tmp), strlen(p) + 1);
				}
			}

		}
		if (tmp) {
			efree(tmp);
		}
	}

	/* auth header if it was specified */
	if (((have_header & HTTP_HEADER_AUTH) == 0) && resource->user) {
		/* decode the strings first */
		php_url_decode(resource->user, strlen(resource->user));

		/* scratch is large enough, since it was made large enough for the whole URL */
		strcpy(scratch, resource->user);
		strcat(scratch, ":");

		/* Note: password is optional! */
		if (resource->pass) {
			php_url_decode(resource->pass, strlen(resource->pass));
			strcat(scratch, resource->pass);
		}

		tmp = (char*)php_base64_encode((unsigned char*)scratch, strlen(scratch), NULL);
		
		if (snprintf(scratch, scratch_len, "Authorization: Basic %s\r\n", tmp) > 0) {
			php_stream_write(stream, scratch, strlen(scratch));
			php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, NULL, 0);
		}

		efree(tmp);
		tmp = NULL;
	}

	/* if the user has configured who they are, send a From: line */
	{
		char *from_address = php_ini_string("from", sizeof("from"), 0);
		if (((have_header & HTTP_HEADER_FROM) == 0) && from_address && from_address[0] != '\0') {
			if (snprintf(scratch, scratch_len, "From: %s\r\n", from_address) > 0)
				php_stream_write(stream, scratch, strlen(scratch));
		}
	}

	/* Send Host: header so name-based virtual hosts work */
	if ((have_header & HTTP_HEADER_HOST) == 0) {
		if ((use_ssl && resource->port != 443 && resource->port != 0) || 
			(!use_ssl && resource->port != 80 && resource->port != 0)) {
			if (snprintf(scratch, scratch_len, "Host: %s:%i\r\n", resource->host, resource->port) > 0)
				php_stream_write(stream, scratch, strlen(scratch));
		} else {
			if (snprintf(scratch, scratch_len, "Host: %s\r\n", resource->host) > 0) {
				php_stream_write(stream, scratch, strlen(scratch));
			}
		}
	}

	if (context && 
	    php_stream_context_get_option(context, "http", "user_agent", &ua_zval) == SUCCESS &&
		Z_TYPE_PP(ua_zval) == IS_STRING) {
		ua_str = Z_STRVAL_PP(ua_zval);
	} else if (FG(user_agent)) {
		ua_str = FG(user_agent);
	}

	if (((have_header & HTTP_HEADER_USER_AGENT) == 0) && ua_str) {
#define _UA_HEADER "User-Agent: %s\r\n"
		char *ua;
		size_t ua_len;
		
		ua_len = sizeof(_UA_HEADER) + strlen(ua_str);
		
		/* ensure the header is only sent if user_agent is not blank */
		if (ua_len > sizeof(_UA_HEADER)) {
			ua = emalloc(ua_len + 1);
			if ((ua_len = slprintf(ua, ua_len, _UA_HEADER, ua_str)) > 0) {
				ua[ua_len] = 0;
				php_stream_write(stream, ua, ua_len);
			} else {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot construct User-agent header");
			}

			if (ua) {
				efree(ua);
			}
		}	
	}

	if (user_headers) {
		/* A bit weird, but some servers require that Content-Length be sent prior to Content-Type for POST
		 * see bug #44603 for details. Since Content-Type maybe part of user's headers we need to do this check first.
		 */
		if (
				header_init &&
				context &&
				!(have_header & HTTP_HEADER_CONTENT_LENGTH) &&
				php_stream_context_get_option(context, "http", "content", &tmpzval) == SUCCESS &&
				Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0
		) {
			scratch_len = slprintf(scratch, scratch_len, "Content-Length: %d\r\n", Z_STRLEN_PP(tmpzval));
			php_stream_write(stream, scratch, scratch_len);
			have_header |= HTTP_HEADER_CONTENT_LENGTH;
		}

		php_stream_write(stream, user_headers, strlen(user_headers));
		php_stream_write(stream, "\r\n", sizeof("\r\n")-1);
		efree(user_headers);
	}

	/* Request content, such as for POST requests */
	if (header_init && context &&
		php_stream_context_get_option(context, "http", "content", &tmpzval) == SUCCESS &&
		Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) {
		if (!(have_header & HTTP_HEADER_CONTENT_LENGTH)) {
			scratch_len = slprintf(scratch, scratch_len, "Content-Length: %d\r\n", Z_STRLEN_PP(tmpzval));
			php_stream_write(stream, scratch, scratch_len);
		}
		if (!(have_header & HTTP_HEADER_TYPE)) {
			php_stream_write(stream, "Content-Type: application/x-www-form-urlencoded\r\n",
				sizeof("Content-Type: application/x-www-form-urlencoded\r\n") - 1);
			php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Content-type not specified assuming application/x-www-form-urlencoded");
		}
		php_stream_write(stream, "\r\n", sizeof("\r\n")-1);
		php_stream_write(stream, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval));
	} else {
		php_stream_write(stream, "\r\n", sizeof("\r\n")-1);
	}

	location[0] = '\0';

	if (!EG(active_symbol_table)) {
		zend_rebuild_symbol_table(TSRMLS_C);
	}

	if (header_init) {
		zval *ztmp;
		MAKE_STD_ZVAL(ztmp);
		array_init(ztmp);
		ZEND_SET_SYMBOL(EG(active_symbol_table), "http_response_header", ztmp);
	}

	{
		zval **rh;
		zend_hash_find(EG(active_symbol_table), "http_response_header", sizeof("http_response_header"), (void **) &rh);
		response_header = *rh;
	}

	if (!php_stream_eof(stream)) {
		size_t tmp_line_len;
		/* get response header */

		if (php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len) != NULL) {
			zval *http_response;
			int response_code;

			if (tmp_line_len > 9) {
				response_code = atoi(tmp_line + 9);
			} else {
				response_code = 0;
			}
			if (context && SUCCESS==php_stream_context_get_option(context, "http", "ignore_errors", &tmpzval)) {
				ignore_errors = zend_is_true(*tmpzval);
			}
			/* when we request only the header, don't fail even on error codes */
			if ((options & STREAM_ONLY_GET_HEADERS) || ignore_errors) {
				reqok = 1;
			}
			/* all status codes in the 2xx range are defined by the specification as successful;
			 * all status codes in the 3xx range are for redirection, and so also should never
			 * fail */
			if (response_code >= 200 && response_code < 400) {
				reqok = 1;
			} else {
				switch(response_code) {
					case 403:
						php_stream_notify_error(context, PHP_STREAM_NOTIFY_AUTH_RESULT,
								tmp_line, response_code);
						break;
					default:
						/* safety net in the event tmp_line == NULL */
						if (!tmp_line_len) {
							tmp_line[0] = '\0';
						}
						php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE,
								tmp_line, response_code);
				}
			}
			if (tmp_line[tmp_line_len - 1] == '\n') {
				--tmp_line_len;
				if (tmp_line[tmp_line_len - 1] == '\r') {
					--tmp_line_len;
				}
			}
			MAKE_STD_ZVAL(http_response);
			ZVAL_STRINGL(http_response, tmp_line, tmp_line_len, 1);
			zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_response, sizeof(zval *), NULL);
		}
	} else {
		php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP request failed, unexpected end of socket!");
		goto out;
	}
	
	/* read past HTTP headers */
	
	http_header_line = emalloc(HTTP_HEADER_BLOCK_SIZE);

	while (!body && !php_stream_eof(stream)) {
		size_t http_header_line_length;
		if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) && *http_header_line != '\n' && *http_header_line != '\r') {
			char *e = http_header_line + http_header_line_length - 1;
			if (*e != '\n') {
				do { /* partial header */
					if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) == NULL) {
						php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Failed to read HTTP headers");
						goto out;
					}
					e = http_header_line + http_header_line_length - 1;
				} while (*e != '\n');
				continue;
			}
			while (*e == '\n' || *e == '\r') {
				e--;
			}
			http_header_line_length = e - http_header_line + 1;
			http_header_line[http_header_line_length] = '\0';

			if (!strncasecmp(http_header_line, "Location: ", 10)) {
				if (context && php_stream_context_get_option(context, "http", "follow_location", &tmpzval) == SUCCESS) {
					SEPARATE_ZVAL(tmpzval);
					convert_to_long_ex(tmpzval);
					follow_location = Z_LVAL_PP(tmpzval);
				}
				strlcpy(location, http_header_line + 10, sizeof(location));
			} else if (!strncasecmp(http_header_line, "Content-Type: ", 14)) {
				php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_line + 14, 0);
			} else if (!strncasecmp(http_header_line, "Content-Length: ", 16)) {
				file_size = atoi(http_header_line + 16);
				php_stream_notify_file_size(context, file_size, http_header_line, 0);
			} else if (!strncasecmp(http_header_line, "Transfer-Encoding: chunked", sizeof("Transfer-Encoding: chunked"))) {

				/* create filter to decode response body */
				if (!(options & STREAM_ONLY_GET_HEADERS)) {
					long decode = 1;

					if (context && php_stream_context_get_option(context, "http", "auto_decode", &tmpzval) == SUCCESS) {
						SEPARATE_ZVAL(tmpzval);
						convert_to_boolean(*tmpzval);
						decode = Z_LVAL_PP(tmpzval);
					}
					if (decode) {
						transfer_encoding = php_stream_filter_create("dechunk", NULL, php_stream_is_persistent(stream) TSRMLS_CC);
						if (transfer_encoding) {
							/* don't store transfer-encodeing header */
							continue;
						}
					}
				}
			}

			if (http_header_line[0] == '\0') {
				body = 1;
			} else {
				zval *http_header;

				MAKE_STD_ZVAL(http_header);

				ZVAL_STRINGL(http_header, http_header_line, http_header_line_length, 1);
				
				zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_header, sizeof(zval *), NULL);
			}
		} else {
			break;
		}
	}

	if (!reqok || (location[0] != '\0' && follow_location)) {
		if (!follow_location || (((options & STREAM_ONLY_GET_HEADERS) || ignore_errors) && redirect_max <= 1)) {
			goto out;
		}

		if (location[0] != '\0')
			php_stream_notify_info(context, PHP_STREAM_NOTIFY_REDIRECTED, location, 0);

		php_stream_close(stream);
		stream = NULL;

		if (location[0] != '\0') {

			char new_path[HTTP_HEADER_BLOCK_SIZE];
			char loc_path[HTTP_HEADER_BLOCK_SIZE];

			*new_path='\0';
			if (strlen(location)<8 || (strncasecmp(location, "http://", sizeof("http://")-1) && 
							strncasecmp(location, "https://", sizeof("https://")-1) && 
							strncasecmp(location, "ftp://", sizeof("ftp://")-1) && 
							strncasecmp(location, "ftps://", sizeof("ftps://")-1))) 
			{
				if (*location != '/') {
					if (*(location+1) != '\0' && resource->path) {
						char *s = strrchr(resource->path, '/');
						if (!s) {
							s = resource->path;
							if (!s[0]) {
								efree(s);
								s = resource->path = estrdup("/");
							} else {
								*s = '/';
							}
						}
						s[1] = '\0'; 
						if (resource->path && *(resource->path) == '/' && *(resource->path + 1) == '\0') {
							snprintf(loc_path, sizeof(loc_path) - 1, "%s%s", resource->path, location);
						} else {
							snprintf(loc_path, sizeof(loc_path) - 1, "%s/%s", resource->path, location);
						}
					} else {
						snprintf(loc_path, sizeof(loc_path) - 1, "/%s", location);
					}
				} else {
					strlcpy(loc_path, location, sizeof(loc_path));
				}
				if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) {
					snprintf(new_path, sizeof(new_path) - 1, "%s://%s:%d%s", resource->scheme, resource->host, resource->port, loc_path);
				} else {
					snprintf(new_path, sizeof(new_path) - 1, "%s://%s%s", resource->scheme, resource->host, loc_path);
				}
			} else {
				strlcpy(new_path, location, sizeof(new_path));
			}

			php_url_free(resource);
			/* check for invalid redirection URLs */
			if ((resource = php_url_parse(new_path)) == NULL) {
				php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Invalid redirect URL! %s", new_path);
				goto out;
			}

#define CHECK_FOR_CNTRL_CHARS(val) { \
	if (val) { \
		unsigned char *s, *e; \
		int l; \
		l = php_url_decode(val, strlen(val)); \
		s = (unsigned char*)val; e = s + l; \
		while (s < e) { \
			if (iscntrl(*s)) { \
				php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Invalid redirect URL! %s", new_path); \
				goto out; \
			} \
			s++; \
		} \
	} \
}
			/* check for control characters in login, password & path */
			if (strncasecmp(new_path, "http://", sizeof("http://") - 1) || strncasecmp(new_path, "https://", sizeof("https://") - 1)) {
				CHECK_FOR_CNTRL_CHARS(resource->user)
				CHECK_FOR_CNTRL_CHARS(resource->pass)
				CHECK_FOR_CNTRL_CHARS(resource->path)
			}
			stream = php_stream_url_wrap_http_ex(wrapper, new_path, mode, options, opened_path, context, --redirect_max, HTTP_WRAPPER_REDIRECTED STREAMS_CC TSRMLS_CC);
		} else {
Пример #19
0
/*********************************************************************
// Name:  TSendMail
// Input:   1) host:    Name of the mail host where the SMTP server resides
//                      max accepted length of name = 256
//          2) appname: Name of the application to use in the X-mailer
//                      field of the message. if NULL is given the application
//                      name is used as given by the GetCommandLine() function
//                      max accespted length of name = 100
// Output:  1) error:   Returns the error code if something went wrong or
//                      SUCCESS otherwise.
//
//  See SendText() for additional args!
//********************************************************************/
PHPAPI int TSendMail(char *host, int *error, char **error_message,
			  char *headers, char *Subject, char *mailTo, char *data,
			  char *mailCc, char *mailBcc, char *mailRPath)
{
	int ret;
	char *RPath = NULL;
	zend_string *headers_lc = NULL; /* headers_lc is only created if we've a header at all */
	char *pos1 = NULL, *pos2 = NULL;

#ifndef NETWARE
	WinsockStarted = FALSE;
#endif

	if (host == NULL) {
		*error = BAD_MAIL_HOST;
		return FAILURE;
	} else if (strlen(host) >= HOST_NAME_LEN) {
		*error = BAD_MAIL_HOST;
		return FAILURE;
	} else {
		strcpy(MailHost, host);
	}

	if (headers) {
		char *pos = NULL;
		size_t i;
		zend_string *headers_trim;

		/* Use PCRE to trim the header into the right format */
		if (NULL == (headers_trim = php_win32_mail_trim_header(headers))) {
			*error = W32_SM_PCRE_ERROR;
			return FAILURE;
		}

		/* Create a lowercased header for all the searches so we're finally case
		 * insensitive when searching for a pattern. */
		if (NULL == (headers_lc = zend_string_copy(headers_trim))) {
			*error = OUT_OF_MEMORY;
			return FAILURE;
		}
		for (i = 0; i < headers_lc->len; i++) {
			headers_lc->val[i] = tolower(headers_lc->val[i]);
		}
	}
 
	/* Fall back to sendmail_from php.ini setting */
	if (mailRPath && *mailRPath) {
		RPath = estrdup(mailRPath);
	} else if (INI_STR("sendmail_from")) {
		RPath = estrdup(INI_STR("sendmail_from"));
	} else if (	headers_lc &&
				(pos1 = strstr(headers_lc->val, "from:")) &&
				((pos1 == headers_lc->val) || (*(pos1-1) == '\n'))
	) {
		/* Real offset is memaddress from the original headers + difference of
		 * string found in the lowercase headrs + 5 characters to jump over   
		 * the from: */
		pos1 = headers + (pos1 - headers_lc->val) + 5;
		if (NULL == (pos2 = strstr(pos1, "\r\n"))) {
			RPath = estrndup(pos1, strlen(pos1));
		} else {
			RPath = estrndup(pos1, pos2 - pos1);
		}
	} else {
		if (headers_lc) {
			zend_string_free(headers_lc);
		}
		*error = W32_SM_SENDMAIL_FROM_NOT_SET;
		return FAILURE;
	}

	/* attempt to connect with mail host */
	*error = MailConnect();
	if (*error != 0) {
		if (RPath) {
			efree(RPath);
		}
		if (headers) {
			efree(headers);
			efree(headers_lc);
		}
		/* 128 is safe here, the specifier in snprintf isn't longer than that */
		if (NULL == (*error_message = ecalloc(1, HOST_NAME_LEN + 128))) {
			return FAILURE;
		}
		snprintf(*error_message, HOST_NAME_LEN + 128,
			"Failed to connect to mailserver at \"%s\" port %d, verify your \"SMTP\" "
			"and \"smtp_port\" setting in php.ini or use ini_set()",
			MailHost, !INI_INT("smtp_port") ? 25 : INI_INT("smtp_port"));
		return FAILURE;
	} else {
		ret = SendText(RPath, Subject, mailTo, mailCc, mailBcc, data, headers, headers_lc->val, error_message);
		TSMClose();
		if (RPath) {
			efree(RPath);
		}
		if (headers) {
			efree(headers);
			efree(headers_lc);
		}
		if (ret != SUCCESS) {
			*error = ret;
			return FAILURE;
		}
		return SUCCESS;
	}
}
Пример #20
0
/** @todo Supspects to glib replacements, all path related stuff. */
tree_cell *
nasl_pread (lex_ctxt * lexic)
{
  tree_cell *retc = NULL, *a;
  anon_nasl_var *v;
  nasl_array *av;
  int i, j, n, sz, sz2, cd, nice;
  char **args = NULL, *cmd, *str, *str2, buf[8192];
  FILE *fp;
  char cwd[MAXPATHLEN], newdir[MAXPATHLEN];

  if (pid != 0)
    {
      nasl_perror (lexic, "nasl_pread is not reentrant!\n");
      return NULL;
    }

  a = get_variable_by_name (lexic, "argv");
  cmd = get_str_local_var_by_name (lexic, "cmd");
  if (cmd == NULL || a == NULL || (v = a->x.ref_val) == NULL)
    {
      nasl_perror (lexic, "pread() usage: cmd:..., argv:...\n");
      return NULL;
    }

  nice = get_int_local_var_by_name (lexic, "nice", 0);

  if (v->var_type == VAR2_ARRAY)
    av = &v->v.v_arr;
  else
    {
      nasl_perror (lexic, "pread: argv element must be an array (0x%x)\n",
                   v->var_type);
      return NULL;
    }

  cd = get_int_local_var_by_name (lexic, "cd", 0);

  cwd[0] = '\0';
  if (cd)
    {
      char *p;

      if (cmd[0] == '/')
        {
          strncpy (newdir, cmd, sizeof (newdir) - 1);   /* Flawfinder: ignore
                                                           (\0-termination taken
                                                           care of) */
          p = strrchr (newdir, '/');
          if (p != newdir)
            *p = '\0';
        }
      else
        {
          p = find_in_path (cmd, 0);
          if (p != NULL)
            strncpy (newdir, p, sizeof (newdir) - 1);   /* Flawfinder: ignore
                                                           (\0-termination taken
                                                           care of) */
          else
            {
              nasl_perror (lexic, "pread: '%s' not found in $PATH\n", cmd);
              return NULL;
            }

        }
      newdir[sizeof (newdir) - 1] = '\0';

      if (getcwd (cwd, sizeof (cwd)) == NULL)
        {
          nasl_perror (lexic, "pread(): getcwd: %s\n", strerror (errno));
          *cwd = '\0';
        }

      if (chdir (newdir) < 0)
        {
          nasl_perror (lexic, "pread: could not chdir to %s\n", newdir);
          return NULL;
        }
      if (cmd[0] != '/' && strlen (newdir) + strlen (cmd) + 1 < sizeof (newdir))
        {
          strcat (newdir, "/"); /* Flawfinder: ignore (if-command above checks
                                   for size) */
          strcat (newdir, cmd); /* Flawfinder: ignore (if-command above checks
                                   for size) */
          cmd = newdir;
        }
    }

  if (av->hash_elt != NULL)
    nasl_perror (lexic, "pread: named elements in 'cmd' are ignored!\n");
  n = av->max_idx;
  args = emalloc (sizeof (char **) * (n + 2));  /* Last arg is NULL */
  for (j = 0, i = 0; i < n; i++)
    {
      str = (char *) var2str (av->num_elt[i]);
      if (str != NULL)
        args[j++] = estrdup (str);
    }
  args[j++] = NULL;

  old_sig_t = signal (SIGTERM, sig_h);
  old_sig_i = signal (SIGINT, sig_h);
  old_sig_c = signal (SIGCHLD, sig_c);

  fp = openvas_popen4 ((const char *) cmd, args, &pid, nice);

  for (i = 0; i < n; i++)
    efree (&args[i]);
  efree (&args);

  if (fp != NULL)
    {
      sz = 0;
      str = emalloc (1);

      errno = 0;
      while ((n = fread (buf, 1, sizeof (buf), fp)) > 0 || errno == EINTR)      /* && kill(pid, 0) >= 0) */
        {
          if (errno == EINTR)
            {
              errno = 0;
              continue;
            }
          sz2 = sz + n;
          str2 = erealloc (str, sz2);
          if (str2 == NULL)
            {
              nasl_perror (lexic, "nasl_pread: erealloc failed\n");
              break;
            }
          str = str2;
          memcpy (str + sz, buf, n);
          sz = sz2;
        }
      if (ferror (fp) && errno != EINTR)
        nasl_perror (lexic, "nasl_pread: fread(): %s\n", strerror (errno));

      (void) openvas_pclose (fp, pid);
      pid = 0;

      if (*cwd != '\0')
        if (chdir (cwd) < 0)
          nasl_perror (lexic, "pread(): chdir(%s): %s\n", cwd,
                       strerror (errno));

      retc = alloc_typed_cell (CONST_DATA);
      retc->x.str_val = str;
      retc->size = sz;
    }

  signal (SIGINT, old_sig_i);
  signal (SIGTERM, old_sig_t);
  signal (SIGCHLD, old_sig_c);

  return retc;
}
Пример #21
0
/*********************************************************************
// Name:  PostHeader
// Input:       1) return path
//              2) Subject
//              3) destination address
//              4) headers
// Output:      Error code or Success
// Description:
// Author/Date:  jcar 20/9/96
// History:
//********************************************************************/
static int PostHeader(char *RPath, char *Subject, char *mailTo, char *xheaders)
{
	/* Print message header according to RFC 822 */
	/* Return-path, Received, Date, From, Subject, Sender, To, cc */

	int res;
	char *header_buffer;
	char *headers_lc = NULL;
	size_t i;

	if (xheaders) {
		if (NULL == (headers_lc = estrdup(xheaders))) {
			return OUT_OF_MEMORY;
		}
		for (i = 0; i < strlen(headers_lc); i++) {
			headers_lc[i] = tolower(headers_lc[i]);
		}
	}

	header_buffer = ecalloc(1, MAIL_BUFFER_SIZE);

	if (!xheaders || !strstr(headers_lc, "date:")) {
		time_t tNow = time(NULL);
		zend_string *dt = php_format_date("r", 1, tNow, 1);

		snprintf(header_buffer, MAIL_BUFFER_SIZE, "Date: %s\r\n", dt->val);
		zend_string_free(dt);
	}

	if (!headers_lc || !strstr(headers_lc, "from:")) {
		if (!addToHeader(&header_buffer, "From: %s\r\n", RPath)) {
			goto PostHeader_outofmem;
		}
	}
	if (!addToHeader(&header_buffer, "Subject: %s\r\n", Subject)) {
		goto PostHeader_outofmem;
	}

	/* Only add the To: field from the $to parameter if isn't in the custom headers */
	if ((headers_lc && (!strstr(headers_lc, "\r\nto:") && (strncmp(headers_lc, "to:", 3) != 0))) || !headers_lc) {
		if (!addToHeader(&header_buffer, "To: %s\r\n", mailTo)) {
			goto PostHeader_outofmem;
		}
	}
	if (xheaders) {
		if (!addToHeader(&header_buffer, "%s\r\n", xheaders)) {
			goto PostHeader_outofmem;
		}
	}

	if (headers_lc) {
		efree(headers_lc);
	}
	if ((res = Post(header_buffer)) != SUCCESS) {
		efree(header_buffer);
		return (res);
	}
	efree(header_buffer);

	if ((res = Post("\r\n")) != SUCCESS) {
		return (res);
	}

	return (SUCCESS);

PostHeader_outofmem:
	if (headers_lc) {
		efree(headers_lc);
	}
	return OUT_OF_MEMORY;
}
Пример #22
0
Файл: dl.c Проект: 899/php-src
/* {{{ php_load_extension
 */
PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC)
{
	void *handle;
	char *libpath;
	zend_module_entry *module_entry;
	zend_module_entry *(*get_module)(void);
	int error_type;
	char *extension_dir;

	if (type == MODULE_PERSISTENT) {
		extension_dir = INI_STR("extension_dir");
	} else {
		extension_dir = PG(extension_dir);
	}

	if (type == MODULE_TEMPORARY) {
		error_type = E_WARNING;
	} else {
		error_type = E_CORE_WARNING;
	}

	/* Check if passed filename contains directory separators */
	if (strchr(filename, '/') != NULL || strchr(filename, DEFAULT_SLASH) != NULL) {
		/* Passing modules with full path is not supported for dynamically loaded extensions */
		if (type == MODULE_TEMPORARY) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Temporary module name should contain only filename");
			return FAILURE;
		}
		libpath = estrdup(filename);
	} else if (extension_dir && extension_dir[0]) {
		int extension_dir_len = strlen(extension_dir);

		if (IS_SLASH(extension_dir[extension_dir_len-1])) {
			spprintf(&libpath, 0, "%s%s", extension_dir, filename); /* SAFE */
		} else {
			spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, filename); /* SAFE */
		}
	} else {
		return FAILURE; /* Not full path given or extension_dir is not set */
	}

	/* load dynamic symbol */
	handle = DL_LOAD(libpath);
	if (!handle) {
#if PHP_WIN32
		char *err = GET_DL_ERROR();
		if (err && (*err != "")) {
			php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, err);
			LocalFree(err);
		} else {
			php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, "Unknown reason");
		}
#else
		php_error_docref(NULL TSRMLS_CC, error_type, "Unable to load dynamic library '%s' - %s", libpath, GET_DL_ERROR());
		GET_DL_ERROR(); /* free the buffer storing the error */
#endif
		efree(libpath);
		return FAILURE;
	}
	efree(libpath);

	get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "get_module");

	/* Some OS prepend _ to symbol names while their dynamic linker
	 * does not do that automatically. Thus we check manually for
	 * _get_module. */

	if (!get_module) {
		get_module = (zend_module_entry *(*)(void)) DL_FETCH_SYMBOL(handle, "_get_module");
	}

	if (!get_module) {
		if (DL_FETCH_SYMBOL(handle, "zend_extension_entry") || DL_FETCH_SYMBOL(handle, "_zend_extension_entry")) {
			DL_UNLOAD(handle);
			php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (appears to be a Zend Extension, try loading using zend_extension=%s from php.ini)", filename);
			return FAILURE;
		}
		DL_UNLOAD(handle);
		php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (maybe not a PHP library) '%s'", filename);
		return FAILURE;
	}
	module_entry = get_module();
	if (module_entry->zend_api != ZEND_MODULE_API_NO) {
		/* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
			struct pre_4_1_0_module_entry {
				char *name;
				zend_function_entry *functions;
				int (*module_startup_func)(INIT_FUNC_ARGS);
				int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
				int (*request_startup_func)(INIT_FUNC_ARGS);
				int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
				void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
				int (*global_startup_func)(void);
				int (*global_shutdown_func)(void);
				int globals_id;
				int module_started;
				unsigned char type;
				void *handle;
				int module_number;
				unsigned char zend_debug;
				unsigned char zts;
				unsigned int zend_api;
			};

			const char *name;
			int zend_api;

			if ((((struct pre_4_1_0_module_entry *)module_entry)->zend_api > 20000000) &&
				(((struct pre_4_1_0_module_entry *)module_entry)->zend_api < 20010901)
			) {
				name		= ((struct pre_4_1_0_module_entry *)module_entry)->name;
				zend_api	= ((struct pre_4_1_0_module_entry *)module_entry)->zend_api;
			} else {
				name		= module_entry->name;
				zend_api	= module_entry->zend_api;
			}

			php_error_docref(NULL TSRMLS_CC, error_type,
					"%s: Unable to initialize module\n"
					"Module compiled with module API=%d\n"
					"PHP    compiled with module API=%d\n"
					"These options need to match\n",
					name, zend_api, ZEND_MODULE_API_NO);
			DL_UNLOAD(handle);
			return FAILURE;
	}
	if(strcmp(module_entry->build_id, ZEND_MODULE_BUILD_ID)) {
		php_error_docref(NULL TSRMLS_CC, error_type,
				"%s: Unable to initialize module\n"
				"Module compiled with build ID=%s\n"
				"PHP    compiled with build ID=%s\n"
				"These options need to match\n",
				module_entry->name, module_entry->build_id, ZEND_MODULE_BUILD_ID);
		DL_UNLOAD(handle);
		return FAILURE;
	}
	module_entry->type = type;
	module_entry->module_number = zend_next_free_module();
	module_entry->handle = handle;

	if ((module_entry = zend_register_module_ex(module_entry TSRMLS_CC)) == NULL) {
		DL_UNLOAD(handle);
		return FAILURE;
	}

	if ((type == MODULE_TEMPORARY || start_now) && zend_startup_module_ex(module_entry TSRMLS_CC) == FAILURE) {
		DL_UNLOAD(handle);
		return FAILURE;
	}

	if ((type == MODULE_TEMPORARY || start_now) && module_entry->request_startup_func) {
		if (module_entry->request_startup_func(type, module_entry->module_number TSRMLS_CC) == FAILURE) {
			php_error_docref(NULL TSRMLS_CC, error_type, "Unable to initialize module '%s'", module_entry->name);
			DL_UNLOAD(handle);
			return FAILURE;
		}
	}
	return SUCCESS;
}
Пример #23
0
PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, time_t expires, char *path, int path_len, char *domain, int domain_len, int secure, int url_encode, int httponly TSRMLS_DC)
{
	char *cookie, *encoded_value = NULL;
	int len=sizeof("Set-Cookie: ");
	char *dt;
	sapi_header_line ctr = {0};
	int result;
	
	if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) {   /* man isspace for \013 and \014 */
		zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" );
		return FAILURE;
	}

	if (!url_encode && value && strpbrk(value, ",; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */
		zend_error( E_WARNING, "Cookie values cannot contain any of the following ',; \\t\\r\\n\\013\\014'" );
		return FAILURE;
	}

	len += name_len;
	if (value && url_encode) {
		int encoded_value_len;

		encoded_value = php_url_encode(value, value_len, &encoded_value_len);
		len += encoded_value_len;
	} else if ( value ) {
		encoded_value = estrdup(value);
		len += value_len;
	}
	if (path) {
		len += path_len;
	}
	if (domain) {
		len += domain_len;
	}

	cookie = emalloc(len + 100);

	if (value && value_len == 0) {
		/* 
		 * MSIE doesn't delete a cookie when you set it to a null value
		 * so in order to force cookies to be deleted, even on MSIE, we
		 * pick an expiry date in the past
		 */
		dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, 1, 0 TSRMLS_CC);
		snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s", name, dt);
		efree(dt);
	} else {
		snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value : "");
		if (expires > 0) {
			const char *p;
			strlcat(cookie, "; expires=", len + 100);
			dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC);
			/* check to make sure that the year does not exceed 4 digits in length */
			p = zend_memrchr(dt, '-', strlen(dt));
			if (!p || *(p + 5) != ' ') {
				efree(dt);
				efree(cookie);
				efree(encoded_value);
				zend_error(E_WARNING, "Expiry date cannot have a year greater than 9999");
				return FAILURE;
			}
			strlcat(cookie, dt, len + 100);
			efree(dt);
		}
	}

	if (encoded_value) {
		efree(encoded_value);
	}

	if (path && path_len > 0) {
		strlcat(cookie, "; path=", len + 100);
		strlcat(cookie, path, len + 100);
	}
	if (domain && domain_len > 0) {
		strlcat(cookie, "; domain=", len + 100);
		strlcat(cookie, domain, len + 100);
	}
	if (secure) {
		strlcat(cookie, "; secure", len + 100);
	}
	if (httponly) {
		strlcat(cookie, "; httponly", len + 100);
	}

	ctr.line = cookie;
	ctr.line_len = strlen(cookie);

	result = sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);
	efree(cookie);
	return result;
}
Пример #24
0
FUZZY_WORD *soundex( FUZZY_OBJECT *fi, const char *inword)
   {
        FUZZY_WORD *fw = create_fuzzy_word( inword, 1 ); /* create place to store stemmed word */
        char word[MAXWORDLEN+1];
	/* Misc Stuff  */
	char u, l ;
	int i, j, n;
	/* Resultant Sound Code  */
	char soundCode[5] = "0000\0";
	/* Group Number Lookup Table  */
	static char soundTable[26] =
	{0,						/* A  */
	 '1',					/* B  */
	 '2',					/* C  */
	 '3',					/* D  */
	 0,						/* E  */
	 '1',					/* F  */
	 '2',					/* G  */
	 0,						/* H  */
	 0,						/* I  */
	 '2',					/* J  */
	 '2',					/* K  */
	 '4',					/* L  */
	 '5',					/* M  */
	 '5',					/* N  */
	 0,						/* O  */
	 '1',					/* P  */
	 '2',					/* Q  */
	 '6',					/* R  */
	 '2',					/* S  */
	 '3',					/* T  */
	 0,						/* U  */
	 '1',					/* V  */
	 0,						/* W  */
	 '2',					/* X  */
	 0,						/* Y  */
	 '2'};					/* Z  */

    /* Make sure the word is not too large from the start. */
    if ( strlen( inword ) >= MAXWORDLEN )
    {
        fw->error =  STEM_WORD_TOO_BIG;
        return fw;
    }


    /* make working copy */
    strcpy( word, inword );

  

#ifdef _DEBUG
	/* Debug to console  */
	printf("# %15s: %s ", "soundex.c", word);
#endif

	/* Make sure it actually starts with a letter  */
	if(!isalpha((int)((unsigned char)word[0]))) 
        {
            fw->error = STEM_NOT_ALPHA;
            return fw;
        }

#ifdef _DEBUG
	/* Debug to console  */
	printf("isalpha, ");
#endif
	
	/* Get string length and make sure its at least 3 characters  */
	if((n = (int)strlen(word)) < 3) 
        {
            fw->error = STEM_TOO_SMALL;
            return fw;
        }
#ifdef _DEBUG
	/* Debug to console  */
	printf("=>3, ");
#endif

        /* If looks like a 4 digit soundex code we don't want to touch it. */

        /* Humm.  Just because it looks like a duck, doesn't mean it is one
         * The source is suppose to not be soundex, so this doesn't make a lot of sense.  - moseely */
#ifdef skip_section
        
        if((n = (int)strlen(word)) == 4){
                if( isdigit( (int)(unsigned char)word[1] ) 
                 && isdigit( (int)(unsigned char)word[2] ) 
                 && isdigit( (int)(unsigned char)word[3] ) )
                       return STEM_OK;  /* Hum, probably not right */
        }
#endif

	/* Convert chars to lower case and strip non-letter chars  */
	j = 0;
	for (i = 0; i < n; i++) {
		u = tolower((unsigned char)word[i]);
		if ((u > 96) && (u < 123)) {
			 word[j] = u;
			j++;
		}
	}

	/* terminate string  */
	 word[j] = 0;

	/* String length again  */
	n = strlen(word);

	soundCode[0] = word[0];

	/* remember first char  */
	l = soundTable[((word[0]) - 97)];

	j = 1;

	/* build soundex string  */
	for (i = 1; i < n && j < 4; i++) {
		u = soundTable[((word[i]) - 97)];

		if (u != l) {
			if (u != 0) {
				soundCode[(int) j++] = u;
			}
			l = u;
		}
	}


    fw->free_strings = 1; /* flag that we are creating a string */
    fw->string_list[0] = estrdup( soundCode );
    return fw;

}
Пример #25
0
SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
{
	char *boundary, *s = NULL, *boundary_end = NULL, *start_arr = NULL, *array_index = NULL;
	char *lbuf = NULL, *abuf = NULL;
	zend_string *temp_filename = NULL;
	int boundary_len = 0, cancel_upload = 0, is_arr_upload = 0, array_len = 0;
	int64_t total_bytes = 0, max_file_size = 0;
	int skip_upload = 0, anonindex = 0, is_anonymous;
	HashTable *uploaded_files = NULL;
	multipart_buffer *mbuff;
	zval *array_ptr = (zval *) arg;
	int fd = -1;
	zend_llist header;
	void *event_extra_data = NULL;
	unsigned int llen = 0;
	int upload_cnt = INI_INT("max_file_uploads");
	const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding();
	php_rfc1867_getword_t getword;
	php_rfc1867_getword_conf_t getword_conf;
	php_rfc1867_basename_t _basename;
	zend_long count = 0;

	if (php_rfc1867_encoding_translation() && internal_encoding) {
		getword = php_rfc1867_getword;
		getword_conf = php_rfc1867_getword_conf;
		_basename = php_rfc1867_basename;
	} else {
		getword = php_ap_getword;
		getword_conf = php_ap_getword_conf;
		_basename = php_ap_basename;
	}

	if (SG(post_max_size) > 0 && SG(request_info).content_length > SG(post_max_size)) {
		sapi_module.sapi_error(E_WARNING, "POST Content-Length of " ZEND_LONG_FMT " bytes exceeds the limit of " ZEND_LONG_FMT " bytes", SG(request_info).content_length, SG(post_max_size));
		return;
	}

	/* Get the boundary */
	boundary = strstr(content_type_dup, "boundary");
	if (!boundary) {
		int content_type_len = (int)strlen(content_type_dup);
		char *content_type_lcase = estrndup(content_type_dup, content_type_len);

		php_strtolower(content_type_lcase, content_type_len);
		boundary = strstr(content_type_lcase, "boundary");
		if (boundary) {
			boundary = content_type_dup + (boundary - content_type_lcase);
		}
		efree(content_type_lcase);
	}

	if (!boundary || !(boundary = strchr(boundary, '='))) {
		sapi_module.sapi_error(E_WARNING, "Missing boundary in multipart/form-data POST data");
		return;
	}

	boundary++;
	boundary_len = (int)strlen(boundary);

	if (boundary[0] == '"') {
		boundary++;
		boundary_end = strchr(boundary, '"');
		if (!boundary_end) {
			sapi_module.sapi_error(E_WARNING, "Invalid boundary in multipart/form-data POST data");
			return;
		}
	} else {
		/* search for the end of the boundary */
		boundary_end = strpbrk(boundary, ",;");
	}
	if (boundary_end) {
		boundary_end[0] = '\0';
		boundary_len = boundary_end-boundary;
	}

	/* Initialize the buffer */
	if (!(mbuff = multipart_buffer_new(boundary, boundary_len))) {
		sapi_module.sapi_error(E_WARNING, "Unable to initialize the input buffer");
		return;
	}

	/* Initialize $_FILES[] */
	zend_hash_init(&PG(rfc1867_protected_variables), 8, NULL, NULL, 0);

	ALLOC_HASHTABLE(uploaded_files);
	zend_hash_init(uploaded_files, 8, NULL, free_filename, 0);
	SG(rfc1867_uploaded_files) = uploaded_files;

	if (Z_TYPE(PG(http_globals)[TRACK_VARS_FILES]) != IS_ARRAY) {
		/* php_auto_globals_create_files() might have already done that */
		array_init(&PG(http_globals)[TRACK_VARS_FILES]);
	}

	zend_llist_init(&header, sizeof(mime_header_entry), (llist_dtor_func_t) php_free_hdr_entry, 0);

	if (php_rfc1867_callback != NULL) {
		multipart_event_start event_start;

		event_start.content_length = SG(request_info).content_length;
		if (php_rfc1867_callback(MULTIPART_EVENT_START, &event_start, &event_extra_data) == FAILURE) {
			goto fileupload_done;
		}
	}

	while (!multipart_buffer_eof(mbuff))
	{
		char buff[FILLUNIT];
		char *cd = NULL, *param = NULL, *filename = NULL, *tmp = NULL;
		size_t blen = 0, wlen = 0;
		zend_off_t offset;

		zend_llist_clean(&header);

		if (!multipart_buffer_headers(mbuff, &header)) {
			goto fileupload_done;
		}

		if ((cd = php_mime_get_hdr_value(header, "Content-Disposition"))) {
			char *pair = NULL;
			int end = 0;

			while (isspace(*cd)) {
				++cd;
			}

			while (*cd && (pair = getword(mbuff->input_encoding, &cd, ';')))
			{
				char *key = NULL, *word = pair;

				while (isspace(*cd)) {
					++cd;
				}

				if (strchr(pair, '=')) {
					key = getword(mbuff->input_encoding, &pair, '=');

					if (!strcasecmp(key, "name")) {
						if (param) {
							efree(param);
						}
						param = getword_conf(mbuff->input_encoding, pair);
						if (mbuff->input_encoding && internal_encoding) {
							unsigned char *new_param;
							size_t new_param_len;
							if ((size_t)-1 != zend_multibyte_encoding_converter(&new_param, &new_param_len, (unsigned char *)param, strlen(param), internal_encoding, mbuff->input_encoding)) {
								efree(param);
								param = (char *)new_param;
							}
						}
					} else if (!strcasecmp(key, "filename")) {
						if (filename) {
							efree(filename);
						}
						filename = getword_conf(mbuff->input_encoding, pair);
						if (mbuff->input_encoding && internal_encoding) {
							unsigned char *new_filename;
							size_t new_filename_len;
							if ((size_t)-1 != zend_multibyte_encoding_converter(&new_filename, &new_filename_len, (unsigned char *)filename, strlen(filename), internal_encoding, mbuff->input_encoding)) {
								efree(filename);
								filename = (char *)new_filename;
							}
						}
					}
				}
				if (key) {
					efree(key);
				}
				efree(word);
			}

			/* Normal form variable, safe to read all data into memory */
			if (!filename && param) {
				size_t value_len;
				char *value = multipart_buffer_read_body(mbuff, &value_len);
				size_t new_val_len; /* Dummy variable */

				if (!value) {
					value = estrdup("");
					value_len = 0;
				}

				if (mbuff->input_encoding && internal_encoding) {
					unsigned char *new_value;
					size_t new_value_len;
					if ((size_t)-1 != zend_multibyte_encoding_converter(&new_value, &new_value_len, (unsigned char *)value, value_len, internal_encoding, mbuff->input_encoding)) {
						efree(value);
						value = (char *)new_value;
						value_len = new_value_len;
					}
				}

				if (++count <= PG(max_input_vars) && sapi_module.input_filter(PARSE_POST, param, &value, value_len, &new_val_len)) {
					if (php_rfc1867_callback != NULL) {
						multipart_event_formdata event_formdata;
						size_t newlength = new_val_len;

						event_formdata.post_bytes_processed = SG(read_post_bytes);
						event_formdata.name = param;
						event_formdata.value = &value;
						event_formdata.length = new_val_len;
						event_formdata.newlength = &newlength;
						if (php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data) == FAILURE) {
							efree(param);
							efree(value);
							continue;
						}
						new_val_len = newlength;
					}
					safe_php_register_variable(param, value, new_val_len, array_ptr, 0);
				} else {
					if (count == PG(max_input_vars) + 1) {
						php_error_docref(NULL, E_WARNING, "Input variables exceeded " ZEND_LONG_FMT ". To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
					}

					if (php_rfc1867_callback != NULL) {
						multipart_event_formdata event_formdata;

						event_formdata.post_bytes_processed = SG(read_post_bytes);
						event_formdata.name = param;
						event_formdata.value = &value;
						event_formdata.length = value_len;
						event_formdata.newlength = NULL;
						php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data);
					}
				}

				if (!strcasecmp(param, "MAX_FILE_SIZE")) {
#ifdef HAVE_ATOLL
					max_file_size = atoll(value);
#else
					max_file_size = strtoll(value, NULL, 10);
#endif
				}

				efree(param);
				efree(value);
				continue;
			}

			/* If file_uploads=off, skip the file part */
			if (!PG(file_uploads)) {
				skip_upload = 1;
			} else if (upload_cnt <= 0) {
				skip_upload = 1;
				sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded");
			}

			/* Return with an error if the posted data is garbled */
			if (!param && !filename) {
				sapi_module.sapi_error(E_WARNING, "File Upload Mime headers garbled");
				goto fileupload_done;
			}

			if (!param) {
				is_anonymous = 1;
				param = emalloc(MAX_SIZE_ANONNAME);
				snprintf(param, MAX_SIZE_ANONNAME, "%u", anonindex++);
			} else {
				is_anonymous = 0;
			}

			/* New Rule: never repair potential malicious user input */
			if (!skip_upload) {
				long c = 0;
				tmp = param;

				while (*tmp) {
					if (*tmp == '[') {
						c++;
					} else if (*tmp == ']') {
						c--;
						if (tmp[1] && tmp[1] != '[') {
							skip_upload = 1;
							break;
						}
					}
					if (c < 0) {
						skip_upload = 1;
						break;
					}
					tmp++;
				}
				/* Brackets should always be closed */
				if(c != 0) {
					skip_upload = 1;
				}
			}

			total_bytes = cancel_upload = 0;
			temp_filename = NULL;
			fd = -1;

			if (!skip_upload && php_rfc1867_callback != NULL) {
				multipart_event_file_start event_file_start;

				event_file_start.post_bytes_processed = SG(read_post_bytes);
				event_file_start.name = param;
				event_file_start.filename = &filename;
				if (php_rfc1867_callback(MULTIPART_EVENT_FILE_START, &event_file_start, &event_extra_data) == FAILURE) {
					temp_filename = NULL;
					efree(param);
					efree(filename);
					continue;
				}
			}

			if (skip_upload) {
				efree(param);
				efree(filename);
				continue;
			}

			if (filename[0] == '\0') {
#if DEBUG_FILE_UPLOAD
				sapi_module.sapi_error(E_NOTICE, "No file uploaded");
#endif
				cancel_upload = UPLOAD_ERROR_D;
			}

			offset = 0;
			end = 0;

			if (!cancel_upload) {
				/* only bother to open temp file if we have data */
				blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end);
#if DEBUG_FILE_UPLOAD
				if (blen > 0) {
#else
				/* in non-debug mode we have no problem with 0-length files */
				{
#endif
					fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, 1);
					upload_cnt--;
					if (fd == -1) {
						sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file");
						cancel_upload = UPLOAD_ERROR_E;
					}
				}
			}

			while (!cancel_upload && (blen > 0))
			{
				if (php_rfc1867_callback != NULL) {
					multipart_event_file_data event_file_data;

					event_file_data.post_bytes_processed = SG(read_post_bytes);
					event_file_data.offset = offset;
					event_file_data.data = buff;
					event_file_data.length = blen;
					event_file_data.newlength = &blen;
					if (php_rfc1867_callback(MULTIPART_EVENT_FILE_DATA, &event_file_data, &event_extra_data) == FAILURE) {
						cancel_upload = UPLOAD_ERROR_X;
						continue;
					}
				}

				if (PG(upload_max_filesize) > 0 && (zend_long)(total_bytes+blen) > PG(upload_max_filesize)) {
#if DEBUG_FILE_UPLOAD
					sapi_module.sapi_error(E_NOTICE, "upload_max_filesize of " ZEND_LONG_FMT " bytes exceeded - file [%s=%s] not saved", PG(upload_max_filesize), param, filename);
#endif
					cancel_upload = UPLOAD_ERROR_A;
				} else if (max_file_size && ((zend_long)(total_bytes+blen) > max_file_size)) {
#if DEBUG_FILE_UPLOAD
					sapi_module.sapi_error(E_NOTICE, "MAX_FILE_SIZE of %" PRId64 " bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
#endif
					cancel_upload = UPLOAD_ERROR_B;
				} else if (blen > 0) {
#ifdef PHP_WIN32
					wlen = write(fd, buff, (unsigned int)blen);
#else
					wlen = write(fd, buff, blen);
#endif

					if (wlen == -1) {
						/* write failed */
#if DEBUG_FILE_UPLOAD
						sapi_module.sapi_error(E_NOTICE, "write() failed - %s", strerror(errno));
#endif
						cancel_upload = UPLOAD_ERROR_F;
					} else if (wlen < blen) {
#if DEBUG_FILE_UPLOAD
						sapi_module.sapi_error(E_NOTICE, "Only %zd bytes were written, expected to write %zd", wlen, blen);
#endif
						cancel_upload = UPLOAD_ERROR_F;
					} else {
						total_bytes += wlen;
					}
					offset += wlen;
				}

				/* read data for next iteration */
				blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end);
			}

			if (fd != -1) { /* may not be initialized if file could not be created */
				close(fd);
			}

			if (!cancel_upload && !end) {
#if DEBUG_FILE_UPLOAD
				sapi_module.sapi_error(E_NOTICE, "Missing mime boundary at the end of the data for file %s", filename[0] != '\0' ? filename : "");
#endif
				cancel_upload = UPLOAD_ERROR_C;
			}
#if DEBUG_FILE_UPLOAD
			if (filename[0] != '\0' && total_bytes == 0 && !cancel_upload) {
				sapi_module.sapi_error(E_WARNING, "Uploaded file size 0 - file [%s=%s] not saved", param, filename);
				cancel_upload = 5;
			}
#endif
			if (php_rfc1867_callback != NULL) {
				multipart_event_file_end event_file_end;

				event_file_end.post_bytes_processed = SG(read_post_bytes);
				event_file_end.temp_filename = ZSTR_VAL(temp_filename);
				event_file_end.cancel_upload = cancel_upload;
				if (php_rfc1867_callback(MULTIPART_EVENT_FILE_END, &event_file_end, &event_extra_data) == FAILURE) {
					cancel_upload = UPLOAD_ERROR_X;
				}
			}

			if (cancel_upload) {
				if (temp_filename) {
					if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
						unlink(ZSTR_VAL(temp_filename));
					}
					zend_string_release(temp_filename);
				}
				temp_filename = NULL;
			} else {
				zend_hash_add_ptr(SG(rfc1867_uploaded_files), temp_filename, temp_filename);
			}

			/* is_arr_upload is true when name of file upload field
			 * ends in [.*]
			 * start_arr is set to point to 1st [ */
			is_arr_upload =	(start_arr = strchr(param,'[')) && (param[strlen(param)-1] == ']');

			if (is_arr_upload) {
				array_len = (int)strlen(start_arr);
				if (array_index) {
					efree(array_index);
				}
				array_index = estrndup(start_arr + 1, array_len - 2);
			}

			/* Add $foo_name */
			if (llen < strlen(param) + MAX_SIZE_OF_INDEX + 1) {
				llen = (int)strlen(param);
				lbuf = (char *) safe_erealloc(lbuf, llen, 1, MAX_SIZE_OF_INDEX + 1);
				llen += MAX_SIZE_OF_INDEX + 1;
			}

			if (is_arr_upload) {
				if (abuf) efree(abuf);
				abuf = estrndup(param, strlen(param)-array_len);
				snprintf(lbuf, llen, "%s_name[%s]", abuf, array_index);
			} else {
				snprintf(lbuf, llen, "%s_name", param);
			}

			/* The \ check should technically be needed for win32 systems only where
			 * it is a valid path separator. However, IE in all it's wisdom always sends
			 * the full path of the file on the user's filesystem, which means that unless
			 * the user does basename() they get a bogus file name. Until IE's user base drops
			 * to nill or problem is fixed this code must remain enabled for all systems. */
			s = _basename(internal_encoding, filename);
			if (!s) {
				s = filename;
			}

			if (!is_anonymous) {
				safe_php_register_variable(lbuf, s, strlen(s), NULL, 0);
			}

			/* Add $foo[name] */
			if (is_arr_upload) {
				snprintf(lbuf, llen, "%s[name][%s]", abuf, array_index);
			} else {
				snprintf(lbuf, llen, "%s[name]", param);
			}
			register_http_post_files_variable(lbuf, s, &PG(http_globals)[TRACK_VARS_FILES], 0);
			efree(filename);
			s = NULL;

			/* Possible Content-Type: */
			if (cancel_upload || !(cd = php_mime_get_hdr_value(header, "Content-Type"))) {
				cd = "";
			} else {
				/* fix for Opera 6.01 */
				s = strchr(cd, ';');
				if (s != NULL) {
					*s = '\0';
				}
			}

			/* Add $foo_type */
			if (is_arr_upload) {
				snprintf(lbuf, llen, "%s_type[%s]", abuf, array_index);
			} else {
				snprintf(lbuf, llen, "%s_type", param);
			}
			if (!is_anonymous) {
				safe_php_register_variable(lbuf, cd, strlen(cd), NULL, 0);
			}

			/* Add $foo[type] */
			if (is_arr_upload) {
				snprintf(lbuf, llen, "%s[type][%s]", abuf, array_index);
			} else {
				snprintf(lbuf, llen, "%s[type]", param);
			}
			register_http_post_files_variable(lbuf, cd, &PG(http_globals)[TRACK_VARS_FILES], 0);

			/* Restore Content-Type Header */
			if (s != NULL) {
				*s = ';';
			}
			s = "";

			{
				/* store temp_filename as-is (in case upload_tmp_dir
				 * contains escapeable characters. escape only the variable name.) */
				zval zfilename;

				/* Initialize variables */
				add_protected_variable(param);

				/* if param is of form xxx[.*] this will cut it to xxx */
				if (!is_anonymous) {
					if (temp_filename) {
						ZVAL_STR_COPY(&zfilename, temp_filename);
					} else {
						ZVAL_EMPTY_STRING(&zfilename);
					}
					safe_php_register_variable_ex(param, &zfilename, NULL, 1);
				}

				/* Add $foo[tmp_name] */
				if (is_arr_upload) {
					snprintf(lbuf, llen, "%s[tmp_name][%s]", abuf, array_index);
				} else {
					snprintf(lbuf, llen, "%s[tmp_name]", param);
				}
				add_protected_variable(lbuf);
				if (temp_filename) {
					ZVAL_STR_COPY(&zfilename, temp_filename);
				} else {
					ZVAL_EMPTY_STRING(&zfilename);
				}
				register_http_post_files_variable_ex(lbuf, &zfilename, &PG(http_globals)[TRACK_VARS_FILES], 1);
			}

			{
				zval file_size, error_type;
				int size_overflow = 0;
				char file_size_buf[65];

				ZVAL_LONG(&error_type, cancel_upload);

				/* Add $foo[error] */
				if (cancel_upload) {
					ZVAL_LONG(&file_size, 0);
				} else {
					if (total_bytes > ZEND_LONG_MAX) {
#ifdef PHP_WIN32
						if (_i64toa_s(total_bytes, file_size_buf, 65, 10)) {
							file_size_buf[0] = '0';
							file_size_buf[1] = '\0';
						}
#else
						{
							int __len = snprintf(file_size_buf, 65, "%" PRId64, total_bytes);
							file_size_buf[__len] = '\0';
						}
#endif
						size_overflow = 1;

					} else {
						ZVAL_LONG(&file_size, total_bytes);
					}
				}

				if (is_arr_upload) {
					snprintf(lbuf, llen, "%s[error][%s]", abuf, array_index);
				} else {
					snprintf(lbuf, llen, "%s[error]", param);
				}
				register_http_post_files_variable_ex(lbuf, &error_type, &PG(http_globals)[TRACK_VARS_FILES], 0);

				/* Add $foo_size */
				if (is_arr_upload) {
					snprintf(lbuf, llen, "%s_size[%s]", abuf, array_index);
				} else {
					snprintf(lbuf, llen, "%s_size", param);
				}
				if (!is_anonymous) {
					if (size_overflow) {
						ZVAL_STRING(&file_size, file_size_buf);
					}
					safe_php_register_variable_ex(lbuf, &file_size, NULL, size_overflow);
				}

				/* Add $foo[size] */
				if (is_arr_upload) {
					snprintf(lbuf, llen, "%s[size][%s]", abuf, array_index);
				} else {
					snprintf(lbuf, llen, "%s[size]", param);
				}
				if (size_overflow) {
					ZVAL_STRING(&file_size, file_size_buf);
				}
				register_http_post_files_variable_ex(lbuf, &file_size, &PG(http_globals)[TRACK_VARS_FILES], size_overflow);
			}
			efree(param);
		}
	}

fileupload_done:
	if (php_rfc1867_callback != NULL) {
		multipart_event_end event_end;

		event_end.post_bytes_processed = SG(read_post_bytes);
		php_rfc1867_callback(MULTIPART_EVENT_END, &event_end, &event_extra_data);
	}

	if (lbuf) efree(lbuf);
	if (abuf) efree(abuf);
	if (array_index) efree(array_index);
	zend_hash_destroy(&PG(rfc1867_protected_variables));
	zend_llist_destroy(&header);
	if (mbuff->boundary_next) efree(mbuff->boundary_next);
	if (mbuff->boundary) efree(mbuff->boundary);
	if (mbuff->buffer) efree(mbuff->buffer);
	if (mbuff) efree(mbuff);
}
/* }}} */

SAPI_API void php_rfc1867_set_multibyte_callbacks(
					php_rfc1867_encoding_translation_t encoding_translation,
					php_rfc1867_get_detect_order_t get_detect_order,
					php_rfc1867_set_input_encoding_t set_input_encoding,
					php_rfc1867_getword_t getword,
					php_rfc1867_getword_conf_t getword_conf,
					php_rfc1867_basename_t basename) /* {{{ */
{
	php_rfc1867_encoding_translation = encoding_translation;
	php_rfc1867_get_detect_order = get_detect_order;
	php_rfc1867_set_input_encoding = set_input_encoding;
	php_rfc1867_getword = getword;
	php_rfc1867_getword_conf = getword_conf;
	php_rfc1867_basename = basename;
}
Пример #26
0
int
ntpdmain(
	int argc,
	char *argv[]
	)
{
	l_fp		now;
	struct recvbuf *rbuf;
	const char *	logfilename;
# ifdef HAVE_UMASK
	mode_t		uv;
# endif
# if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
	uid_t		uid;
# endif
# if defined(HAVE_WORKING_FORK)
	long		wait_sync = 0;
	int		pipe_fds[2];
	int		rc;
	int		exit_code;
#  ifdef _AIX
	struct sigaction sa;
#  endif
#  if !defined(HAVE_SETSID) && !defined (HAVE_SETPGID) && defined(TIOCNOTTY)
	int		fid;
#  endif
# endif	/* HAVE_WORKING_FORK*/
# ifdef SCO5_CLOCK
	int		fd;
	int		zero;
# endif

# ifdef HAVE_UMASK
	uv = umask(0);
	if (uv)
		umask(uv);
	else
		umask(022);
# endif
	saved_argc = argc;
	saved_argv = argv;
	progname = argv[0];
	initializing = TRUE;		/* mark that we are initializing */
	parse_cmdline_opts(&argc, &argv);
# ifdef DEBUG
	debug = OPT_VALUE_SET_DEBUG_LEVEL;
# endif

	if (HAVE_OPT(NOFORK) || HAVE_OPT(QUIT)
# ifdef DEBUG
	    || debug
# endif
	    || HAVE_OPT(SAVECONFIGQUIT))
		nofork = TRUE;

	init_logging(progname, NLOG_SYNCMASK, TRUE);
	/* honor -l/--logfile option to log to a file */
	if (HAVE_OPT(LOGFILE)) {
		logfilename = OPT_ARG(LOGFILE);
		syslogit = FALSE;
		change_logfile(logfilename, FALSE);
	} else {
		logfilename = NULL;
		if (nofork)
			msyslog_term = TRUE;
		if (HAVE_OPT(SAVECONFIGQUIT))
			syslogit = FALSE;
	}
	msyslog(LOG_NOTICE, "%s: Starting\n", Version);

	{
		int i;
		char buf[1024];	/* Secret knowledge of msyslog buf length */
		char *cp = buf;

		/* Note that every arg has an initial space character */
		snprintf(cp, sizeof(buf), "Command line:");
		cp += strlen(cp);

		for (i = 0; i < saved_argc ; ++i) {
			snprintf(cp, sizeof(buf) - (cp - buf),
				" %s", saved_argv[i]);
			cp += strlen(cp);
		}
		msyslog(LOG_NOTICE, "%s", buf);
	}

	/*
	 * Install trap handlers to log errors and assertion failures.
	 * Default handlers print to stderr which doesn't work if detached.
	 */
	isc_assertion_setcallback(assertion_failed);
	isc_error_setfatal(library_fatal_error);
	isc_error_setunexpected(library_unexpected_error);

	/* MPE lacks the concept of root */
# if defined(HAVE_GETUID) && !defined(MPE)
	uid = getuid();
	if (uid && !HAVE_OPT( SAVECONFIGQUIT )) {
		msyslog_term = TRUE;
		msyslog(LOG_ERR,
			"must be run as root, not uid %ld", (long)uid);
		exit(1);
	}
# endif

/*
 * Enable the Multi-Media Timer for Windows?
 */
# ifdef SYS_WINNT
	if (HAVE_OPT( MODIFYMMTIMER ))
		set_mm_timer(MM_TIMER_HIRES);
# endif

#ifdef HAVE_DNSREGISTRATION
/*
 * Enable mDNS registrations?
 */
	if (HAVE_OPT( MDNS )) {
		mdnsreg = TRUE;
	}
#endif  /* HAVE_DNSREGISTRATION */

	if (HAVE_OPT( NOVIRTUALIPS ))
		listen_to_virtual_ips = 0;

	/*
	 * --interface, listen on specified interfaces
	 */
	if (HAVE_OPT( INTERFACE )) {
		int		ifacect = STACKCT_OPT( INTERFACE );
		const char**	ifaces  = STACKLST_OPT( INTERFACE );
		sockaddr_u	addr;

		while (ifacect-- > 0) {
			add_nic_rule(
				is_ip_address(*ifaces, AF_UNSPEC, &addr)
					? MATCH_IFADDR
					: MATCH_IFNAME,
				*ifaces, -1, ACTION_LISTEN);
			ifaces++;
		}
	}

	if (HAVE_OPT( NICE ))
		priority_done = 0;

# ifdef HAVE_SCHED_SETSCHEDULER
	if (HAVE_OPT( PRIORITY )) {
		config_priority = OPT_VALUE_PRIORITY;
		config_priority_override = 1;
		priority_done = 0;
	}
# endif

# ifdef HAVE_WORKING_FORK
	do {					/* 'loop' once */
		if (!HAVE_OPT( WAIT_SYNC ))
			break;
		wait_sync = OPT_VALUE_WAIT_SYNC;
		if (wait_sync <= 0) {
			wait_sync = 0;
			break;
		}
		/* -w requires a fork() even with debug > 0 */
		nofork = FALSE;
		if (pipe(pipe_fds)) {
			exit_code = (errno) ? errno : -1;
			msyslog(LOG_ERR,
				"Pipe creation failed for --wait-sync: %m");
			exit(exit_code);
		}
		waitsync_fd_to_close = pipe_fds[1];
	} while (0);				/* 'loop' once */
# endif	/* HAVE_WORKING_FORK */

	init_lib();
# ifdef SYS_WINNT
	/*
	 * Start interpolation thread, must occur before first
	 * get_systime()
	 */
	init_winnt_time();
# endif
	/*
	 * Initialize random generator and public key pair
	 */
	get_systime(&now);

	ntp_srandom((int)(now.l_i * now.l_uf));

	/*
	 * Detach us from the terminal.  May need an #ifndef GIZMO.
	 */
	if (!nofork) {

# ifdef HAVE_WORKING_FORK
		rc = fork();
		if (-1 == rc) {
			exit_code = (errno) ? errno : -1;
			msyslog(LOG_ERR, "fork: %m");
			exit(exit_code);
		}
		if (rc > 0) {	
			/* parent */
			exit_code = wait_child_sync_if(pipe_fds[0],
						       wait_sync);
			exit(exit_code);
		}
		
		/*
		 * child/daemon 
		 * close all open files excepting waitsync_fd_to_close.
		 * msyslog() unreliable until after init_logging().
		 */
		closelog();
		if (syslog_file != NULL) {
			fclose(syslog_file);
			syslog_file = NULL;
			syslogit = TRUE;
		}
		close_all_except(waitsync_fd_to_close);
		INSIST(0 == open("/dev/null", 0) && 1 == dup2(0, 1) \
			&& 2 == dup2(0, 2));

		init_logging(progname, 0, TRUE);
		/* we lost our logfile (if any) daemonizing */
		setup_logfile(logfilename);

#  ifdef SYS_DOMAINOS
		{
			uid_$t puid;
			status_$t st;

			proc2_$who_am_i(&puid);
			proc2_$make_server(&puid, &st);
		}
#  endif	/* SYS_DOMAINOS */
#  ifdef HAVE_SETSID
		if (setsid() == (pid_t)-1)
			msyslog(LOG_ERR, "setsid(): %m");
#  elif defined(HAVE_SETPGID)
		if (setpgid(0, 0) == -1)
			msyslog(LOG_ERR, "setpgid(): %m");
#  else		/* !HAVE_SETSID && !HAVE_SETPGID follows */
#   ifdef TIOCNOTTY
		fid = open("/dev/tty", 2);
		if (fid >= 0) {
			ioctl(fid, (u_long)TIOCNOTTY, NULL);
			close(fid);
		}
#   endif	/* TIOCNOTTY */
		ntp_setpgrp(0, getpid());
#  endif	/* !HAVE_SETSID && !HAVE_SETPGID */
#  ifdef _AIX
		/* Don't get killed by low-on-memory signal. */
		sa.sa_handler = catch_danger;
		sigemptyset(&sa.sa_mask);
		sa.sa_flags = SA_RESTART;
		sigaction(SIGDANGER, &sa, NULL);
#  endif	/* _AIX */
# endif		/* HAVE_WORKING_FORK */
	}

# ifdef SCO5_CLOCK
	/*
	 * SCO OpenServer's system clock offers much more precise timekeeping
	 * on the base CPU than the other CPUs (for multiprocessor systems),
	 * so we must lock to the base CPU.
	 */
	fd = open("/dev/at1", O_RDONLY);		
	if (fd >= 0) {
		zero = 0;
		if (ioctl(fd, ACPU_LOCK, &zero) < 0)
			msyslog(LOG_ERR, "cannot lock to base CPU: %m");
		close(fd);
	}
# endif

# if defined(HAVE_MLOCKALL)
#  ifdef HAVE_SETRLIMIT
	ntp_rlimit(RLIMIT_STACK, DFLT_RLIMIT_STACK * 4096, 4096, "4k");
#   ifdef RLIMIT_MEMLOCK
	/*
	 * The default RLIMIT_MEMLOCK is very low on Linux systems.
	 * Unless we increase this limit malloc calls are likely to
	 * fail if we drop root privilege.  To be useful the value
	 * has to be larger than the largest ntpd resident set size.
	 */
	ntp_rlimit(RLIMIT_MEMLOCK, DFLT_RLIMIT_MEMLOCK * 1024 * 1024, 1024 * 1024, "MB");
#   endif	/* RLIMIT_MEMLOCK */
#  endif	/* HAVE_SETRLIMIT */
	/*
	 * lock the process into memory
	 */
	if (!HAVE_OPT(SAVECONFIGQUIT) &&
	    0 != mlockall(MCL_CURRENT|MCL_FUTURE))
		msyslog(LOG_ERR, "mlockall(): %m");
# else	/* !HAVE_MLOCKALL follows */
#  ifdef HAVE_PLOCK
#   ifdef PROCLOCK
#    ifdef _AIX
	/*
	 * set the stack limit for AIX for plock().
	 * see get_aix_stack() for more info.
	 */
	if (ulimit(SET_STACKLIM, (get_aix_stack() - 8 * 4096)) < 0)
		msyslog(LOG_ERR,
			"Cannot adjust stack limit for plock: %m");
#    endif	/* _AIX */
	/*
	 * lock the process into memory
	 */
	if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(PROCLOCK))
		msyslog(LOG_ERR, "plock(PROCLOCK): %m");
#   else	/* !PROCLOCK follows  */
#    ifdef TXTLOCK
	/*
	 * Lock text into ram
	 */
	if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(TXTLOCK))
		msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
#    else	/* !TXTLOCK follows */
	msyslog(LOG_ERR, "plock() - don't know what to lock!");
#    endif	/* !TXTLOCK */
#   endif	/* !PROCLOCK */
#  endif	/* HAVE_PLOCK */
# endif	/* !HAVE_MLOCKALL */

	/*
	 * Set up signals we pay attention to locally.
	 */
# ifdef SIGDIE1
	signal_no_reset(SIGDIE1, finish);
	signal_no_reset(SIGDIE2, finish);
	signal_no_reset(SIGDIE3, finish);
	signal_no_reset(SIGDIE4, finish);
# endif
# ifdef SIGBUS
	signal_no_reset(SIGBUS, finish);
# endif

# if !defined(SYS_WINNT) && !defined(VMS)
#  ifdef DEBUG
	(void) signal_no_reset(MOREDEBUGSIG, moredebug);
	(void) signal_no_reset(LESSDEBUGSIG, lessdebug);
#  else
	(void) signal_no_reset(MOREDEBUGSIG, no_debug);
	(void) signal_no_reset(LESSDEBUGSIG, no_debug);
#  endif	/* DEBUG */
# endif	/* !SYS_WINNT && !VMS */

	/*
	 * Set up signals we should never pay attention to.
	 */
# ifdef SIGPIPE
	signal_no_reset(SIGPIPE, SIG_IGN);
# endif

	/*
	 * Call the init_ routines to initialize the data structures.
	 *
	 * Exactly what command-line options are we expecting here?
	 */
	INIT_SSL();
	init_auth();
	init_util();
	init_restrict();
	init_mon();
	init_timer();
	init_request();
	init_control();
	init_peer();
# ifdef REFCLOCK
	init_refclock();
# endif
	set_process_priority();
	init_proto();		/* Call at high priority */
	init_io();
	init_loopfilter();
	mon_start(MON_ON);	/* monitor on by default now	  */
				/* turn off in config if unwanted */

	/*
	 * Get the configuration.  This is done in a separate module
	 * since this will definitely be different for the gizmo board.
	 */
	getconfig(argc, argv);
	loop_config(LOOP_DRIFTINIT, 0);
	report_event(EVNT_SYSRESTART, NULL, NULL);
	initializing = FALSE;

# ifdef HAVE_DROPROOT
	if (droproot) {
		/* Drop super-user privileges and chroot now if the OS supports this */

#  ifdef HAVE_LINUX_CAPABILITIES
		/* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
		if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) {
			msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
			exit(-1);
		}
#  else
		/* we need a user to switch to */
		if (user == NULL) {
			msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" );
			exit(-1);
		}
#  endif	/* HAVE_LINUX_CAPABILITIES */

		if (user != NULL) {
			if (isdigit((unsigned char)*user)) {
				sw_uid = (uid_t)strtoul(user, &endp, 0);
				if (*endp != '\0')
					goto getuser;

				if ((pw = getpwuid(sw_uid)) != NULL) {
					free(user);
					user = estrdup(pw->pw_name);
					sw_gid = pw->pw_gid;
				} else {
					errno = 0;
					msyslog(LOG_ERR, "Cannot find user ID %s", user);
					exit (-1);
				}

			} else {
getuser:
				errno = 0;
				if ((pw = getpwnam(user)) != NULL) {
					sw_uid = pw->pw_uid;
					sw_gid = pw->pw_gid;
				} else {
					if (errno)
						msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user);
					else
						msyslog(LOG_ERR, "Cannot find user `%s'", user);
					exit (-1);
				}
			}
		}
		if (group != NULL) {
			if (isdigit((unsigned char)*group)) {
				sw_gid = (gid_t)strtoul(group, &endp, 0);
				if (*endp != '\0')
					goto getgroup;
			} else {
getgroup:
				if ((gr = getgrnam(group)) != NULL) {
					sw_gid = gr->gr_gid;
				} else {
					errno = 0;
					msyslog(LOG_ERR, "Cannot find group `%s'", group);
					exit (-1);
				}
			}
		}

		if (chrootdir ) {
			/* make sure cwd is inside the jail: */
			if (chdir(chrootdir)) {
				msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir);
				exit (-1);
			}
			if (chroot(chrootdir)) {
				msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir);
				exit (-1);
			}
			if (chdir("/")) {
				msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m");
				exit (-1);
			}
		}
		if (user && initgroups(user, sw_gid)) {
			msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user);
			exit (-1);
		}
		if (group && setgid(sw_gid)) {
			msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
			exit (-1);
		}
		if (group && setegid(sw_gid)) {
			msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
			exit (-1);
		}
		if (user && setuid(sw_uid)) {
			msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
			exit (-1);
		}
		if (user && seteuid(sw_uid)) {
			msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
			exit (-1);
		}

#  ifndef HAVE_LINUX_CAPABILITIES
		/*
		 * for now assume that the privilege to bind to privileged ports
		 * is associated with running with uid 0 - should be refined on
		 * ports that allow binding to NTP_PORT with uid != 0
		 */
		disable_dynamic_updates |= (sw_uid != 0);  /* also notifies routing message listener */
#  endif

		if (disable_dynamic_updates && interface_interval) {
			interface_interval = 0;
			msyslog(LOG_INFO, "running as non-root disables dynamic interface tracking");
		}

#  ifdef HAVE_LINUX_CAPABILITIES
		{
			/*
			 *  We may be running under non-root uid now, but we still hold full root privileges!
			 *  We drop all of them, except for the crucial one or two: cap_sys_time and
			 *  cap_net_bind_service if doing dynamic interface tracking.
			 */
			cap_t caps;
			char *captext;
			
			captext = (0 != interface_interval)
				      ? "cap_sys_time,cap_net_bind_service=pe"
				      : "cap_sys_time=pe";
			caps = cap_from_text(captext);
			if (!caps) {
				msyslog(LOG_ERR,
					"cap_from_text(%s) failed: %m",
					captext);
				exit(-1);
			}
			if (-1 == cap_set_proc(caps)) {
				msyslog(LOG_ERR,
					"cap_set_proc() failed to drop root privs: %m");
				exit(-1);
			}
			cap_free(caps);
		}
#  endif	/* HAVE_LINUX_CAPABILITIES */
		root_dropped = TRUE;
		fork_deferred_worker();
	}	/* if (droproot) */
# endif	/* HAVE_DROPROOT */

	/*
	 * Use select() on all on all input fd's for unlimited
	 * time.  select() will terminate on SIGALARM or on the
	 * reception of input.	Using select() means we can't do
	 * robust signal handling and we get a potential race
	 * between checking for alarms and doing the select().
	 * Mostly harmless, I think.
	 */
	/*
	 * On VMS, I suspect that select() can't be interrupted
	 * by a "signal" either, so I take the easy way out and
	 * have select() time out after one second.
	 * System clock updates really aren't time-critical,
	 * and - lacking a hardware reference clock - I have
	 * yet to learn about anything else that is.
	 */
# ifdef HAVE_IO_COMPLETION_PORT

	for (;;) {
		GetReceivedBuffers();
# else /* normal I/O */

	BLOCK_IO_AND_ALARM();
	was_alarmed = FALSE;
	for (;;) {
#  ifndef HAVE_SIGNALED_IO
		fd_set rdfdes;
		int nfound;
#  endif

		if (alarm_flag) {	/* alarmed? */
			was_alarmed = TRUE;
			alarm_flag = FALSE;
		}

		if (!was_alarmed && !has_full_recv_buffer()) {
			/*
			 * Nothing to do.  Wait for something.
			 */
#  ifndef HAVE_SIGNALED_IO
			rdfdes = activefds;
#   if !defined(VMS) && !defined(SYS_VXWORKS)
			nfound = select(maxactivefd + 1, &rdfdes, NULL,
					NULL, NULL);
#   else	/* VMS, VxWorks */
			/* make select() wake up after one second */
			{
				struct timeval t1;

				t1.tv_sec = 1;
				t1.tv_usec = 0;
				nfound = select(maxactivefd + 1,
						&rdfdes, NULL, NULL,
						&t1);
			}
#   endif	/* VMS, VxWorks */
			if (nfound > 0) {
				l_fp ts;

				get_systime(&ts);

				input_handler(&ts);
			} else if (nfound == -1 && errno != EINTR) {
				msyslog(LOG_ERR, "select() error: %m");
			}
#   ifdef DEBUG
			  else if (debug > 4) {
				msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);
			} else {
				DPRINTF(1, ("select() returned %d: %m\n", nfound));
			}
#   endif /* DEBUG */
#  else /* HAVE_SIGNALED_IO */

			wait_for_signal();
#  endif /* HAVE_SIGNALED_IO */
			if (alarm_flag) {	/* alarmed? */
				was_alarmed = TRUE;
				alarm_flag = FALSE;
			}
		}

		if (was_alarmed) {
			UNBLOCK_IO_AND_ALARM();
			/*
			 * Out here, signals are unblocked.  Call timer routine
			 * to process expiry.
			 */
			timer();
			was_alarmed = FALSE;
			BLOCK_IO_AND_ALARM();
		}

# endif		/* !HAVE_IO_COMPLETION_PORT */

# ifdef DEBUG_TIMING
		{
			l_fp pts;
			l_fp tsa, tsb;
			int bufcount = 0;

			get_systime(&pts);
			tsa = pts;
# endif
			rbuf = get_full_recv_buffer();
			while (rbuf != NULL) {
				if (alarm_flag) {
					was_alarmed = TRUE;
					alarm_flag = FALSE;
				}
				UNBLOCK_IO_AND_ALARM();

				if (was_alarmed) {
					/* avoid timer starvation during lengthy I/O handling */
					timer();
					was_alarmed = FALSE;
				}

				/*
				 * Call the data procedure to handle each received
				 * packet.
				 */
				if (rbuf->receiver != NULL) {
# ifdef DEBUG_TIMING
					l_fp dts = pts;

					L_SUB(&dts, &rbuf->recv_time);
					DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9)));
					collect_timing(rbuf, "buffer processing delay", 1, &dts);
					bufcount++;
# endif
					(*rbuf->receiver)(rbuf);
				} else {
					msyslog(LOG_ERR, "fatal: receive buffer callback NULL");
					abort();
				}

				BLOCK_IO_AND_ALARM();
				freerecvbuf(rbuf);
				rbuf = get_full_recv_buffer();
			}
# ifdef DEBUG_TIMING
			get_systime(&tsb);
			L_SUB(&tsb, &tsa);
			if (bufcount) {
				collect_timing(NULL, "processing", bufcount, &tsb);
				DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9)));
			}
		}
# endif

		/*
		 * Go around again
		 */

# ifdef HAVE_DNSREGISTRATION
		if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) {
			mdnsreg = current_time;
			msyslog(LOG_INFO, "Attempting to register mDNS");
			if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, 
			    htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) {
				if (!--mdnstries) {
					msyslog(LOG_ERR, "Unable to register mDNS, giving up.");
				} else {	
					msyslog(LOG_INFO, "Unable to register mDNS, will try later.");
				}
			} else {
				msyslog(LOG_INFO, "mDNS service registered.");
				mdnsreg = FALSE;
			}
		}
# endif /* HAVE_DNSREGISTRATION */

	}
	UNBLOCK_IO_AND_ALARM();
	return 1;
}
#endif	/* !SIM */


#if !defined(SIM) && defined(SIGDIE1)
/*
 * finish - exit gracefully
 */
static RETSIGTYPE
finish(
	int sig
	)
{
	const char *sig_desc;

	sig_desc = NULL;
#ifdef HAVE_STRSIGNAL
	sig_desc = strsignal(sig);
#endif
	if (sig_desc == NULL)
		sig_desc = "";
	msyslog(LOG_NOTICE, "%s exiting on signal %d (%s)", progname,
		sig, sig_desc);
# ifdef HAVE_DNSREGISTRATION
	if (mdns != NULL)
		DNSServiceRefDeallocate(mdns);
# endif
	exit(0);
}
#endif	/* !SIM && SIGDIE1 */


#ifndef SIM
/*
 * wait_child_sync_if - implements parent side of -w/--wait-sync
 */
# ifdef HAVE_WORKING_FORK
static int
wait_child_sync_if(
	int	pipe_read_fd,
	long	wait_sync
	)
{
	int	rc;
	int	exit_code;
	time_t	wait_end_time;
	time_t	cur_time;
	time_t	wait_rem;
	fd_set	readset;
	struct timeval wtimeout;

	if (0 == wait_sync) 
		return 0;

	/* waitsync_fd_to_close used solely by child */
	close(waitsync_fd_to_close);
	wait_end_time = time(NULL) + wait_sync;
	do {
		cur_time = time(NULL);
		wait_rem = (wait_end_time > cur_time)
				? (wait_end_time - cur_time)
				: 0;
		wtimeout.tv_sec = wait_rem;
		wtimeout.tv_usec = 0;
		FD_ZERO(&readset);
		FD_SET(pipe_read_fd, &readset);
		rc = select(pipe_read_fd + 1, &readset, NULL, NULL,
			    &wtimeout);
		if (-1 == rc) {
			if (EINTR == errno)
				continue;
			exit_code = (errno) ? errno : -1;
			msyslog(LOG_ERR,
				"--wait-sync select failed: %m");
			return exit_code;
		}
		if (0 == rc) {
			/*
			 * select() indicated a timeout, but in case
			 * its timeouts are affected by a step of the
			 * system clock, select() again with a zero 
			 * timeout to confirm.
			 */
			FD_ZERO(&readset);
			FD_SET(pipe_read_fd, &readset);
			wtimeout.tv_sec = 0;
			wtimeout.tv_usec = 0;
			rc = select(pipe_read_fd + 1, &readset, NULL,
				    NULL, &wtimeout);
			if (0 == rc)	/* select() timeout */
				break;
			else		/* readable */
				return 0;
		} else			/* readable */
			return 0;
	} while (wait_rem > 0);

	fprintf(stderr, "%s: -w/--wait-sync %ld timed out.\n",
		progname, wait_sync);
	return ETIMEDOUT;
}
Пример #27
0
static int cli_main( int argc, char * argv[] )
{

    static const char * ini_defaults[] = {
        "report_zend_debug",    "0",
        "display_errors",       "1",
        "register_argc_argv",   "1",
        "html_errors",          "0",
        "implicit_flush",       "1",
        "output_buffering",     "0",
        "max_execution_time",   "0",
        "max_input_time",       "-1",
        NULL
    };

    const char ** ini;
    char ** p = &argv[1];
    char ** argend= &argv[argc];
    int ret = -1;
    int c;
#if PHP_MAJOR_VERSION >= 7
	zend_string * psKey;
#endif
    lsapi_mode = 0;        /* enter CLI mode */

#ifdef PHP_WIN32
    _fmode = _O_BINARY;            /*sets default for file streams to binary */
    setmode(_fileno(stdin), O_BINARY);    /* make the stdio mode be binary */
    setmode(_fileno(stdout), O_BINARY);   /* make the stdio mode be binary */
    setmode(_fileno(stderr), O_BINARY);   /* make the stdio mode be binary */
#endif

    zend_first_try     {
        SG(server_context) = (void *) 1;

        zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */
        CG(in_compilation) = 0; /* not initialized but needed for several options */
        SG(options) |= SAPI_OPTION_NO_CHDIR;
        
#if PHP_MAJOR_VERSION < 7
        EG(uninitialized_zval_ptr) = NULL;
#endif
        for( ini = ini_defaults; *ini; ini+=2 ) {
#if PHP_MAJOR_VERSION >= 7
			psKey = zend_string_init(*ini, strlen( *ini ), 1);
            zend_alter_ini_entry_chars(psKey,
                                (char *)*(ini+1), strlen( *(ini+1) ),
                                PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
			zend_string_release(psKey);
#else
            zend_alter_ini_entry( (char *)*ini, strlen( *ini )+1,
                                (char *)*(ini+1), strlen( *(ini+1) ),
                                PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
#endif
        }

        while (( p < argend )&&(**p == '-' )) {
            c = *((*p)+1);
            ++p;
            switch( c ) {
            case 'q':
                break;
            case 'i':
                if (php_request_startup() != FAILURE) {
                    php_print_info(0xFFFFFFFF);
#ifdef PHP_OUTPUT_NEWAPI
                    php_output_end_all();
#else
                    php_end_ob_buffers(1);
#endif
                    php_request_shutdown( NULL );
                    ret = 0;
                }
                break;
            case 'v':
                if (php_request_startup() != FAILURE) {
#if ZEND_DEBUG
                    php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2017 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
#else
                    php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2017 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
#endif
#ifdef PHP_OUTPUT_NEWAPI
                    php_output_end_all();
#else
                    php_end_ob_buffers(1);
#endif
                    php_request_shutdown( NULL );
                    ret = 0;
                }
                break;
            case 'c':
                ++p;
            /* fall through */
            case 's':
                break;
            case 'l':
                source_highlight = 2;
                break;
            case 'h':
            case '?':
            default:
                cli_usage();
                ret = 0;
                break;

            }
        }
        if ( ret == -1 ) {
            if ( *p ) {
                zend_file_handle file_handle = {0};

                file_handle.type = ZEND_HANDLE_FP;
                file_handle.handle.fp = VCWD_FOPEN(*p, "rb");

                if ( file_handle.handle.fp ) {
                    script_filename = *p;
                    php_self = *p;

                    SG(request_info).path_translated = estrdup(*p);
                    SG(request_info).argc = argc - (p - argv);
                    SG(request_info).argv = p;

                    if (php_request_startup() == FAILURE ) {
                        fclose( file_handle.handle.fp );
                        ret = 2;
                    } else {
                        if (source_highlight == 1) {
                            zend_syntax_highlighter_ini syntax_highlighter_ini;

                            php_get_highlight_struct(&syntax_highlighter_ini);
                            highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini);
                        } else if (source_highlight == 2) {
                            file_handle.filename = *p;
                            file_handle.free_filename = 0;
                            file_handle.opened_path = NULL;
                            ret = php_lint_script(&file_handle);
                            if (ret==SUCCESS) {
                                zend_printf("No syntax errors detected in %s\n", file_handle.filename);
                            } else {
                                zend_printf("Errors parsing %s\n", file_handle.filename);
                            }

                        } else {
                            file_handle.filename = *p;
                            file_handle.free_filename = 0;
                            file_handle.opened_path = NULL;

                            php_execute_script(&file_handle);
                            ret = EG(exit_status);
                       }

                        php_request_shutdown( NULL );
                    }
                } else {
                    php_printf("Could not open input file: %s.\n", *p);
                }
            } else {
                cli_usage();
            }
        }

    }zend_end_try();

    php_module_shutdown();

#ifdef ZTS
    tsrm_shutdown();
#endif
    return ret;
}
Пример #28
0
/* setprogram: set stored name of program */
void setprogname2(char *str){
  name = estrdup(str);
}
Пример #29
0
static void
loadcgo(char *file, char *pkg, char *p, int n)
{
	char *pend, *next, *p0, *q;
	char *f[10], *local, *remote, *lib;
	int nf;
	Sym *s;

	USED(file);
	pend = p + n;
	p0 = nil;
	for(; p<pend; p=next) {
		next = strchr(p, '\n');
		if(next == nil)
			next = "";
		else
			*next++ = '\0';

		free(p0);
		p0 = estrdup(p); // save for error message
		nf = tokenize(p, f, nelem(f));
		
		if(strcmp(f[0], "cgo_import_dynamic") == 0) {
			if(nf < 2 || nf > 4)
				goto err;
			
			local = f[1];
			remote = local;
			if(nf > 2)
				remote = f[2];
			lib = "";
			if(nf > 3)
				lib = f[3];
			
			if(debug['d']) {
				fprint(2, "%s: %s: cannot use dynamic imports with -d flag\n", argv0, file);
				nerrors++;
				return;
			}
		
			if(strcmp(local, "_") == 0 && strcmp(remote, "_") == 0) {
				// allow #pragma dynimport _ _ "foo.so"
				// to force a link of foo.so.
				havedynamic = 1;
				adddynlib(lib);
				continue;
			}

			local = expandpkg(local, pkg);
			q = strchr(remote, '#');
			if(q)
				*q++ = '\0';
			s = lookup(local, 0);
			if(local != f[1])
				free(local);
			if(s->type == 0 || s->type == SXREF || s->type == SHOSTOBJ) {
				s->dynimplib = lib;
				s->extname = remote;
				s->dynimpvers = q;
				if(s->type != SHOSTOBJ)
					s->type = SDYNIMPORT;
				havedynamic = 1;
			}
			continue;
		}
		
		if(strcmp(f[0], "cgo_import_static") == 0) {
			if(nf != 2)
				goto err;
			local = f[1];
			s = lookup(local, 0);
			s->type = SHOSTOBJ;
			s->size = 0;
			continue;
		}

		if(strcmp(f[0], "cgo_export_static") == 0 || strcmp(f[0], "cgo_export_dynamic") == 0) {
			// TODO: Remove once we know Windows is okay.
			if(strcmp(f[0], "cgo_export_static") == 0 && HEADTYPE == Hwindows)
				continue;

			if(nf < 2 || nf > 3)
				goto err;
			local = f[1];
			if(nf > 2)
				remote = f[2];
			else
				remote = local;
			local = expandpkg(local, pkg);
			s = lookup(local, 0);

			if(flag_shared && s == lookup("main", 0))
				continue;

			// export overrides import, for openbsd/cgo.
			// see issue 4878.
			if(s->dynimplib != nil) {
				s->dynimplib = nil;
				s->extname = nil;
				s->dynimpvers = nil;
				s->type = 0;
			}

			if(s->cgoexport == 0) {
				s->extname = remote;
				if(ndynexp%32 == 0)
					dynexp = erealloc(dynexp, (ndynexp+32)*sizeof dynexp[0]);
				dynexp[ndynexp++] = s;
			} else if(strcmp(s->extname, remote) != 0) {
				fprint(2, "%s: conflicting cgo_export directives: %s as %s and %s\n", argv0, s->name, s->extname, remote);
				nerrors++;
				return;
			}
			if(strcmp(f[0], "cgo_export_static") == 0)
				s->cgoexport |= CgoExportStatic;
			else
				s->cgoexport |= CgoExportDynamic;
			if(local != f[1])
				free(local);
			continue;
		}
		
		if(strcmp(f[0], "cgo_dynamic_linker") == 0) {
			if(nf != 2)
				goto err;
			
			if(!debug['I']) { // not overridden by command line
				if(interpreter != nil && strcmp(interpreter, f[1]) != 0) {
					fprint(2, "%s: conflict dynlinker: %s and %s\n", argv0, interpreter, f[1]);
					nerrors++;
					return;
				}
				free(interpreter);
				interpreter = estrdup(f[1]);
			}
			continue;
		}
		
		if(strcmp(f[0], "cgo_ldflag") == 0) {
			if(nf != 2)
				goto err;
			if(nldflag%32 == 0)
				ldflag = erealloc(ldflag, (nldflag+32)*sizeof ldflag[0]);
			ldflag[nldflag++] = estrdup(f[1]);
			continue;
		}
	}
	free(p0);
	return;

err:
	fprint(2, "%s: %s: invalid dynimport line: %s\n", argv0, file, p0);
	nerrors++;
}
Пример #30
0
/* {{{ php_fopen_with_path
 * Tries to open a file with a PATH-style list of directories.
 * If the filename starts with "." or "/", the path is ignored.
 */
PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, zend_string **opened_path)
{
	char *pathbuf, *ptr, *end;
	char trypath[MAXPATHLEN];
	FILE *fp;
	int filename_length;
	zend_string *exec_filename;

	if (opened_path) {
		*opened_path = NULL;
	}

	if (!filename) {
		return NULL;
	}

	filename_length = (int)strlen(filename);
#ifndef PHP_WIN32
	(void) filename_length;
#endif

	/* Relative path open */
	if ((*filename == '.')
	/* Absolute path open */
	 || IS_ABSOLUTE_PATH(filename, filename_length)
	 || (!path || !*path)
	) {
		return php_fopen_and_set_opened_path(filename, mode, opened_path);
	}

	/* check in provided path */
	/* append the calling scripts' current working directory
	 * as a fall back case
	 */
	if (zend_is_executing() &&
	    (exec_filename = zend_get_executed_filename_ex()) != NULL) {
		const char *exec_fname = ZSTR_VAL(exec_filename);
		size_t exec_fname_length = ZSTR_LEN(exec_filename);

		while ((--exec_fname_length < SIZE_MAX) && !IS_SLASH(exec_fname[exec_fname_length]));
		if ((exec_fname && exec_fname[0] == '[') || exec_fname_length <= 0) {
			/* [no active file] or no path */
			pathbuf = estrdup(path);
		} else {
			size_t path_length = strlen(path);

			pathbuf = (char *) emalloc(exec_fname_length + path_length + 1 + 1);
			memcpy(pathbuf, path, path_length);
			pathbuf[path_length] = DEFAULT_DIR_SEPARATOR;
			memcpy(pathbuf + path_length + 1, exec_fname, exec_fname_length);
			pathbuf[path_length + exec_fname_length + 1] = '\0';
		}
	} else {
		pathbuf = estrdup(path);
	}

	ptr = pathbuf;

	while (ptr && *ptr) {
		end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
		if (end != NULL) {
			*end = '\0';
			end++;
		}
		if (snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename) >= MAXPATHLEN) {
			php_error_docref(NULL, E_NOTICE, "%s/%s path was truncated to %d", ptr, filename, MAXPATHLEN);
		}
		fp = php_fopen_and_set_opened_path(trypath, mode, opened_path);
		if (fp) {
			efree(pathbuf);
			return fp;
		}
		ptr = end;
	} /* end provided path */

	efree(pathbuf);
	return NULL;
}