コード例 #1
0
ファイル: ctcpio.c プロジェクト: cbh34680/jbx
static int module_do_callback_(const struct cbmod_st* cbmod, struct jbxm_callback_if_st* cbif)
{
FUNC_ENTER

	JBX_ASSERT(cbmod);

	struct type2cb_st t2cb = { 0 };
	syserr = type2cb(cbif->type, cbmod->loadlib_ref->callbacks, &t2cb);
	if (syserr)
	{
		FIRE("type2cb");
	}

	if (! t2cb.func)
	{
		FINISH();
	}

	cbif->process_no = mgd.runv.ss.nt_boottime;

TRCLOG(
	"enter user-function\n"
	"--->>\n"
	"\t dll path    = %s\n"
	"\t func name   = %s (%p)\n"
	"\t next events = 0x%08x%s"

	, cbmod->iconf->dllpath
	, t2cb.name
	, t2cb.func
	, cbif->flow ? (cbif->flow->next_events) : 0
	, cbif->flow ? (cbif->flow->next_events ? " *" : "") : ""
);

	syserr = t2cb.func(cbmod->iconf, cbif);
	if (syserr)
	{
		FIRE("callback(type=%d)", cbif->type);
	}

TRCLOG(
	"leave user-function\n"
	"\t dll path    = %s\n"
	"\t func name   = %s (%p)\n"
	"\t next events = 0x%08x%s\n"
	"<<---"

	, cbmod->iconf->dllpath
	, t2cb.name
	, t2cb.func
	, cbif->flow ? (cbif->flow->next_events) : 0
	, cbif->flow ? (cbif->flow->next_events ? " *" : "") : ""
);

FUNC_CHECKPOINT

FUNC_LEAVE

	return FUNC_RC_INT();
}
コード例 #2
0
ファイル: test_threads.c プロジェクト: animotron/animos
static void t_wait(void *a)
{
    hal_set_current_thread_priority( THREAD_PRIO_HIGH );

    char *name = a;
    while(!thread_stop_request)
    {
        thread_activity_counter++;

        if(TEST_CHATTY) printf("--- thread %s will wait 4 cond ---\n", name);

        hal_mutex_lock(&m);
        checkEnterMutex();
        checkLeaveMutex();
        hal_cond_wait(&c, &m);
        checkEnterMutex();
        checkLeaveMutex();
        hal_mutex_unlock(&m);

        if(TEST_CHATTY) printf("--- thread %s runs ---\n", name);
        //pressEnter("--- thread a runs ---\n");
        YIELD();
    }
    FINISH();
}
コード例 #3
0
ファイル: sandbox.c プロジェクト: alphaKAI/poe
static int
timer_handler(sd_event_source *es, uint64_t usec, void *vmpid)
{
    (void)es;
    (void)usec;
    (void)vmpid;
    FINISH(POE_TIMEDOUT, -1, NULL);
    return 0;
}
コード例 #4
0
ファイル: sandbox.c プロジェクト: alphaKAI/poe
static int
sigint_handler(sd_event_source *es, const struct signalfd_siginfo *si, void *vmpid)
{
    (void)es;
    (void)si;
    (void)vmpid;
    FINISH(POE_TIMEDOUT, -1, "Supervisor terminated");
    return 0;
}
コード例 #5
0
ファイル: entry.cpp プロジェクト: handgod/soma
/*
 * Main interpreter loop.
 *
 * This was written with an ARM implementation in mind.
 */
void dvmInterpretPortable(Thread* self)
{
#if defined(EASY_GDB)
    StackSaveArea* debugSaveArea = SAVEAREA_FROM_FP(self->interpSave.curFrame);
#endif
    DvmDex* methodClassDex;     // curMethod->clazz->pDvmDex
    JValue retval;

    /* core state */
    const Method* curMethod;    // method we're interpreting
    const u2* pc;               // program counter
    u4* fp;                     // frame pointer
    u2 inst;                    // current instruction
    /* instruction decoding */
    u4 ref;                     // 16 or 32-bit quantity fetched directly
    u2 vsrc1, vsrc2, vdst;      // usually used for register indexes
    /* method call setup */
    const Method* methodToCall;
    bool methodCallRange;

    /* static computed goto table */
    DEFINE_GOTO_TABLE(handlerTable);

    /* copy state in */
    curMethod = self->interpSave.method;
    pc = self->interpSave.pc;
    fp = self->interpSave.curFrame;
    retval = self->interpSave.retval;   /* only need for kInterpEntryReturn? */

    methodClassDex = curMethod->clazz->pDvmDex;

    LOGVV("threadid=%d: %s.%s pc=%#x fp=%p",
        self->threadId, curMethod->clazz->descriptor, curMethod->name,
        pc - curMethod->insns, fp);

    /*
     * Handle any ongoing profiling and prep for debugging.
     */
    if (self->interpBreak.ctl.subMode != 0) {
        TRACE_METHOD_ENTER(self, curMethod);
        self->debugIsMethodEntry = true;   // Always true on startup
    }
    /*
     * DEBUG: scramble this to ensure we're not relying on it.
     */
    methodToCall = (const Method*) -1;

#if 0
    if (self->debugIsMethodEntry) {
        ILOGD("|-- Now interpreting %s.%s", curMethod->clazz->descriptor,
                curMethod->name);
        DUMP_REGS(curMethod, self->interpSave.curFrame, false);
    }
#endif

    FINISH(0);                  /* fetch and execute first instruction */
コード例 #6
0
ファイル: sandbox.c プロジェクト: alphaKAI/poe
static int
sigchld_handler(sd_event_source *es, const struct signalfd_siginfo *si, void *vmpid)
{
    (void)es;
    pid_t mpid = *(pid_t *)vmpid;
    if (si->ssi_signo != SIGCHLD) ERROR("parent: unexpected signal");

    while (true) {
        int status;
        pid_t spid = waitpid(-mpid, &status, WNOHANG | __WALL);
        NONNEGATIVE(spid);
        if (!spid) break;

        if (WIFEXITED(status) && spid == mpid) {
            FINISH(POE_SUCCESS, WEXITSTATUS(status), NULL);
        } else if (WIFSIGNALED(status) && spid == mpid) {
            FINISH(POE_SIGNALED, -1, "Program terminated with signal %d (%s)", WTERMSIG(status), strsignal(WTERMSIG(status)));
        } else if (WIFSTOPPED(status)) {
            int e = status >> 16 & 0xff;
            switch (e) {
            case PTRACE_EVENT_SECCOMP:
                handle_syscall(spid);
                break;
            case PTRACE_EVENT_CLONE:
            case PTRACE_EVENT_FORK:
            case PTRACE_EVENT_VFORK:
                ptrace(PTRACE_CONT, spid, 0, 0);
                break;
            default:
                ptrace(PTRACE_CONT, spid, 0, WSTOPSIG(status));
                break;
            }
        }
    }
    return 0;
}
コード例 #7
0
ファイル: sandbox.c プロジェクト: alphaKAI/poe
static void
handle_syscall(pid_t pid)
{
    errno = 0;
    int syscalln = ptrace(PTRACE_PEEKUSER, pid, sizeof(long) * ORIG_RAX);
    if (errno) ERROR("ptrace(PTRACE_PEEKUSER) failed");

    switch (syscalln) {
    default:
        goto kill;
    }
kill:
    kill(pid, SIGKILL);
    char *rule = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, syscalln);
    if (!rule) ERROR("seccomp_syscall_resolve_num_arch() failed");
    FINISH(POE_SIGNALED, -1, "System call %s is blocked", rule);
allowed:
    ptrace(PTRACE_CONT, pid, 0, 0);
}
コード例 #8
0
ファイル: test_threads.c プロジェクト: animotron/animos
static void thread1(void *a)
{
    char *name = a;
    while(!thread_stop_request)
    {
        thread_activity_counter++;

        if(TEST_CHATTY) printf("--- thread %s runs ---\n", name);
        pressEnter("");

        if(TEST_CHATTY) printf("Will lock mutex\n");
        hal_mutex_lock(&m);
        if(TEST_CHATTY) printf("locked mutex\n");
        checkEnterMutex();
        YIELD();
        if(TEST_CHATTY) printf("Will unlock mutex\n");
        checkLeaveMutex();
        hal_mutex_unlock(&m);
        if(TEST_CHATTY) printf("unlocked mutex\n");

        if( random() & 1 )
            hal_sem_acquire( &s );

        counter++;
        if(counter >7)
        {
            counter = 0;
            if(TEST_CHATTY) printf("Will signal cond\n");
            hal_cond_signal(&c);
            if(TEST_CHATTY) printf("Signalled cond\n");
        }
        YIELD();

    }
    FINISH();
}
コード例 #9
0
ファイル: entry.c プロジェクト: Andproject/platform_dalvik
/*
 * Main interpreter loop.
 *
 * This was written with an ARM implementation in mind.
 */
bool INTERP_FUNC_NAME(Thread* self, InterpState* interpState)
{
#if defined(EASY_GDB)
    StackSaveArea* debugSaveArea = SAVEAREA_FROM_FP(self->curFrame);
#endif
#if INTERP_TYPE == INTERP_DBG
    bool debugIsMethodEntry = interpState->debugIsMethodEntry;
#endif
#if defined(WITH_TRACKREF_CHECKS)
    int debugTrackedRefStart = interpState->debugTrackedRefStart;
#endif
    DvmDex* methodClassDex;     // curMethod->clazz->pDvmDex
    JValue retval;

    /* core state */
    const Method* curMethod;    // method we're interpreting
    const u2* pc;               // program counter
    u4* fp;                     // frame pointer
    u2 inst;                    // current instruction
    /* instruction decoding */
    u2 ref;                     // 16-bit quantity fetched directly
    u2 vsrc1, vsrc2, vdst;      // usually used for register indexes
    /* method call setup */
    const Method* methodToCall;
    bool methodCallRange;


#if defined(THREADED_INTERP)
    /* static computed goto table */
    DEFINE_GOTO_TABLE(handlerTable);
#endif

#if defined(WITH_JIT)
#if 0
    LOGD("*DebugInterp - entrypoint is %d, tgt is 0x%x, %s\n",
         interpState->entryPoint,
         interpState->pc,
         interpState->method->name);
#endif
#if INTERP_TYPE == INTERP_DBG
    /* Check to see if we've got a trace selection request. */
    if (
         /*
          * Only perform dvmJitCheckTraceRequest if the entry point is
          * EntryInstr and the jit state is either kJitTSelectRequest or
          * kJitTSelectRequestHot. If debugger/profiler happens to be attached,
          * dvmJitCheckTraceRequest will change the jitState to kJitDone but
          * but stay in the dbg interpreter.
          */
         (interpState->entryPoint == kInterpEntryInstr) &&
         (interpState->jitState == kJitTSelectRequest ||
          interpState->jitState == kJitTSelectRequestHot) &&
         dvmJitCheckTraceRequest(self, interpState)) {
        interpState->nextMode = INTERP_STD;
        //LOGD("Invalid trace request, exiting\n");
        return true;
    }
#endif /* INTERP_TYPE == INTERP_DBG */
#endif /* WITH_JIT */

    /* copy state in */
    curMethod = interpState->method;
    pc = interpState->pc;
    fp = interpState->fp;
    retval = interpState->retval;   /* only need for kInterpEntryReturn? */

    methodClassDex = curMethod->clazz->pDvmDex;

    LOGVV("threadid=%d: entry(%s) %s.%s pc=0x%x fp=%p ep=%d\n",
        self->threadId, (interpState->nextMode == INTERP_STD) ? "STD" : "DBG",
        curMethod->clazz->descriptor, curMethod->name, pc - curMethod->insns,
        fp, interpState->entryPoint);

    /*
     * DEBUG: scramble this to ensure we're not relying on it.
     */
    methodToCall = (const Method*) -1;

#if INTERP_TYPE == INTERP_DBG
    if (debugIsMethodEntry) {
        ILOGD("|-- Now interpreting %s.%s", curMethod->clazz->descriptor,
                curMethod->name);
        DUMP_REGS(curMethod, interpState->fp, false);
    }
#endif

    switch (interpState->entryPoint) {
    case kInterpEntryInstr:
        /* just fall through to instruction loop or threaded kickstart */
        break;
    case kInterpEntryReturn:
        CHECK_JIT();
        goto returnFromMethod;
    case kInterpEntryThrow:
        goto exceptionThrown;
    default:
        dvmAbort();
    }

#ifdef THREADED_INTERP
    FINISH(0);                  /* fetch and execute first instruction */
#else
    while (1) {
        CHECK_DEBUG_AND_PROF(); /* service debugger and profiling */
        CHECK_TRACKED_REFS();   /* check local reference tracking */

        /* fetch the next 16 bits from the instruction stream */
        inst = FETCH(0);

        switch (INST_INST(inst)) {
コード例 #10
0
ファイル: srs.c プロジェクト: shevek/libsrs2
static void
rundaemon(srs_t *srs, char *path, int daemonflags)
{
	fd_set				 readfds_sv;
	fd_set				 readfds;
	struct sockaddr_un	 addr;
	socklen_t			 addrlen;
	int	 				 sock;
	int					 maxfd;
	int					 fd;
	char				 line[BUFSIZ];
	int					 len;
	char				 buf[BUFSIZ];
	char				*cp;
	char				*address;
	char				*alias;
	int					 ret;

	sock = listen_socket(path);

	/* daemon() */

	FD_ZERO(&readfds_sv);
	FD_SET(sock, &readfds_sv);
	maxfd = sock + 1;

#define FINISH(fd) \
	do { close(fd); FD_CLR(fd, &readfds_sv); continue; } while(0)
#define SKIPWHITE(cp) while (isspace(*cp)) cp++;

	if (!(daemonflags & DF_NOFORK)) {
		if (daemon(0, 0) < 0)
			perror("daemon");
	}

	for (;;) {
		memcpy(&readfds, &readfds_sv, sizeof(fd_set));

		select(maxfd, &readfds, NULL, NULL, NULL);
		for (fd = 0; fd < maxfd; fd++) {
			if (FD_ISSET(fd, &readfds)) {
				if (fd == sock) {
					fd = accept(sock, (struct sockaddr*)&addr,&addrlen);
					if (fd < 0) {
						perror("accept");
						continue;
					}
					FD_SET(fd, &readfds_sv);
					if (fd >= maxfd)
						maxfd = fd + 1;
					fprintf(stderr, "Accept %d\n", fd);
					continue;
				}
				else {
					len = read(fd, line, BUFSIZ);
					if (len <= 0) {
						if (len < 0)
							perror("read");
						fprintf(stderr, "Close %d\n", fd);
						FINISH(fd);
					}
					line[strcspn(line, "\r\n")] = '\0';
					fprintf(stderr, "%d: %s\n", fd, line);

					if (strncasecmp(line, "forward ", 8) == 0) {
						cp = line + 8;
						while (isspace(*cp))
							cp++;
						address = cp;
						cp = strchr(address, ' ');
						if (cp == NULL) {
							fprintf(stderr, "No alias in %s on %d\n",
											line, fd);
							FINISH(fd);
						}
						*cp++ = '\0';
						while (isspace(*cp))
							cp++;
						alias = cp;
						ret = srs_forward(srs, buf, BUFSIZ,
										address, alias);
						if (ret != SRS_SUCCESS) {
							fprintf(stderr, "SRS error: %s\n",
											srs_strerror(ret));
							FINISH(fd);
						}
						fprintf(stderr, "Forward %s, %s -> %s\n",
										address, alias, buf);
						write(fd, buf, strlen(buf));
						write(fd, "\n", 1);
						FINISH(fd);
					}
					else if (strncasecmp(line, "reverse ", 8) == 0) {
						cp = line + 8;
						while (isspace(*cp))
							cp++;
						address = cp;
						ret = srs_reverse(srs, buf, BUFSIZ, address);
						if (ret != SRS_SUCCESS) {
							fprintf(stderr, "SRS error: %s\n",
											srs_strerror(ret));
							FINISH(fd);
						}
						fprintf(stderr, "Reverse %s -> %s\n",
										address, buf);
						write(fd, buf, strlen(buf));
						write(fd, "\n", 1);
						FINISH(fd);
					}
					else {
						fprintf(stderr, "Unknown command %s on %d\n",
										line, fd);
						FINISH(fd);
					}
				}
			}
		}
	}
}
コード例 #11
0
ファイル: entry.cpp プロジェクト: tempbottle/aprotector
/*
 * Main interpreter loop.
 *
 * This was written with an ARM implementation in mind.
 * portable���͵Ľ������Ľ���ѭ�����
 */
void dvmInterpretPortable(Thread* self)
{
#if defined(EASY_GDB)
    // ��������Ƿ�����ԣ�������ջ֡�ĵ�ַ
    StackSaveArea* debugSaveArea = SAVEAREA_FROM_FP(self->interpSave.curFrame);
#endif
    DvmDex* methodClassDex;     // curMethod->clazz->pDvmDex
    JValue retval;

    /* core state */
    const Method* curMethod;    // method we're interpreting ��ǰ����Ҫ���͵ķ���
    const u2* pc;               // program counter ���������
    u4* fp;                     // frame pointer ָ֡��
    u2 inst;                    // current instruction ��ǰָ��

	
    /* instruction decoding */
    u4 ref;                     // 16 or 32-bit quantity fetched directly
    u2 vsrc1, vsrc2, vdst;      // usually used for register indexes
    
    /* method call setup */
    const Method* methodToCall;
    bool methodCallRange;

    /* 
    * static computed goto table
    * ��̬����õ���ת��
    * ʵ���Ͼ��Ƕ���õ�һ�����
    * �þ�̬��ת����libdex��dexopcode.h�ж���
    * [��Ҫע����壺�ñ�ֻ�ṩ����cʵ�ֵĽ�������ʹ��]
    * �⿪�����������
    *  static const void* handlerTable[0x100] = {                      \
    *    H(OP_NOP),                                                            \
    *    H(OP_MOVE),                                                           \
    *    ....
    *  }
    * ���������opcode-gen������߶�̬���ɵģ�����˵�����������ʲô�����ɵģ���Ҫ�ο��ù��ߵ�ʵ��
    *
    * # define H(_op)             &&op_##_op
    * ʵ�����������������&&op_OP_NOP �����ĵ�ַ
    */
    DEFINE_GOTO_TABLE(handlerTable);

    /* copy state in 
    * ��ʼ��һЩ״ֵ̬
    */
    curMethod = self->interpSave.method;
    pc = self->interpSave.pc;
    fp = self->interpSave.curFrame;
    retval = self->interpSave.retval;   /* only need for kInterpEntryReturn? */

    methodClassDex = curMethod->clazz->pDvmDex; //��ȡdex��ص�����(������Ҫ�ο�vm\DvmDex.cpp��������ʵ��)

    LOGVV("threadid=%d: %s.%s pc=%#x fp=%p",
        self->threadId, curMethod->clazz->descriptor, curMethod->name,
        pc - curMethod->insns, fp);

    /*
     * Handle any ongoing profiling and prep for debugging.
     * ������Ҫ�Ƿ�����ԣ�����������һ�����巽���Ľ���
     */
    if (self->interpBreak.ctl.subMode != 0) {
        TRACE_METHOD_ENTER(self, curMethod);
        self->debugIsMethodEntry = true;   // Always true on startup
    }
    /*
     * DEBUG: scramble this to ensure we're not relying on it.
     */
    methodToCall = (const Method*) -1;

#if 0
    if (self->debugIsMethodEntry) {
        ILOGD("|-- Now interpreting %s.%s", curMethod->clazz->descriptor,
                curMethod->name);
        DUMP_REGS(curMethod, self->interpSave.curFrame, false);
    }
#endif

    //�����↑ʼ����ȡָ�ִ�У����صĽ׶�
    // ������ʵ���Ͻ�����һ��do - while��ѭ����ֱ��ִ����Ϸ���
    FINISH(0);                  /* fetch and execute first instruction */
コード例 #12
0
ファイル: envelope_handle.c プロジェクト: heytimc/envelope
bool handle(int csock) {
	NOTICE("################# REQUEST");
	PGconn *cnxn = NULL;
	char buf[BUF_LEN + 2];
	buf[0] = 0;
	DEFINE_VAR_ALL(str_response, str_request, str_uri, str_temp, str_form_data);
	DEFINE_VAR_MORE(str_correct_referer_start1, str_correct_referer_start2);
	DEFINE_VAR_MORE(str_referer, str_host, str_request_len, str_boundary);
	DEFINE_VAR_MORE(str_cookie_envelope, str_complete_response, str_buffer);
	
	DEBUG("### get the str_request\n");
	//##########################################
	//### get the str_request
	
	//DEBUG(">%d|%d<", SSIZE_MAX, BUF_LEN);
	
	int int_request_len = BUF_LEN;
	memset(buf, 0, BUF_LEN + 1);
	int_request_len = read(csock, buf, BUF_LEN);
	FINISH_SALLOC(str_request, int_request_len + 1);
	memcpy(str_request, buf, int_request_len);
	str_request[int_request_len] = '\0';
	
	//HERE BE DRAGONS
	//Maintainer: joseph
	//This code reads from the socket only for as long as is necessary.
	//If we have just one extra read command, it will hang until the browser
	//sends more data. Which it won't. So read until end of request.
	//@@@@@@@@@@@@@@@@@@@@@**^^""~~~"^@@^*@*@@**@@@@@@@@@
	//@@@@@@@@@@@@@*^^'"~   , - ' '; ,@@b. '  -e@@@@@@@@@
	//@@@@@@@@*^"~      . '     . ' ,@@@@(  e@*@@@@@@@@@@
	//@@@@@^~         .       .   ' @@@@@@, ~^@@@@@@@@@@@
	//@@@~ ,e**@@*e,  ,e**e, .    ' '@@@@@@e,  "*@@@@@'^@
	//@',e@@@@@@@@@@ e@@@@@@       ' '*@@@@@@    @@@'   0
	//@@@@@@@@@@@@@@@@@@@@@',e,     ;  ~^*^'    ;^~   ' 0
	//@@@@@@@@@@@@@@@^""^@@e@@@   .'           ,'   .'  @
	//@@@@@@@@@@@@@@'    '@@@@@ '         ,  ,e'  .    ;@
	//@@@@@@@@@@@@@' ,&&,  ^@*'     ,  .  i^"@e, ,e@e  @@
	//@@@@@@@@@@@@' ,@@@@,          ;  ,& !,,@@@e@@@@ e@@
	//@@@@@,~*@@*' ,@@@@@@e,   ',   e^~^@,   ~'@@@@@@,@@@
	//@@@@@@, ~" ,e@@@@@@@@@*e*@*  ,@e  @@""@e,,@@@@@@@@@
	//@@@@@@@@ee@@@@@@@@@@@@@@@" ,e@' ,e@' e@@@@@@@@@@@@@
	//@@@@@@@@@@@@@@@@@@@@@@@@" ,@" ,e@@e,,@@@@@@@@@@@@@@
	//@@@@@@@@@@@@@@@@@@@@@@@~ ,@@@,,0@@@@@@@@@@@@@@@@@@@
	//@@@@@@@@@@@@@@@@@@@@@@@@,,@@@@@@@@@@@@@@@@@@@@@@@@@
	//"""""""""""""""""""""""""""""""""""""""""""""""""""

	char *ptr_boundary_start = strstr(str_request, "Content-Type: multipart/form-data; boundary=");
	if (ptr_boundary_start != NULL &&
		strchr(ptr_boundary_start, 13) == NULL) {
		memset(buf, 0, BUF_LEN + 1);
		int int_current_length = read(csock, buf, BUF_LEN);
		FINISH_SREALLOC(str_request, int_current_length + int_request_len + 1);
		memcpy(str_request + int_request_len, buf, int_current_length);
		str_request[int_current_length + int_request_len] = '\0';
		int_request_len = int_request_len + int_current_length;
	}
	
	//DEBUG("test0>%s|%i<", str_request, int_request_len);
	
	char *request_ptr;
	//// ****if upload then special case
	if (strstr(str_request, "Content-Type: multipart/form-data; boundary=") != 0) {
		//get boundary
		char *boundary_ptr = strstr(str_request, "Content-Type: multipart/form-data; boundary=") + 44;
		char *boundary_end_ptr = strchr(boundary_ptr, 13) != 0 ?	strchr(boundary_ptr, 13) : strchr(boundary_ptr, 10);
		DEBUG("str_boundary: %d %d", boundary_end_ptr, boundary_ptr);
		int int_boundary_length = boundary_end_ptr - boundary_ptr;
		DEBUG("str_boundary: %d", int_boundary_length);
		FINISH_SALLOC(str_boundary, int_boundary_length + 3); //extra and null byte
		DEBUG("TESTING1");
		memcpy(str_boundary, boundary_ptr, int_boundary_length);
		DEBUG("TESTING2");
		str_boundary[int_boundary_length + 0] = '-';
		DEBUG("TESTING3");
		str_boundary[int_boundary_length + 1] = '-';
		DEBUG("TESTING4");
		str_boundary[int_boundary_length + 2] = '\0';
		DEBUG("TESTING5");
		int int_current_length = BUF_LEN;
		DEBUG("TESTING6");
		//DEBUG("str_boundary: %s", str_boundary);
		//DEBUG("str_request: %s", str_request);
		DEBUG("bstrstr(\"%-10s\", %d, \"%s\", %d", str_request, int_request_len, str_boundary, int_boundary_length + 2);
		/*
		DEBUG("test0>%s<", bstrstr(
						str_request, int_request_len,
						str_boundary, int_boundary_length + 2) == NULL ? "NULL" : "NOT NULL");
		while (bstrstr(
					str_request, int_request_len,
					str_boundary, int_boundary_length + 2) == NULL) {//while null
			DEBUG("test1");
			memset(buf, 0, BUF_LEN + 1);
			//FINISH_SALLOC(str_buffer, BUF_LEN + 2);
			DEBUG("test2");
			int_current_length = read(csock, buf, BUF_LEN);
			DEBUG("test3");
			FINISH_SREALLOC(str_request, int_request_len + int_current_length + 1);
			DEBUG("test4>%s<", str_request);
			memcpy(str_request + int_request_len, buf, int_current_length);
			int_request_len = int_request_len + int_current_length;
			str_request[int_request_len] = '\0';
			//SFREE(str_buffer);
			DEBUG("test5>%i<", int_request_len);
		}
		*/
		DEBUG(">%s<", bstrstr(
						str_request + int_request_len - int_current_length - int_boundary_length,
						int_current_length + int_boundary_length,
						str_boundary, int_boundary_length + 2) == NULL ? "NULL" : "NOT NULL");
		while (bstrstr(
					str_request + int_request_len - int_current_length - int_boundary_length,
					int_current_length + int_boundary_length,
					str_boundary, int_boundary_length + 2) == NULL) {//while null
			memset(buf, 0, BUF_LEN + 1);
			//DEBUG("test1");
			int_current_length = read(csock, buf, BUF_LEN);
			//DEBUG("test2");
			FINISH_SREALLOC(str_request, int_request_len + int_current_length + 1);
			//DEBUG("test3>%s<", str_request);
			memcpy(str_request + int_request_len, buf, int_current_length);
			int_request_len = int_request_len + int_current_length;
			str_request[int_request_len] = '\0';
			//DEBUG("test4>%i<", int_request_len);
		}
		DEBUG("test5>%s<", bstrstr(
						str_request,
						int_request_len,
						str_boundary, int_boundary_length + 2) - 25);
		SFREE(str_boundary);
	
	////  ****
	// if post or put, then get content length and receive that amount after two newlines, then break
	} else if (strncmp(str_request, "P", 1) == 0) {
		//we need Content-Length: before we can continue
		while (! strstr(str_request, "Content-Length:")) {
			memset(buf, 0, BUF_LEN + 1);
			//DEBUG("test1");
			int_request_len = read(csock, buf, BUF_LEN);
			//DEBUG("test2>%i<", int_request_len);
			//buf[request_len] = 0;
			FINISH_CAT_APPEND(str_request, buf);
			//DEBUG("#request_len:%d", int_request_len);
		}
		request_ptr = strstr(str_request, "Content-Length:");
		// if we didn't find anything we need to stop, len("Content-Length")==15
		if (strlen(request_ptr) < 16) {
			// error bad str_request
			FINISH("Bad str_request");
		}
		// move pointer to start of content length value
		request_ptr = request_ptr + 15;
		//DEBUG("request_ptr>%s<", request_ptr);
		
		// step through the buffer and see if we can get the length
		int req_len = 0;
		while (request_ptr != 0 && *request_ptr != '\r' && *request_ptr != '\n') {
			if (request_ptr == 0 && req_len == 0) {
				// error bad str_request
			}
			//do not comment next line!!!!!!!! give inconsistent output without this line!!!!!! idk why!!!!!!!
			//DEBUG("test1>%c<", *request_ptr);
			///////////////
			if (*request_ptr != '\r' && *request_ptr != '\n') {
				request_ptr = request_ptr + 1;
				req_len = req_len + 1;
			}
		}
		FINISH_SALLOC(str_request_len, req_len + 1);
		request_ptr = request_ptr - req_len;
		memcpy(str_request_len, request_ptr, req_len);
		str_request_len[req_len] = '\0';
		//DEBUG("test2>%s|%s<", str_request_len, request_ptr, req_len);
		req_len = atoi(str_request_len);
		SFREE(str_request_len);
		while (strstr(str_request,"\r\n\r\n") == 0 && strstr(str_request, "\n\n") == 0 && strstr(str_request, "\r\r") == 0) {
			memset(buf,0,BUF_LEN + 1);
			int_request_len = read(csock, buf, BUF_LEN);
			FINISH_CAT_APPEND(str_request, buf);
		}
		request_ptr = strstr(str_request,"\r\n\r\n") != 0 ? strstr(str_request,"\r\n\r\n") + 4 :
			strstr(str_request,"\n\n") != 0 ? strstr(str_request,"\n\n") + 2 :
			strstr(str_request,"\r\r") != 0 ? strstr(str_request,"\r\r") + 2 : 0;
		unsigned int int_length_we_want = ((request_ptr - str_request) + req_len);
		//DEBUG("test3>%s|%s<", str_request, request_ptr);
		//DEBUG("test4>%i|%i|%i|%i<\n", int_length_we_want, strlen( str_request ), (request_ptr - str_request), req_len);
	
		while (int_length_we_want > strlen(str_request)) {
			memset(buf,0,BUF_LEN + 1);
			int_request_len = read(csock, buf, BUF_LEN);
			FINISH_CAT_APPEND(str_request, buf);
			//DEBUG("test4.1>%i|%i<\n", int_length_we_want, strlen( str_request ));
		}
		//DEBUG("test5\n");
		int_request_len = strlen(str_request);
    
	// if not POST, then break at two newlines.
	// (only other request we accept is GET, we don't use any other methods of request)
	} else {
		while (strstr(str_request,"\r\n\r\n") == 0 && strstr(str_request,"\n\n") == 0 && strstr(str_request,"\r\r") == 0) {
			memset(buf, 0, BUF_LEN + 1);
			int_request_len = read(csock, buf, BUF_LEN);
			FINISH_CAT_APPEND(str_request, buf);
		}
		int_request_len = strlen(str_request);
	}
	DEBUG("request_len>%i<", strlen(str_request));
	
	
	/*
	//for testing actions
	GS.ajaxJSON('URI', 'PARAMS', function (data, error) {
		if (!error) {
			console.log(data);
			
		} else {
			GS.ajaxErrorDialog(data);
		}
	});
	*/
	
	
	
	
	str_uri = str_uri_path(str_request);
	FINISH_CHECK(str_uri != NULL,
		"str_uri_path failed");
	INFO("### str_uri: %s", str_uri);
	
	str_host = request_header(str_request, "host");
	INFO("### str_host: %s", str_host);
	//DEBUG("### REQUEST: %s", str_request);
	
	//check referer
	str_referer = request_header(str_request, "Referer");
	INFO("### str_referer: %s", str_referer);
	
	//when we have a referer, we should make sure it matches our website, but we have a few exceptions.
	if (str_referer != NULL) {
		FINISH_CAT_CSTR(str_correct_referer_start1, "https://", str_host);
		FINISH_CAT_CSTR(str_correct_referer_start2, "http://" , str_host);
		FINISH_CHECK(
			strncmp(str_correct_referer_start1, str_referer, strlen(str_correct_referer_start1)) == 0 ||
			strncmp(str_correct_referer_start2, str_referer, strlen(str_correct_referer_start2)) == 0 ||
			strlen(str_referer) <= 0 ||
			strncmp(str_uri, "/v1/"        , 4 ) != 0 ||
			//strncmp(str_uri, "/v1/env/auth", 12) == 0 ||
			strncmp(str_uri, "/v1/cluster" , 11) == 0 ||
			strncmp(str_uri, "/v1/app"     , 7 ) == 0 ||
			strncmp(str_uri, "/v1/dev"     , 7 ) == 0,
			"Referer does not match host.");
		SFREE(str_correct_referer_start1);
		SFREE(str_correct_referer_start2);
	}
	
	//####################################################################################################
	//######################################### MANAGE COOKIES ###########################################
	// set up database connection
	// FEAR NOT GCC! This will not be used uninitialized.
	//PQinitOpenSSL(0, 0); //prevent Libpq from initializing ssl
	
	bool bol_valid_subdomain = false;
	
	//if subdomain database configuration is active, then change int_global_current_conn_port
	//we use int_global_current_conn_port to connect to the postgres instance
	//if the subdomain is the default subdomain, we should connect to production
	//if the subdomain is not the default subdomain, we should connect to the correct developer area
	//if the subdomain is not recognized, we should connect to production
	if (strlen(str_global_developers) > 0) {
		char *temp = strchr(str_host, '.');
		int int_length = temp - str_host;
		FINISH_SALLOC(str_current_subdomain, int_length + 1);
		DEBUG("### str_host: %s, temp: %s, char: %c, int_length: %d\n", str_host, temp, '.', int_length);
		memcpy(str_current_subdomain, str_host, int_length);
		str_current_subdomain[int_length] = '\0';
		str_temp = getport(str_global_developers, str_current_subdomain);
		FINISH_CHECK(str_temp != NULL, "getport failed");
		if (strlen(str_temp) > 0) {
			DEBUG("VALID SUBDOMAIN DETECTED >%s|%s<", str_global_developers, str_temp);
			int_global_current_conn_port = atoi(str_temp);
			bol_valid_subdomain = true;
		}
		SFREE(str_temp);
	} else {
		FINISH_CAT_CSTR(str_current_subdomain, "");
	}
	
	DEBUG(">%s|%s|%i|%i<", str_uri, "/auth_envelope/accept_auth", strlen(str_uri), strncmp(str_uri, "/auth_envelope/accept_auth", 26) == 0);
	
	DEBUG("test0>str_request: %s", str_request);
	str_cookie_envelope = str_cookie(str_request, "envelope");
	DEBUG("test1");
	
	bol_global_public = false;
	
	DEBUG("str_uri: >%s< str_uri + 13 + strcspn(str_uri + 13, \"./\"): >%s<", str_uri, str_uri + 13 + strcspn(str_uri + 13, "./"));
	
	// if the URL does not start with /v1
	// then serve from the web_root
	if (strncmp(str_uri, "/v1/", 4) != 0) {
		str_response = link_web_root(csock, str_uri, bol_valid_subdomain ? str_current_subdomain : "");
		FINISH_CHECK(str_response != NULL, "link_web_root failed");
		goto finish;
		
	// postgres functions that start with actionnc_ or acceptnc_
	// these CAN have a COOKIE, but it WON'T BE USED
	// set up a public connection
	} else if (//str_cookie_envelope == NULL &&
		strlen(str_uri) >= 13 && strncmp(str_uri, "/v1/cluster/", 12) == 0 &&
		(strncmp(str_uri + 13 + strcspn(str_uri + 13, "./"), ".acceptnc_", 10) == 0 ||
		 strncmp(str_uri + 13 + strcspn(str_uri + 13, "./"), ".actionnc_", 10) == 0)) {
		cnxn = set_cnxn_public(csock, str_request);
		
	// built in envelope functions
	// these links CAN have a COOKIE, but if we don't then set up a public connection
	} else if (str_cookie_envelope == NULL &&
			   ((strlen(str_uri) >= 18 && strncmp(str_uri, "/v1/env/action_info"         , 18) == 0) ||
				(strlen(str_uri) >= 20 && strncmp(str_uri, "/v1/env/action_upload"       , 20) == 0) ||
				(strlen(str_uri) >= 22 && strncmp(str_uri, "/v1/env/accept_download"     , 22) == 0) ||
				(strlen(str_uri) >= 23 && strncmp(str_uri, "/v1/envelope/action_info"    , 23) == 0) ||
				(strlen(str_uri) >= 25 && strncmp(str_uri, "/v1/envelope/action_upload"  , 25) == 0) ||
				(strlen(str_uri) >= 27 && strncmp(str_uri, "/v1/envelope/accept_download", 27) == 0) ||
			    (strlen(str_uri) >= 21 && strncmp(str_uri, "/v1/env/action_select", 21) == 0) ||
				(strlen(str_uri) >= 21 && strncmp(str_uri, "/v1/env/action_update", 21) == 0) ||
				(strlen(str_uri) >= 21 && strncmp(str_uri, "/v1/env/action_insert", 21) == 0) ||
				(strlen(str_uri) >= 21 && strncmp(str_uri, "/v1/env/action_delete", 21) == 0) ||
				(strlen(str_uri) >= 20 && strncmp(str_uri, "/v1/env/action_order" , 20) == 0))) {
		cnxn = set_cnxn_public(csock, str_request);
		
	// authentication links for normal user, these CAN have a COOKIE
	} else if ((strlen(str_uri) >= 26 && strncmp(str_uri, "/auth_envelope/accept_auth", 26) == 0) ||
		(strlen(str_uri) >= 12 && strncmp(str_uri, "/v1/env/auth", 12) == 0)) {
		/*
		FINISH_CHECK(strncmp(str_current_subdomain, str_global_subdomain, strlen(str_global_subdomain)) == 0,
			"Must be in \"%s\" subdomain.", str_global_subdomain);
		*/
		
		str_response = link_auth(cnxn, str_request);
		FINISH_CHECK(str_response != NULL, "link_auth failed");
		goto finish;
	
	// authentication links for superuser, these REQUIRE a COOKIE
	} else if ((strlen(str_uri) >= 16 && strncmp(str_uri, "/v1/postage/auth", 16) == 0)) {
		str_response = link_auth_postage(str_request);
		FINISH_CHECK(str_response != NULL, "link_auth_postage failed");
		goto finish;
	
	// superuser links, these REQUIRE a COOKIE
	} else if (strncmp(str_uri, "/v1/dev"    , 7 ) == 0 ||
			   strncmp(str_uri, "/v1/postage", 11) == 0 ||
			   strncmp(str_uri, "/v1/sql"    , 7 ) == 0) {
		cnxn = set_cnxn_postage(csock, str_uri, str_request);
	
	// subdomain links, these REQUIRE a COOKIE
	} else if (bol_valid_subdomain) {
		cnxn = set_cnxn_test(csock, str_uri, str_request);
	
	// production links, these REQUIRE a COOKIE
	} else {
		cnxn = set_cnxn(csock, str_uri, str_request);
	}
	
	//IF NULL THEN EXIT, CSOCK IS ALREADY WRITTEN TO BY set_cnxn AND set_cnxn_test
	if (cnxn == NULL) {
		//if we use FINISH_CHECK, there will be a sunlogf
		//we don't want a sunlogf cause there is no error. we just want to return
		goto finish;
	}
	
	// cnxn GARANTEED TO BE VALID HERE
	
	//if public cookie (or nocookie always) then public action
	if (bol_global_public) {
		str_response = main_public_action(cnxn, csock, str_uri, str_request, int_request_len,
										  bol_valid_subdomain ? str_current_subdomain : "");
		FINISH_CHECK(str_response != NULL, "link_auth failed");
		goto finish;
	}
	
	//################################################################################################
	//########################## HAVE COOKIE, HAVE CNXN, PARSE REQUESTS ##############################
	DEBUG("COOKIE IS VALID");
	
	//not a webroot request
	if (strncmp(str_uri, "/v1/", 4) == 0) {
		char *ptr_uri = str_uri + 3;
		
		//this link is for accessing the database
		if (strlen(ptr_uri) >= 9 && strncmp(ptr_uri, "/cluster/", 9) == 0) {
			str_response = link_cluster(cnxn, ptr_uri, str_request, csock);
			FINISH_CHECK(str_response != NULL, "link_cluster failed");
			
		//this link is for uploading a file to role
		} else if (strlen(ptr_uri) >= 16 && strncmp(ptr_uri, "/upload_envelope", 16) == 0) {
			str_response = link_upload(cnxn, str_request, int_request_len, bol_valid_subdomain ? str_current_subdomain : "");
			FINISH_CHECK(str_response != NULL, "link_upload failed");
			
		//this link is for builtin c actions like action_select (read from view)
		} else if (strlen(ptr_uri) >= 10 && strncmp(ptr_uri, "/envelope/", 10) == 0) {
			// link system is in envelope_handle_c.c
			str_response = link_system(cnxn, csock, ptr_uri + 5, str_request, int_request_len, bol_valid_subdomain ? str_current_subdomain : "");
			FINISH_CHECK(str_response != NULL, "link_system failed");
		
		//shorter version of the above link
		} else if (strlen(ptr_uri) >= 5 && strncmp(ptr_uri, "/env/", 5) == 0) {
			// link system is in envelope_handle_c.c
			str_response = link_system(cnxn, csock, ptr_uri, str_request, int_request_len, bol_valid_subdomain ? str_current_subdomain : "");
			FINISH_CHECK(str_response != NULL, "link_system failed");
			
		//read file from role
		} else if (strlen(ptr_uri) >= 6 && strncmp(ptr_uri, "/role/", 6) == 0) {
			str_response = link_role(csock, cnxn, ptr_uri, bol_valid_subdomain ? str_current_subdomain : "");
			FINISH_CHECK(str_response != NULL, "link_role failed");
			
		//read app file
		} else if (strncmp(ptr_uri, "/app/", 5) == 0) {
			str_response = link_apps(csock, cnxn, ptr_uri, bol_valid_subdomain ? str_current_subdomain : "");
			FINISH_CHECK(str_response != NULL, "link_apps failed");
			
		//read app file, but require superuser
		} else if (strncmp(ptr_uri, "/dev/", 5) == 0) {
			str_response = link_apps(csock, cnxn, ptr_uri, bol_valid_subdomain ? str_current_subdomain : "");
			FINISH_CHECK(str_response != NULL, "link_apps failed");
			
		//more builtin c actions, but require superuser
		} else if (strlen(ptr_uri) >= 9 && strncmp(ptr_uri, "/postage/", 9) == 0) {
			// link system is in postage_handle_c2.c
			str_response = link_system_postage(cnxn, csock, ptr_uri, str_request, int_request_len);
			FINISH_CHECK(str_response != NULL, "link_system_postage failed");
			
		//run arbitrary sql, must be superuser
		} else if (strlen(ptr_uri) >= 4 && strncmp(ptr_uri, "/sql", 4) == 0) {
			str_response = link_sql(csock, cnxn, str_request);
			FINISH_CHECK(str_response != NULL, "link_sql failed");
			
		//if none of these, error
		} else {
			NOTICE("REQUEST TYPE: UNHANDLED str_uri:%s", str_uri);
			FINISH_CAT_CSTR(str_response, "HTTP/1.1 303 See Other\r\nLocation: /index.html\r\n");
		}
	
	//web_root request should already have been handled, error
	} else {
		NOTICE("REQUEST TYPE: UNHANDLED str_uri:%s", str_uri);
		FINISH_CAT_CSTR(str_response, "HTTP/1.1 303 See Other\r\nLocation: /index.html\r\n");
	}
	
finish:
	if (str_response != NULL) {
		INFO("REPLACE COOKIE IN str_response");
		//replace cookie before expiration
		str_complete_response = replace_cookie(str_response, str_request);
		SFREE_PWORD(str_response);
		
		DEBUG("str_complete_response: %s", str_complete_response);
		
		if ((long)write(csock, str_complete_response, strlen(str_complete_response)) != (long)strlen(str_complete_response)) {
			str_complete_response = ERROR_RESPONSE("write failed: %d (%s)", errno, strerror(errno));
			write(csock, str_complete_response, strlen(str_complete_response));
		}
	} else {
		ERROR_NORESPONSE("no str_response");
	}
	fsync(csock);
	NOTICE("RESPONSE SENT %d bytes", strlen(str_complete_response));
	if (cnxn != NULL) PQfinish(cnxn);
	SFREE_PWORD(str_request);
	SFREE_ALL();
	return true;
}