コード例 #1
0
int handle_header(int clientSock, char* buffer)
{
  		char *Sec_WebSocket_Key = extract_substring(buffer ,"Sec-WebSocket-Key: ","\n");
                //printf("[%s]\n",Sec_WebSocket_Key);
                char *magickey = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
                char *str = malloc(strlen(Sec_WebSocket_Key)+strlen(magickey));
                memset(str,0,strlen(str));
                strcpy(str,Sec_WebSocket_Key);
                strcat(str,magickey);
                unsigned char *sha1_str;
                sha1_str = getsha1 (str ,strlen(str));
                unsigned char *base64_str;
                size_t len;
                base64_str = base64_encode(sha1_str, strlen(sha1_str), &len);
                //printf("[%s]\n",base64_str);
		char buf[512];
		sprintf(buf, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: %s\r\nSec-WebSocket-Protocol: chat\r\n\r\n",base64_str);
		/* 
            	printf("----sending to client----\n");
             	printf("%s\n",buf);
             	printf("-------------------------\n");
		*/
		int byteCount = write(clientSock, buf, strlen(buf));
		if (byteCount > 0)
			return 0;
		else 
			return 1;
}
コード例 #2
0
void handle_message_loop(int clientSock)
{
	unsigned char buffer[1024];
        memset(buffer,0,sizeof(buffer));
        while(1){
        	int byteCount = read(clientSock , buffer, sizeof(buffer));
                if ( byteCount >= 0 ) {
			unsigned char* decoded_msg = decoded_message(buffer);
			if (decoded_msg == NULL){
                                if (buffer[0] == 0x88){
					printf("socket suddenly close\n");
                                        break;
                                }
				//----------------------------------------------------
                                int i;
                                for(i=0;i<(int)strlen(buffer);i++){
                                        //printf("\ni=%d/%d\n",i,(int) strlen(read_buf));
                                        //printf("[%s]\n", read_buf);
                                        printf("0x%02x ",buffer[i]);
                                }
                                printf("\n");
				//----------------------------------------------------
                        }else{
				printf("Get message [%s]\n",decoded_msg);
				char *get_val;
				if ( (get_val = extract_substring(decoded_msg,"connection:", "\n")) != NULL){
					printf("get_val=connection:%s\n",get_val);	
					char*client_msg=(char*)malloc(512);
					strcpy(client_msg,"connection:");
					strcat(client_msg,get_val);
					//strcat(client_msg,"\n");
                			send_sock_text(clientSock,client_msg);
				}else if ( (get_val = extract_substring(decoded_msg,"input:", "\n")) != NULL){
					printf("get_val=input:%s\n",get_val);
					char*client_msg=(char*)malloc(512);
                                        strcpy(client_msg,"input:");
                                        strcat(client_msg,get_val);
                			send_sock_text(clientSock,client_msg);
				}
			}
                }
	}
}
コード例 #3
0
int main( int argc, char const *argv[])
{
    int serverSock ;
    int val = 1;
    struct sockaddr_in serverAddr ;
    struct sockaddr_in clientAddr ;
    socklen_t clientAddrLen = sizeof (clientAddr);
    char buffer [512];
    char * uuid = random_uuid();
    fprintf(stdout , "%s, %s\n" ,"Start", uuid);
    fprintf(stdout , "%s, %s\n" ,"Another", random_uuid());
    serverSock = socket(AF_INET, SOCK_STREAM , 0 );
    if (serverSock == -1 ) {
        fprintf (stderr, "%s\n" ,"open socket fail");
         return - 1;
    }
    // Make sure the port can be immediately re-used
    if (setsockopt(serverSock, SOL_SOCKET , SO_REUSEADDR, &val , sizeof(val )) < 0 ) {
        fprintf (stderr, "%s\n" ,"can't reuse socket");
        close (serverSock);
         return - 1;
    }
    
    memset(&serverAddr , 0 , sizeof (serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr .s_addr = htonl(INADDR_ANY );
    serverAddr.sin_port = htons(12345);
    if (bind( serverSock, (struct sockaddr *) & serverAddr, sizeof(serverAddr )) != 0 ) {
        fprintf (stderr, "%s\n" ,"can't bind socket");
        close (serverSock);
         return - 1;
    }
    // Listen to socket
    fprintf(stdout , "%s\n" ,"start listen port 12345");
    if (listen( serverSock, 1024) < 0 ) {
         return - 1;
    }

    while(1){
         //accept will wait for message coming
        fprintf (stdout, "%s\n" ,"wait accept");
         int clientSock = accept(serverSock , ( struct sockaddr *) &clientAddr, &clientAddrLen );

         int total_byte_cnt = 0;
         for (;;) {
             int byteCount = read(clientSock , buffer + total_byte_cnt, sizeof(buffer ) - total_byte_cnt - 1);
             if ( byteCount >= 0 ) {
                total_byte_cnt += byteCount;
                buffer [total_byte_cnt] = 0;
		/*
                fprintf (stdout, "[1] %d bytes read\n" , byteCount);
                fprintf (stdout, "%s\n" , "========================" );
                fprintf (stdout, "%s\n" , buffer);
                fprintf (stdout, "%s\n" , "========================" );
		*/
		//
		char *pch = strstr(buffer,"GET / HTTP/1.1");
  		char *Upgrade = extract_substring(buffer ,"Upgrade: ","\n");
  		char *Connection = extract_substring(buffer ,"Connection: ","\n");
		//Sec-WebSocket-Protocol should be "chat"
  		char *Sec_WebSocket_Protocol = extract_substring(buffer ,"Sec-WebSocket-Protocol: ","\n");
		if (pch == NULL) printf("pch is null");
		//printf("[%s]\n", Upgrade);
		//printf("[%s]\n", Connection);
		if ((pch == buffer) && ((strcmp(Upgrade,"websocket") == 0) || (strcmp(Upgrade,"Websocket") == 0)) && ((strcmp(Connection,"Upgrade") == 0) || (strcmp(Connection,"keep-alive, Upgrade") == 0)) ){
			handle_header(clientSock, buffer);
			handle_message_loop(clientSock);
}
                // 
		break;
             } else {
                 //fprintf (stdout, "%s\n" ,"[3] oh no");
                 break;
             }
         }
    }
    fprintf(stdout , "%s\n" ,"Finish");

    return 0;
}
コード例 #4
0
/*
 * match_complete
 * Try to complete a string as far as possible using the syntax.
 * 
 * Parameters
 * IN
 *   h       cligen handle
 *   string  Input string to match
 *   pt      Vector of commands (array of cligen object pointers (cg_obj)
 *   pt_max  Length of the pt array
 *   maxlen  Max length of string
 * OUT
 *   cvec      cligen variable vector containing vars/values pair for completion
 * RETURNS:
 *   -1 - Error 
 *   0  - No matches, no completions made
 *   1  - We have completed by adding characters at the end of "string"
 */
int 
match_complete(cligen_handle h, 
	       char         *string, 
	       parse_tree    pt, 
	       int           maxlen, 
	       cvec         *cvec)
{
    int level;
    int slen;
    int equal;
    int i, j, minmatch;
    cg_obj *co, *co1 = NULL;
    char *s;
    char *ss;
    pt_vec pt1;
    int nr;
    int matchlen = 0;
    int *matchv = NULL;
    int mv;
    int append = 0; /* Has appended characters */
    int retval = -1;

    /* ignore any leading whitespace */
    s = string;
    while ((strlen(s) > 0) && isblank(*s))
	    s++;
 again:
    matchlen = 0;
    if ((nr = match_pattern(h, s, pt, 0, 1, &pt1, &matchv, &matchlen, cvec, NULL)) < 0)
	goto done;
    if (nr==0){
	retval = 0;
	goto done; /*  No matches */
    }
    if ((level = command_levels(s)) < 0)
	goto done;
    extract_substring(s, level, &ss);
    slen = ss?strlen(ss):0;
    if (ss)
	free(ss);

    minmatch = slen;
    equal = 1;
    for (i=0; i<matchlen; i++){
	assert((mv = matchv[i])!=-1);
	co = pt1[mv];
	if (co == NULL){
	    retval = 0;
	    goto done;
	}
	if (co->co_type != CO_COMMAND)
	    continue;
	if (co1 == NULL){
	    minmatch = strlen(co->co_command);
	    co1 = co;
	}
	else{
	    if (strcmp(co1->co_command, co->co_command)==0)
		; /* equal */
	    else{
		equal = 0;
		for (j=0; j<MIN(strlen(co1->co_command), strlen(co->co_command)); j++)
		    if (co1->co_command[j] != co->co_command[j])
			break;
		minmatch = MIN(minmatch, j);
	    }
	}
    }
    if (co1 == NULL){
        retval = 0;
	goto done;
    }
    assert(strlen(string) + minmatch - slen < maxlen);
    strncat(string, &co1->co_command[slen], minmatch-slen);
    append = append || minmatch-slen;
    if (equal){ /* add space */
	string[strlen(string)+1] = '\0';
	string[strlen(string)] = co1?co1->co_delimiter:' ';
	level++;
	slen = 0;
	co1 = NULL;
	if (cligen_completion(h) == 1){
	    if (matchv)
		free(matchv);
	    matchv = NULL;
	    goto again;
	}
    }
    retval = append?1:0;
  done:
    if (matchv)
	free(matchv);
    return retval;
}
コード例 #5
0
/*
 * match_pattern_exact
 * INPUT:
 *   h          CLIgen handle
 *   string     Input string to match
 *   pt         CLIgen parse tree, vector of cligen objects.
 *   exact      Try to find an exact match. if 0 dont bother about errors.
 * OUTPUT:
 *   cvec      cligen variable vector containing vars/values pair for completion
 *   match_obj  Exact object to return
 * RETURNS:
 *  -1       Error
 *   0       No match
 *   1       Exactly one match
 *   2+      Multiple matches
 * 
 * Only if retval == 0 _AND> exact == 1 then cligen_nomatch() is set, otherwise not.
 */
int 
match_pattern_exact(cligen_handle h, 
		    char         *string, 
		    parse_tree    pt, 
		    int           exact,
		    cvec         *cvec,
		    cg_obj      **match_obj)
{
  pt_vec  res_pt;
  cg_obj *co;
  int     matchlen = 0;
  int     *matchv = NULL;
  int     i;
  int     ret;
  char   *reason = NULL;

  /* clear old errors */
  if (exact)
      cligen_nomatch_set(h, NULL); 
  if ((ret = match_pattern(h, string, pt, 1, 0, &res_pt, 
			   &matchv, &matchlen, cvec, &reason)) < 0)
      return -1;
  if (ret == 0) {
      if (exact){
	  if (reason != NULL){
	      cligen_nomatch_set(h, "%s", reason);
	      free(reason);
	  }
	  else
	      cligen_nomatch_set(h, "Unknown command");
      }
  }
  else{
      if (ret > 1){
	  /* Special case: command and exact-> use that */
	  int j;
	  char *string1;

	  extract_substring(string, command_levels(string), &string1);
	  for (j=0; j<ret; j++){
	      co = res_pt[matchv[j]];
	      if (co->co_type == CO_COMMAND && string1 && 
		  strcmp(string1, co->co_command)==0){
		  ret = 1;
		  matchv[0] = matchv[j];
		  break;
	      }
	  }
      }
  }
  if (ret != 1){
      if (matchv)
	  free(matchv);
      return ret;
  }
  /* Here we have an obj (res_pt[]) that is unique so far.
     We need to see if there is only one sibling to it. */
  co = res_pt[*matchv];
  free(matchv);
  matchv = NULL;
  /*
   * Special case: if matching object has a NULL child,
   * we match.
   */
  if (co->co_max == 0)
      goto done;
  for (i=0; i< co->co_max; i++)
      if (co->co_next[i] == NULL)
	  goto done;

#if 0
  {
  int variable = 0;
  /* The last object should be unique */
  while (co->co_max == 1){
      co = co->co_next[0];
      if (co->co_type == CO_VARIABLE && co->co_vtype != CGV_REST)
	  variable++;
  }
  if (co->co_max)
      return 0;
  if (variable) 
      return 0;
  }
#else
  if (exact)
      cligen_nomatch_set(h, "Incomplete command");
  return 0;
#endif
 done:
  if (match_obj)
      *match_obj = co;
  return 1;
}
コード例 #6
0
/*
 * match_pattern_node
 * Non-terminal. Need to match exact.
 * INPUT:
 *   h         CLIgen handle
 *   string0   Input string to match
 *   pt        Vector of commands (array of cligen object pointers (cg_obj)
 *   pt_max    Length of the pt array
 *   level     How many levels (words) into string0
 *   use_pref  Set this flag value if you want to use the preferences between
 *             matches. It is only when you want a final exact match (not 
 *             completion or show options) that you should set this.
 * RETURNS:
 *   The number of matches (0-n) in pt or -1 on error. See matchlen below.
 * OUTPUT:
 *   ptp       Returns the vector at the place of matching
 *   matchv    A vector of integers containing which 
 *   matchlen  Length of matchv. That is, # of matches and same as return 
 *              value (if 0-n)
 *   cvec      cligen variable vector containing vars/values pair for completion
 *   reason0   If retval = 0, this may be malloced to indicate reason for not
 *             matching variables, if given. Need to be free:d
 */
static int 
match_pattern_node(cligen_handle h, 
		   char *string0, 
		   parse_tree pt,
		   int level, 
		   int use_pref, 
		   int hide,
		   pt_vec *ptp, 
		   int *matchv[], 
		   int *matchlen,
		   cvec  *cvec,
		   char **reason0
		   )
{
    char *string = NULL;
    int i;
    int match;
    int matches = 0;
    int perfect = 0;
    int retval = -1;
    cg_obj *co, *co_match;
    cg_obj *co_orig;
    int rest_match = -1;
    int cmd_levels;
    int p;
    int preference = 0;
    int exact;
    char *reason;
    int findreason;
    parse_tree ptn={0,};     /* Expanded */
    cg_var *cv = NULL;

    co_match = NULL;
    if (level > command_levels(string0)){
	fprintf(stderr, "%s: level > command_level in %s\n",
		__FUNCTION__, string0);
	return -1;
    }
    /* If there are only variables in the list, then keep track of variable match errors */
    findreason = 0;
    if (reason0)
	for (i=0; i<pt.pt_len; i++){ 
	    if ((co = pt.pt_vec[i]) == NULL)
		continue;
	    if (co->co_type != CO_VARIABLE){
		findreason = 0;
		break;
	    }
	    findreason++;
	}
    extract_substring(string0, level, &string);
    for (i=0; i<pt.pt_len; i++){
	if ((co = pt.pt_vec[i]) == NULL)
	    continue;
	reason = NULL;
	if ((match = match_object(string, co, &exact, findreason?&reason:NULL)) < 0)
	    goto error;
	if (match){
	    assert(reason==NULL);
	    /* Special case to catch rest variable and space delimited
	       arguments after it */
	    if (co->co_type == CO_VARIABLE && co->co_vtype == CGV_REST)
		rest_match = i;
	    if (match_perfect(string, co)){
		if (!perfect){
		    matches = 0;
		    perfect = 1;
		}
	    }
	    else{
		if (perfect)
		    break;
 		if (1 || use_pref){
		    p = co_pref(co, exact);
		    if (p < preference)
			continue; /* ignore */
		    if (p > preference){
			preference = p;
			matches = 0; /* Start again at this level */
		    }
		}
	    }
	    co_match = co;
	    matches++;
	}
	/* match == 0, co type is variable and findreason, then reason is set 
	   this may not be the best preference, we just set the first
	*/
	if (reason){
	    if (*reason0 == NULL)
		*reason0 = reason;
	    reason = NULL;
	    findreason = 0;
	}
    } /* for */
    if (matches != 0 && reason0 && *reason0){
	    free(*reason0);
	    *reason0 = NULL;
	}

    if (matches != 1) {
#ifdef notneeded
	if (matches == 0){
	    cligen_nomatch_set(h, "Unrecognized command");
	}
	else
	    cligen_nomatch_set(h, "Ambigious command");
#endif
	retval = 0;
	goto quit;
    }
    assert(co_match);
    if ((cmd_levels = command_levels(string0)) < 0)
	goto error;

    /* co_orig is original object in case of expansion */
    co_orig = co_match->co_ref?co_match->co_ref: co_match;
    if (pt_expand_1(h, co_match, &co_match->co_pt) < 0) /* sub-tree expansion */
	goto error; 

    if (co_match->co_type == CO_VARIABLE){
	if ((cv = add_cov_to_cvec(co_match, string, cvec)) == NULL)
	    goto error;
    }
    else
	if (co_match->co_type == CO_COMMAND && co_orig->co_type == CO_VARIABLE)
	    if ((cv = add_cov_to_cvec(co_orig, string, cvec)) == NULL)
		goto error;
    if (pt_expand_2(h, &co_match->co_pt, cvec, &ptn, hide) < 0) /* expand/choice variables */
	goto error;
    if (level+1 == cmd_levels)
	retval = match_pattern_terminal(h,
					string0, ptn, 
					level+1, use_pref,
					ptp, matchv, matchlen, reason0);
    else
	retval = match_pattern_node(h, 
				    string0, ptn,
				    level+1, use_pref, hide,
				    ptp, matchv, matchlen, cvec, reason0);

    if (pt_expand_add(co_orig, ptn) < 0) /* add expanded ptn to orig parsetree */
	goto error;
    if (co_match->co_type == CO_COMMAND && co_orig->co_type == CO_VARIABLE)
	if (co_value_set(co_orig, co_match->co_command) < 0)
	    goto error;


    /* Cleanup made on top-level */
    
    /* 
     * Special case: we have matched a REST variable (anything) and
     * there is more text have this word, then we can match REST
     */
    if (retval == 0 && rest_match != -1){
	retval = 1;
	if (*matchlen < 1){
	    *matchlen = 1;
	    if ((*matchv = realloc(*matchv, (*matchlen)*sizeof(int))) == NULL){
		fprintf(stderr, "%s: realloc: %s\n", __FUNCTION__, strerror(errno));
		return -1;
	    }
	}
	else
	    *matchlen = 1;
	*ptp = pt.pt_vec;
	(*matchv)[0] = rest_match;
    }
  quit:
    if (cv){ /* cv may be stale */
	cv = cvec_i(cvec, cvec_len(cvec)-1);
	cv_reset(cv);
	cvec_del(cvec, cv);
    }
    /* Only the last level may have multiple matches */
    if (string)
	free(string);
    return retval;
  error:
    retval = -1;
    goto quit;
}
コード例 #7
0
/*
 * match_pattern_terminal
 * This is the last level. Multiple matches may be OK and is used
 * for completion.
 * We must have a preference when matching when it matches a command
 * and some variables.
 * The preference is:
 *  command > ipv4,mac > string > rest
 * return in matchvector which element match (their index)
 * and how many that match.
 * return value is the number of matches on return (also returned in matchlen)
 * index is the index of the first such match.
 * INPUT:
 *   h         CLIgen handle
 *   string0   Input string to match
 *   pt        Vector of commands (array of cligen object pointers (cg_obj)
 *   pt_max    Length of the pt array
 *   level     How many levels (words) into string0
 *   use_pref  Set this flag value if you want to use the preferences between
 *             matches. It is only when you want a final exact match (not 
 *             completion or show options) that you should set this.
 * RETURNS:
 *   The number of matches (0-n) in pt or -1 on error. See matchlen below.
 *
 * OUTPUT:
 *   ptp       Returns the vector at the place of matching
 *   matchv    A vector of integers containing which 
 *   matchlen  Length of matchv. That is, # of matches and same as return 
 *              value (if 0-n)
 *   reason0   If retval = 0, this may be malloced to indicate reason for not
 *             matching variables, if given. Neeed to be free:d
 */
static int 
match_pattern_terminal(cligen_handle h, 
		       char *string0, parse_tree pt,
		       int level, int use_pref,
		       pt_vec *ptp, 
		       int *matchv[], int *matchlen,
		       char **reason0
		       )
{
    char   *string;
    int     i;
    int     match;
    int     matches = 0;
    int     preference = 0;
    int     p;
    cg_obj *co, *co_match;
    cg_obj *co_orig;
    int     exact;
    char   *reason;
    int     findreason;

    co_match = NULL;
    if (level > command_levels(string0)){
	fprintf(stderr, "%s: level > command_level in %s\n",
		__FUNCTION__, string0);
	return -1;
    }
    /* If there are only variables in the list, then keep track of variable match errors */
    findreason = 0;
    if (reason0)
	for (i=0; i<pt.pt_len; i++){ 
	    if ((co = pt.pt_vec[i]) == NULL)
		continue;
	    if (co->co_type != CO_VARIABLE){
		findreason = 0;
		break;
	    }
	    findreason++;
	}
    extract_substring(string0, level, &string);
    for (i=0; i<pt.pt_len; i++){
	if ((co = pt.pt_vec[i]) == NULL)
	    continue;
	reason = NULL;
	if ((match = match_object(string, co, &exact, findreason?&reason:NULL)) < 0)
	    goto error;
	if (match){
	    assert(reason==NULL);
	    if (use_pref){
		p = co_pref(co, exact);
		if (p < preference)
		    continue; /* ignore */
		if (p > preference){
		    preference = p;
		    matches = 0; /* Start again at this level */
		}
	    }
	    *matchlen = *matchlen + 1;
	    if ((*matchv = realloc(*matchv, (*matchlen)*sizeof(int))) == NULL){
		fprintf(stderr, "%s: realloc: %s\n", __FUNCTION__, strerror(errno));
		return -1;
	    }
	    co_match = co;
	    (*matchv)[matches++] = i; 
	}
	/* match == 0, co type is variable and findreason, then reason is set 
	   this may not be the best preference, we just set the first
	 */
	if (reason){
	    if (*reason0 == NULL)
		*reason0 = reason;
	    reason = NULL;
	    findreason = 0;
	}
    }

    if (matches){
	*ptp = pt.pt_vec;
	if (reason0 && *reason0){
	    free(*reason0);
	    *reason0 = NULL;
	}
	if (matches == 1){
	    assert(co_match);

	    co_orig = co_match->co_ref?co_match->co_ref: co_match;
	    if (co_match->co_type == CO_COMMAND && co_orig->co_type == CO_VARIABLE){
		if (co_value_set(co_orig, co_match->co_command) < 0)
		    goto error;
	    }
	    /* Cleanup made on top-level */
	}
    }
    *matchlen = matches;
    if (string)
	free(string);
    return matches;
  error:
    if (string)
	free(string);
    return -1;
}