Пример #1
0
// find an entry in the db; return offset of id or FAIL
int findKey(char *id) {
int start = STARTDB;
	while (start < ENDDB-4) {
		// find the next entry
		start = findoccupied(start);
		if (start == FAIL) return FAIL;

		// start points to EEPROM id - check for match with id		
		if (eestrmatch(start, id)) return start;

		// no match - skip the id and its value and continue scanning
		start = findend(start);		// scan past id
		start = findend(start);		// and value
	}
	return FAIL;
}
Пример #2
0
// list the strings in the avpdb
void cmd_ls(void) {
int start = STARTDB;
	for (;;) {
		// find the next entry
		start = findoccupied(start);
		if (start == FAIL) return;

		eeputs(start);
		msgp(M_defmacro);
		start = findend(start);
		eeputs(start);
		spb('"');
		speol();
		start = findend(start);
	}
}
Пример #3
0
void prompt(void) {
char buf[IDLEN+1];
	// Run the script named "prompt" if there is one else print "> "
	strncpy_P(buf, getmsg(M_promptid), IDLEN);	// get the name "prompt" in our cmd buf
	int entry = findKey(buf);
	if (entry >= 0) doCommand(kludge(findend(entry)));
	else msgp(M_prompt);							// else print default prompt
}
Пример #4
0
// list the strings in the avpdb
void cmd_ls(void) {
int start = STARTDB;
	for (;;) {
		// find the next entry
		start = findoccupied(start);
		if (start == FAIL) return;

		msgp(M_function);
		spb(' ');
		eeputs(start);
		spb(' ');
		spb('{');
		start = findend(start);
		eeputs(start);
		spb('}');
		spb(';');
		speol();
		start = findend(start);
	}
}
Пример #5
0
void doMacroCall(int macroaddress) {
char op = sym;					// save sym for restore
	if (macroaddress >= 0) {
	
		char *fetchmark = fetchptr;			// save the current parse pointer
	
		// call the macro
		calleeprommacro(findend(macroaddress));	// register the macro into the parser stream
		getsym();
		getstatementlist();		// parse and execute the macro code here
		if (sym != s_eof) expected(M_eof);
	
		// restore parsing context so we can resume cleanly
		fetchptr = fetchmark;	// restore pointer
		primec();				// and inchar
		sym = op;				// restore saved sym
	}
}
Пример #6
0
// call a macro and push its return value on the stack
//
void domacrocall(int macroaddress) {
	if (macroaddress >= 0) {
	
		parsearglist();
		byte thesym = sym;					// save sym for restore
		vpush(symval);						// and symval
		char *fetchmark = fetchptr;			// save the current parse pointer

		// call the macro
		calleeprommacro(findend(macroaddress));	// register the macro into the parser stream
		getsym();								// fetch its first symbol
		
		numvar ret = getstatementlist();		// parse and execute the macro code here
//		if (sym != s_eof) expected(M_eof);

		// restore parsing context so we can resume cleanly
		symval = vpop();		// restore symval
		sym = thesym;			// restore saved sym
		releaseargblock();		// drop the args
		fetchptr = fetchmark;	// restore pointer
		primec();				// and inchar
		vpush(ret);				// send back our return value
	}
}
Пример #7
0
//////////
//
//	runBackgroundTasks
//
//	Runs one eligible background task per invocation
//	Returns true if a task was run
//
void runBackgroundTasks(void) {
byte i;	

#ifdef suspendBackground
	if (suspendBackground) return;
#endif

	for (i=0; i<NUMTASKS; i++) {
		// run one task per call on a round robin basis
		if (++curtask >= NUMTASKS) curtask = 0;
		if ((tasklist[curtask] != SLOT_FREE) && 
			(((signed long) millis() - (signed long) waketime[curtask])) >= 0) {

			// run it with the background flag set
			background = 1;
			execscript(SCRIPT_EEPROM, findend(tasklist[curtask]), 0);

			// schedule the next time quantum for this task
			waketime[curtask] = millis() + snoozetime[curtask];
			background = 0;
			break;
		}
	}
}
Пример #8
0
// Get a statement
void getstatement(void) {

#if !defined(TINY85)
	chkbreak();
#endif

	if (sym == s_while) {
		// at this point sym is pointing at s_while, before the conditional expression
		// save fetchptr so we can restart parsing from here as the while iterates
		char *fetchmark = fetchptr;
		for (;;) {
			fetchptr = fetchmark;			// restore to mark
			primec();						// set up for mr. getsym()
			getsym(); 						// fetch the start of the conditional
			if (!getnum()) {					
				//longjmp(env, X_EXIT);		// get the conditional; exit on false
				sym = s_eof;				// we're finished here.  move along.
				return;
			}
			if (sym != s_colon) expectedchar(':');
			getsym();	// eat :
			getstatementlist();
		}
	}
	
	else if (sym == s_if) {
		getsym(); 								// fetch the start of the conditional
		if (!getnum()) {
			//longjmp(env, X_EXIT);	// get the conditional; exit on false
			sym = s_eof;
			return;
		}
		if (sym != s_colon) expectedchar(':');
		getsym();	// eat :
		getstatementlist();
	}


#if SKETCH
	// The switch statement: call one of N macros based on a selector value
	// switch <numval>: macroid1, macroid2,.., macroidN
	// numval < 0: numval = 0
	// numval > N: numval = N

	else if (sym == s_switch) {
		getsym();	// eat "switch"
		numvar selector = getnum();	// evaluate the switch value
		if (selector < 0) selector = 0;
		if (sym != s_colon) expectedchar(':');

		// we sit before the first macroid
		// scan and discard the <selector>'s worth of macro ids 
		// that sit before the one we want
		for (;;) {
			getsym();	// get an id, sets symval to its eeprom addr as a side effect
			if (sym != s_macro) expected (6);		// TODO: define M_macro instead of 6
			getsym();	// eat id, get separator; assume symval is untouched
			if ((sym == s_semi) || (sym == s_eof)) break;	// last case is default so we exit always
			if (sym != s_comma) expectedchar(',');
			if (!selector) break;		// ok, this is the one we want to execute
			selector--;					// one down...
		}

		// call the macro whose addr is squirreled in symval all this time
		// on return, the parser is ready to pick up where we left off
		doMacroCall(symval);

		// scan past the rest of the unused switch options, if any
		// TODO: syntax checking for non-chosen options could be made much tighter at the cost of some space
		while ((sym != s_semi) && (sym != s_eof)) getsym();		// scan to end of statement without executing
	}
#endif


	else if ((sym == s_macro) || (sym == s_undef)) {		// macro def or ref
		getsym();						// scan past macro name to next symbol: ; or :=
		if (sym == s_define) {			// macro definition: macroid := strvalue
			// to define the macro, we need to copy the id somewhere on the stack
			// to avoid having this local buffer in every getstatement stack frame,
			// we break out defineMacro here to a separate function that only eats that
			// stack in the case that a macro is being defined
#ifdef TINY85
			unexpected(M_defmacro);
#else
			defineMacro();
#endif
		}
		else if ((sym == s_semi) || (sym == s_eof)) {	// valid macro reference: let's call it
#if SKETCH
			doMacroCall(symval);			// parseid stashes the macro address in symval
#else
			char op = sym;					// save sym for restore
			expval = findKey(idbuf);		// assumes id in idbuf isn't clobbered since getsym() above
			if (expval >= 0) {
				char *fetchmark = fetchptr;			// save the current parse pointer

				// call the macro
				calleeprommacro(findend(expval));	// register the macro into the parser stream
				getsym();
				getstatementlist();		// parse and execute the macro code here
				if (sym != s_eof) expected(M_eof);

				// restore parsing context so we can resume cleanly
				fetchptr = fetchmark;	// restore pointer
				primec();				// and inchar
				sym = op;				// restore saved sym: s_semi or s_eof
			} else unexpected(M_id);
#endif
		}
		else expectedchar(';');
		//else getexpression();		// assume it was macro1+32+macro2...
	}
	
	else if (sym == s_run) {	// run macroname
		getsym();
		if (sym != s_macro) unexpected(M_id);

#if 0
		// address of macroid is in symval via parseid
		startTask(kludge(symval));
		getsym();
#else
		// address of macroid is in symval via parseid
		// check for [,snoozeintervalms]
		getsym();	// eat macroid to check for comma; symval untouched
		if (sym == s_comma) {
			vpush(symval);
			getsym();			// eat the comma
			getnum();			// get a number or else
			startTask(kludge(vpop()), expval);
		}
		else startTask(kludge(symval), 0);
#endif
	}
	else if (sym == s_stop) {
		getsym();
		if (sym == s_mul) {						// stop * stops all tasks
			initTaskList();
			getsym();
		}
		else if ((sym == s_semi) || (sym == s_eof)) {
			if (background) stopTask(curtask);	// stop with no args stops the current task IF we're in back
			else initTaskList();				// in foreground, stop all
		}
		else stopTask(getnum());
	}

	else if (sym == s_boot) reboot();

#if !defined(TINY85)
	else if (sym == s_rm) {		// rm "sym" or rm *
		getsym();
		if (sym == s_macro) {
			eraseentry(idbuf);
		} 
		else if (sym == s_mul) nukeeeprom();
		else expected(M_id);
		getsym();
	}
	else if (sym == s_ps) showTaskList();
	else if (sym == s_peep) 	{ getsym(); cmd_peep(); }
	else if (sym == s_ls) 		{ getsym(); cmd_ls(); }
	else if (sym == s_help) 	{ getsym(); cmd_help(); }
	else if (sym == s_print) 	{ getsym(); cmd_print(); }
#endif

#ifdef HEX_UPLOAD
	// a line beginning with a colon is treated as a hex record
	// containing data to upload to eeprom
	//
	// TODO: verify checksum
	//
	else if (sym == s_colon) {
		// fetchptr points at the byte count
		byte byteCount = gethex(2);		// 2 bytes byte count
		int addr = gethex(4);			// 4 bytes address
		byte recordType = gethex(2);	// 2 bytes record type; now fetchptr -> data
		if (recordType == 1) reboot();	// reboot on EOF record (01)
		if (recordType != 0) return;	// we only handle the data record (00)
		if (addr == 0) nukeeeprom();	// auto-clear eeprom on write to 0000
		while (byteCount--) eewrite(addr++, gethex(2));		// update the eeprom
		gethex(2);						// discard the checksum
		getsym();						// and re-prime the parser
	}
#endif

	else  {
		getexpression();
	}
}
Пример #9
0
//
//	Recursive descent parser, old-school style.
//
void getfactor(void) {
numvar thesymval = symval;
byte thesym = sym;
	getsym();		// eat the sym we just saved

	switch (thesym) {
		case s_nval:
			vpush(thesymval);
			break;
			
		case s_nvar:
			if (sym == s_equals) {		// assignment, push is after the break;
				getsym();
				assignVar(thesymval, getnum());
			}
			else if (sym == s_incr) {	// postincrement nvar++
				vpush(getVar(thesymval));
				assignVar(thesymval, getVar(thesymval) + 1);
				getsym();
				break;
			}
			else if (sym == s_decr) {	// postdecrement nvar--
				vpush(getVar(thesymval));
				assignVar(thesymval, getVar(thesymval) - 1);
				getsym();
				break;
			}
			vpush(getVar(thesymval));			// both assignment and reference get pushed here
			break;

		case s_nfunct:
			dofunctioncall(thesymval);			// get its value onto the stack
			break;

		// Script-function-returning-value used as a factor
		case s_script_eeprom:				// macro returning value
			callscriptfunction(SCRIPT_EEPROM, findend(thesymval));
			break;

		case s_script_progmem:
			callscriptfunction(SCRIPT_PROGMEM, thesymval);
			break;

		case s_script_file:
			callscriptfunction(SCRIPT_FILE, (numvar) 0);	// name implicitly in idbuf!
			break;

		case s_apin:					// analog pin reference like a0
			if (sym == s_equals) { 		// digitalWrite or analogWrite
				getsym();
				analogWrite(thesymval, getnum());
				vpush(expval);
			}
			else vpush(analogRead(thesymval));
			break;

		case s_dpin:					// digital pin reference like d1
			if (sym == s_equals) { 		// digitalWrite or analogWrite
				getsym();
				digitalWrite(thesymval, getnum());
				vpush(expval);
			}
			else vpush(digitalRead(thesymval));
			break;

		case s_incr:
			if (sym != s_nvar) expected(M_var);
			assignVar(symval, getVar(symval) + 1);
			vpush(getVar(symval));
			getsym();
			break;

		case s_decr:		// pre decrement
			if (sym != s_nvar) expected(M_var);
			assignVar(symval, getVar(symval) - 1);
			vpush(getVar(symval));
			getsym();
			break;

		case s_arg:			// arg(n) - argument value
			if (sym != s_lparen) expectedchar(s_lparen);
			getsym(); 		// eat '('
			vpush(getarg(getnum()));
			if (sym != s_rparen) expectedchar(s_rparen);
			getsym();		// eat ')'
			break;

		case s_lparen:  // expression in parens
			getexpression();
			if (exptype != s_nval) expected(M_number);
			if (sym != s_rparen) missing(M_rparen);
			vpush(expval);
			getsym();	// eat the )
			break;

		//
		// The Family of Unary Operators, which Bind Most Closely to their Factor
		//
		case s_add:			// unary plus (like +3) is kind of a no-op
			getfactor();	// scan a factor and leave its result on the stack
			break;			// done
	
		case s_sub:			// unary minus (like -3)
			getfactor();
			vpush(-vpop());	// similar to above but we adjust the stack value
			break;
	
		case s_bitnot:
			getfactor();
			vpush(~vpop());
			break;
	
		case s_logicalnot:
			getfactor();
			vpush(!vpop());
			break;

		case s_bitand:		// &var gives address-of-var; &macro gives eeprom address of macro
			if (sym == s_nvar) vpush((numvar) &vars[symval]);
			else if (sym == s_script_eeprom) vpush(symval);
			else expected(M_var);
			getsym();		// eat the var reference
			break;

		case s_mul:			// *foo is contents-of-address-foo; *foo=bar is byte poke assignment

/*****
// what is really acceptable for an lvalue here? ;)
//	*y = 5 is failing now by assigning 5 to y before the * is dereferenced
//	due to calling getfactor
//	everything else works :(
*****/
			getfactor();
#if 0
			if (sym == s_equals) {
				getsym();	// eat '='
				getexpression();
				* (volatile byte *) vpop() = (byte) expval;
				vpush((numvar) (byte) expval);
			} 
			else 
#endif
			vpush((numvar) (* (volatile byte *) vpop()));
			break;

		default: 
			unexpected(M_number);
	}

}
Пример #10
0
// Look up an entry by key.  Returns -1 on fail else addr of value.
int getValue(char *key) {
	int kaddr = findKey(key);
	return (kaddr < 0) ? kaddr : findend(kaddr);
}
Пример #11
0
static int parse_http_request(char * data, int len, char * url)
{
	const char * p = data;
	char * tail = p + len;
	const char * uri_data = NULL;
	int uri_len = 0;
	const char * host_data = NULL;
	int host_len = 0;
	int flag_find = 0;

	// POST / HTTP/1.0$$$$
	// GET / HTTP/1.0$$$$   minimum
	// 0123456789012345678
	//      9876543210
	if (((p = findend(data, tail, 18)) == NULL) || (memcmp(p - 9, " HTTP/", 6) != 0))
	{
		return -1;
	}

	// save uri to buf
	uri_data = data + 4;
	//get_strip_string(WEBFILTER_STR_URI, &uri_data, p - 9, &uri_len);
	// support '?' in uri
	if (get_strip_uri(&uri_data, p - 9, &uri_len))
	{
		return -1;
	}
	//printf("urI len : %4d\n", uri_len);

	while (1)
	{
		// find all info, so break
		if (1 == flag_find)
		{
			break;
		}

		data = p + 2;               // skip previous \r\n
		p = findend(data, tail, 8); // p = current line's \r
		if (p == NULL)
		{
			break;
		}

		if (0 == memcmp(data, "Host: ", 6))
		{
			host_data = data + 6;
			get_strip_string(WEBFILTER_STR_HOST, &host_data, p, &host_len);

			if (host_len >= MAX_URL_LEN)
			{
				LOG("%s, host(size:%d) is too long!\n", __FUNCTION__, host_len);
				return -1;
			}

			if (host_len + uri_len >= MAX_URL_LEN)
			{
				LOG("%s, url(size:%d) is too long!\n", __FUNCTION__, host_len + uri_len);
				return -1;
			}

			memcpy(url, host_data, host_len);
			memcpy(url + host_len, uri_data, uri_len);
			url[host_len + uri_len] = '\0';
			printf("urL len : %4d, urL str : %s\n", host_len + uri_len, url);
			flag_find = 1;
		}
	}

	return 0;
}
Пример #12
0
int
main (int argc, char *argv[])
{
  int cl_sfd,adm_sfd, s,u;
  int efd;
  char small_buf[10];
  struct epoll_event event;
   struct epoll_event event2;
  struct epoll_event *events;
  struct ev_conn *tmpptr=NULL;
  struct rlimit limit;
  long maxfd = MAX_FD;
  //allocate and check memory
  
  
  
      limit.rlim_cur = maxfd;
	  limit.rlim_max = maxfd;
      if ( setrlimit( RLIMIT_NOFILE, &limit ) == -1 ) {
	perror( "unable to set new soft limit" );
	return 1;
      }
    
  /* obtain hard/soft limit */
  if ( getrlimit( RLIMIT_NOFILE, &limit ) == -1 ) {
    perror( "unable to obtain limits" );
    return 1;
  } else {
    printf( "FD limit = { hard : %d, soft : %d }\n",
	    limit.rlim_max, limit.rlim_cur );
  }
  
  ev_conn_ptr=(struct ev_conn *) malloc(sizeof(struct ev_conn)*MAX_CLIENTS);
  if (ev_conn_ptr == NULL) {
		fprintf(stderr,"malloc can't allocate memory !!!");
		return 0;
	}
  //

 //bind on the client port
	fprintf(stderr,"Binding on the client port...\n");
  cl_sfd = create_and_bind (CLIENT_PORT);
  if (cl_sfd == -1)
    abort();

  s = make_socket_non_blocking (cl_sfd);
  if (s == -1)
    abort();

  s = listen (cl_sfd, SOMAXCONN);
  if (s == -1)
    {
      perror ("listen");
      abort();
    }

  efd = epoll_create1 (0);
  if (efd == -1)
    {
      perror ("epoll_create");
      abort();
    }
fprintf(stderr,"Client sfd %d\n",cl_sfd);
  event.data.ptr =  fd_alloc(cl_sfd);;
//  event.data.u64 = 0;
//  event.data.u32 = 0;
  event.events = EPOLLIN | EPOLLET;
  s = epoll_ctl (efd, EPOLL_CTL_ADD, cl_sfd, &event);
  if (s == -1)
    {
      perror ("epoll_ctl");
      abort();
    }
	
 //bind on the admin port
	fprintf(stderr,"Binding on the admin port...\n");
  adm_sfd = create_and_bind (ADMIN_PORT);
  if (adm_sfd == -1)
    abort();

  s = make_socket_non_blocking (adm_sfd);
  if (s == -1)
    abort();

  s = listen (adm_sfd, SOMAXCONN);
  if (s == -1)
    {
      perror ("listen");
      abort();
    }

fprintf(stderr,"Admin sfd %d\n",adm_sfd);
  event2.data.ptr = fd_alloc(adm_sfd);
//  event2.data.u64 = 0;
//  event2.data.u32 = 0;
  event2.events = EPOLLIN | EPOLLET;
  s = epoll_ctl (efd, EPOLL_CTL_ADD, adm_sfd, &event2);
  if (s == -1)
    {
      perror ("epoll_ctl");
      abort();
    }

  /* Buffer where events are returned */
  events = calloc (MAXEVENTS, sizeof event);

  /* The event loop */
  while (1)
    {
      int n, i;

      n = epoll_wait (efd, events, MAXEVENTS, -1);
	  
      for (i = 0; i < n; i++)
	{
	struct fd *tmpfd=events[i].data.ptr;
		fprintf(stderr,"wait stopped with %d events fd %d\n",n,tmpfd->sock);
		//continue;
	  if ((events[i].events & EPOLLERR) ||
              (events[i].events & EPOLLHUP) ||
              (!(events[i].events & EPOLLIN)))
	    {
              /* An error has occured on this fd, or the socket is not
                 ready for reading (why were we notified then?) */
	      fprintf (stderr, "epoll error closing the socket or not error maybe\n");
			
	      fd_close(tmpfd);
	      continue;
	    }
	
	  else if (adm_sfd == tmpfd->sock)
	    {
			fprintf(stderr,"admin connection\n");
              /* We have a notification on the listening socket, which
                 means one or more incoming connections. */
              while (1)
                {
			      struct fd *allocfd=NULL;
                  struct sockaddr in_addr;
                  socklen_t in_len;
                  int infd;
                  char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];

                  in_len = sizeof in_addr;
                  infd = accept (adm_sfd, &in_addr, &in_len);
                  if (infd == -1)
                    {
                      if ((errno == EAGAIN) ||
                          (errno == EWOULDBLOCK))
                        {
                          /* We have processed all incoming
                             connections. */
                          break;
                        }
                      else
                        {
                          perror ("accept");
                          break;
                        }
                    }
					
				//TODO da comentiram dolniq zapis, poneje e izlishen ama sega za debug 6te go ostavq
                  s = getnameinfo (&in_addr, in_len,
                                   hbuf, sizeof hbuf,
                                   sbuf, sizeof sbuf,
                                   NI_NUMERICHOST | NI_NUMERICSERV);
                  if (s == 0)
                    {
                      printf("Accepted Admin connection on descriptor %d "
                             "(host=%s, port=%s)\n", infd, hbuf, sbuf);
                    }

                  /* Make the incoming socket non-blocking and add it to the
                     list of fds to monitor. */
                  s = make_socket_non_blocking (infd);
                  if (s == -1)
                    abort();
					allocfd=fd_alloc(infd);
					allocfd->is_admin=1;
                  event.data.ptr = allocfd;
				  //event.data.u32 = 1;
                  event.events = EPOLLIN | EPOLLET;
                  s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event);
                  if (s == -1)
                    {
                      perror ("epoll_ctl");
                      abort();
                    }
                }
              continue;
        }
		else if (cl_sfd == tmpfd->sock)
	    {
			fprintf(stderr,"client connection\n");
              /* We have a notification on the listening socket, which
                 means one or more incoming connections. */
              while (1)
                {
                  struct sockaddr in_addr;
                  socklen_t in_len;
                  int infd;
                  char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];

                  in_len = sizeof in_addr;
                  infd = accept (cl_sfd, &in_addr, &in_len);
                  if (infd == -1)
                    {
                      if ((errno == EAGAIN) ||
                          (errno == EWOULDBLOCK))
                        {
                          /* We have processed all incoming
                             connections. */
                          break;
                        }
                      else
                        {
                          perror ("accept");
                          break;
                        }
                    }
					//TODO da comentiram dolniq zapis, poneje e izlishen ama sega za debug 6te go ostavq
                  s = getnameinfo (&in_addr, in_len,
                                   hbuf, sizeof hbuf,
                                   sbuf, sizeof sbuf,
                                   NI_NUMERICHOST | NI_NUMERICSERV);
                  if (s == 0)
                    {
                      printf("Accepted Client connection on descriptor %d "
                             "(host=%s, port=%s)\n", infd, hbuf, sbuf);
                    }

                  /* Make the incoming socket non-blocking and add it to the
                     list of fds to monitor. */
                  s = make_socket_non_blocking (infd);
                  if (s == -1)
                    abort();

                  event.data.ptr = fd_alloc(infd);
                  event.events = EPOLLIN | EPOLLET;
                  s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event);
                  if (s == -1)
                    {
                      perror ("epoll_ctl");
                      abort();
                    }
                }
              continue;
        }
        else
            {
              /* We have data on the fd waiting to be read. Read and
                 display it. We must read whatever data is available
                 completely, as we are running in edge-triggered mode
                 and won't get a notification again for the same
                 data. */
              int done = 0;
			fprintf(stderr,"check\n");
				if(tmpfd->is_admin)//admin socket
				{
				  ssize_t count=0;
				  int local_ptr=-1;
				  int buf_i=0;
				  if(tmpfd->buffer==NULL)
				  {
				  tmpfd->buffer=ev_buffer_alloc(BUFFER_SIZE);
				  tmpfd->buffer->len=0;
				  }
				  fprintf(stderr,"buffer ne e null\n");
				   char *buf=tmpfd->buffer->buf;
                  
				 while (1)
                {
					
					if(tmpfd->buffer->len>=BUFFER_SIZE)
						{
						fprintf(stderr,"max buffer size reached\n");
							done=1;
							break;
						}
                  count = read (tmpfd->sock, buf+tmpfd->buffer->len, (BUFFER_SIZE-tmpfd->buffer->len));
				  fprintf(stderr,"4ete ot admin\n");
				  write(0,buf+tmpfd->buffer->len,count);
                  if (count == -1)
                    {
                      /* If errno == EAGAIN, that means we have read all
                         data. So go back to the main loop. */
                      if (errno != EAGAIN)
                        {
                          perror ("read");
                          done = 1;
                        }
                      break;
                    }
                  else if (count == 0)
                    {
                      /* End of file. The remote has closed the
                         connection. */
                      done = 1;
                      break;
                    }
					tmpfd->buffer->len+=count;
				fprintf(stderr,"tmpfd->buffer->len e %d\n",tmpfd->buffer->len);
					
					

                  /* Write the buffer to standard output */
				 
				 if(tmpfd->cur_ptr<0)
				 {
				  if(buf[0]=='\n' || buf[0]=='\r') // new key
				  {
					u=0;
					while(u<ERROR_LOOP) //TODO to fix this da po4ne da 4isti socketite kogato sa na 80% pulni
					{
					fprintf(stderr,"vleze v cikula i vurti u\n");
						cur_ptr++;
						if(cur_ptr==MAX_CLIENTS)
						{
						cur_ptr=1;
						u++;
						}
						tmpptr=ev_conn_ptr+cur_ptr;
						if(!tmpptr->sock && tmpptr->buffer==NULL)
						{
						fprintf(stderr,"cur_ptr e %d\n",cur_ptr);
						sprintf(small_buf, "%d", cur_ptr); 
						//key generation
						fprintf(stderr,"small_buf e %s\n",small_buf);
						write(tmpfd->sock,small_buf,strlen(small_buf));
						fprintf(stderr,"brum2\n");
						//tmpfd->cur_ptr=cur_ptr;
						//adding the socket to the memory
						//tmpptr->sock=tmpfd->sock;
						
						break;
						}
						
					}
					if(u==ERROR_LOOP)
						{
						fprintf(stderr,"no free fds\n");
						write(tmpfd->sock,"ERROR",5);
						//TODO to send reconnect signals to the clients and to free the all fds
						abort();
						}
				  
						fprintf(stderr,"key %d\n",cur_ptr);
						done=1;
						break;
				  
				  }
				  else
				  {
				  fprintf(stderr,"chete admina kum koi client 6te se vurje\n");
				 
				 // write (0, buf, count);
				  
				  for(buf_i=0;buf_i<9 && *(buf+buf_i)!='\n' && *(buf+buf_i)!='\r';buf_i++)small_buf[buf_i]=*(buf+buf_i);
				  small_buf[buf_i]='\0';
				  local_ptr=strtol(small_buf, NULL, 10);
				  fprintf(stderr,"local_ptr se okaza %d\n",local_ptr);
				  tmpfd->buffer->offset=(buf_i+1);
					if(tmpfd->buffer->offset>tmpfd->buffer->len)
						{
							fprintf(stderr,"ERROR , the offset is bigger than the len.This should not happen\n");
							return -1;
						}
						
				 
				  if(!local_ptr || local_ptr>MAX_CLIENTS)
					{
					fprintf(stderr,"ERROR wrong number\n");
					write(tmpfd->sock,"ERROR",5);
					close(tmpfd->sock);
					tmpfd->sock=0;
					break;
					//error
					}
					tmpfd->cur_ptr=local_ptr;
					fprintf(stderr,"DEBUG count %d\n",count);
					fprintf(stderr,"DEBUG buf_i %d\n",buf_i);
				  }
				 }
				  
				  
  
				}
				
				if (done)
                {
				
				if((tmpfd->cur_ptr)>=0)
				{
					tmpptr=ev_conn_ptr+tmpfd->cur_ptr;
					//buf[count]='\0';//TODO tova da go vidq dali nqma da otreje posledniq symbol
				  if(tmpptr->sock)
				  {
				  fprintf(stderr,"ima clientski socket za %d i pi6e v nego\n",tmpfd->cur_ptr);
				  s = write (tmpptr->sock, tmpfd->buffer->buf+tmpfd->buffer->offset, tmpfd->buffer->len-tmpfd->buffer->offset);
				  s = write (0, tmpfd->buffer->buf+tmpfd->buffer->offset, tmpfd->buffer->len-tmpfd->buffer->offset);
                  if (s == -1)
                    {
                      perror ("write");
					  write(tmpfd->sock,"ERROR",5);
					  close(tmpfd->sock);
					  tmpfd->sock=0;
					  //nikov
					  if(tmpptr->sock){close(tmpptr->sock);tmpptr->sock=0;}
					  ev_buffer_free(tmpfd->buffer);
					  tmpfd->buffer=NULL;
					  break;
                    }
					
					//closing the client socket
					
					if(tmpptr->sock)close(tmpptr->sock);
					tmpptr->sock=0;
					ev_buffer_free(tmpfd->buffer);
					tmpfd->buffer=NULL;
					//if(tmpptr->buffer!=NULL)ev_buffer_free(tmpptr->buffer);
					
				   
				   }
				   else 
				   {
				   fprintf(stderr,"zapisva v buffer za %d golqm %d,\n",tmpfd->cur_ptr,tmpfd->buffer->len);
				   tmpptr->buffer=tmpfd->buffer;
				   
				   }
				   
				}
				 
                  printf ("Closed connection on descriptor %d\n",
                          tmpfd->sock);

                  /* Closing the descriptor will make epoll remove it
                     from the set of descriptors which are monitored. */
					 tmpfd->buffer=NULL;
                  close (tmpfd->sock);
                }
				
				}
				else // client socket
				{
				char buf[BUFFER_SIZE];
				  long int local_ptr=-1;
				  int buf_i=0;
				  int tmp=0;
				  int i=0;
				  int error=0;
				  ssize_t count;
					while (1)
					{
                  ssize_t count;
                  

                  count = read (tmpfd->sock, buf,BUFFER_SIZE);
				  fprintf(stderr,"client count %d\n",count);
                  if (count == -1)
                    {
                      /* If errno == EAGAIN, that means we have read all
                         data. So go back to the main loop. */
                      if (errno != EAGAIN)
                        {
                          perror ("read");
                          done = 1;
                        }
                      break;
                    }
                  else if (count == 0)
                    {
                      /* End of file. The remote has closed the
                         connection. */
                      done = 1;
                      break;
                    }
					
					if (strncmp(buf,"GET ",4))
							{
							break; 
							}
							
					for(i=0;i<count;i++)
					{
						fprintf(stderr,"%c %d\n",buf[i],i);
						if(buf[i]=='\r' || buf[i]=='\n')
						{
						break;
						}
					}
					if(i==count)
						{
							fprintf(stderr,"strange error in http protocol\n");
							fd_close(tmpfd);
							break;
						}
					fprintf(stderr,"i e %d\n",i);
					count=i;
					 
					if(count <5)
							{
							fprintf(stderr,"ERROR count out of boundaries\n");
							error=1;
							break;
							}
						
						
						
						fprintf(stderr,"buf+4 e %c\n",*(buf+4));
						buf_i=findend(buf+4,count);
						fprintf(stderr,"bif_i e %d\n",buf_i);
						buf[buf_i+4]='\0';
						tmp=buf_i;
						
						for(;buf[buf_i+4]!='/' && buf_i>0;buf_i--);
						if((tmp-(buf_i+1))>9)
							{
							fprintf(stderr,"ERROR count out of boundaries 2\n");
							
							error=1;
							break;
							}
						tmp=0;
						
						local_ptr = strtol(buf+4+buf_i+1, NULL, 10);
						fprintf(stderr,"local_ptr e %lld\n",local_ptr);
						if(local_ptr==0)
							{
							fprintf(stderr,"ERROR local_ptr is 0 for some reason\n");
							
							error=1;
							break;
								
							}
						if(local_ptr>MAX_CLIENTS)
						{
							fprintf(stderr,"ERROR local_ptr %ld",local_ptr);
							
							error=1;
							break;	
						}
						
						tmpptr=ev_conn_ptr+local_ptr;
						if(tmpptr->sock)
						{
							fprintf(stderr,"ERROR tmpptr->sock %d",tmpptr->sock);
							
							error=1;
							break;	
						}
						tmpptr->sock=tmpfd->sock;
						tmpfd->cur_ptr=local_ptr;
						done=1;
					}
					
					if(error)
					{
					s = write (tmpfd->sock, HEADER_BUSY, HEADER_LEN_BUSY);
					
					fd_close(tmpfd);tmpfd->sock=0;
					}
					else if (done && tmpfd->cur_ptr!=-1)
					{
					tmpptr=ev_conn_ptr+tmpfd->cur_ptr;
					s = write (tmpptr->sock, HEADER, HEADER_LEN);
					
						if(tmpptr->buffer!=NULL)
						{
						fprintf(stderr,"buffer ne e NULL len e %d\n",tmpptr->buffer->len);
						fprintf(stderr,"offset\n");
						fprintf(stderr,"buffer ne e NULL offset e %d\n",tmpptr->buffer->offset);
						//for(i=0;i<tmpptr->buffer->len;i++)fprintf(stderr,"%c %d\n",tmpptr->buffer->buf);
						s = write (tmpptr->sock, tmpptr->buffer->buf+tmpptr->buffer->offset, tmpptr->buffer->len-tmpptr->buffer->offset);
						write(0,tmpptr->buffer->buf+tmpptr->buffer->offset,tmpptr->buffer->len-tmpptr->buffer->offset);
						fprintf(stderr,"close\n");
						fd_close(tmpfd);
						tmpptr->sock=0;
						fprintf(stderr,"sock 0\n");
						ev_buffer_free(tmpptr->buffer);
						fprintf(stderr,"free\n");
						tmpptr->buffer=NULL;
						
						}
				
				
					}
					else if(done)
					{
					fprintf(stderr,"nqma cur_ptr i e done taka 4e zatvarq conneciqta\n");
					fd_close(tmpfd);tmpfd->sock=0;
					}
				
				
				}

              
            }
        }
    }

  free (events);

  close (adm_sfd);
  close (cl_sfd);


  return EXIT_SUCCESS;
}