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