dav_error *dav_repos_deliver_principal_search_property_set(request_rec * r, const dav_resource * resource, const apr_xml_doc * doc, ap_filter_t * output) { apr_bucket_brigade *bb; apr_pool_t *pool = resource->pool; TRACE(); bb = apr_brigade_create(pool, output->c->bucket_alloc); send_xml(bb, output, "<D:principal-search-property-set xmlns:D=\"DAV:\">" DEBUG_CR); send_xml(bb, output, "<D:principal-search-property>" DEBUG_CR); send_xml(bb, output, "<D:prop>" DEBUG_CR); send_xml(bb, output, "<D:displayname/>" DEBUG_CR); send_xml(bb, output, "</D:prop>" DEBUG_CR); send_xml(bb, output, "<D:description xml:lang=\"en\">Full name</D:description>" DEBUG_CR); send_xml(bb, output, "</D:principal-search-property>" DEBUG_CR); send_xml(bb, output, "</D:principal-search-property-set>" DEBUG_CR); ap_fflush(output, bb); return NULL; }
int message_parsing(int server_socket,int *exit_num,MYSQL mysql_conn) { char command[5][10]= {"ll","exit","vim","open","close"}; xmlChar *xmlbuf; char *buffer=(char *)malloc(256*sizeof(char)); memset(buffer,'\0',256); int response_type=-1; //响应类型 xmlDocPtr doc; xmlNodePtr curNode; //定义结点指针(你需要它为了在各个结点间移动) if((xmlbuf=recv_xml(server_socket))!=NULL) { /* if(modify_num==1) * * { * * printf("接收%s成功!\n",xmlbuf); ** }*/ // doc=xmlchar_to_doc(xmlbuf); doc = xmlReadMemory(xmlbuf,strlen(xmlbuf)+1,NULL,"utf-8",XML_PARSE_RECOVER ); // doc = xmlParseMemory(xmlbuf,strlen(xmlbuf)+1); free(xmlbuf); curNode = xmlDocGetRootElement(doc); //确定文档根元素 if(NULL == curNode) { xmlFreeDoc(doc); return -1; } if(xmlStrcmp(curNode->name, (const xmlChar *)"message")==0) response_type=0; if(xmlStrcmp(curNode->name, (const xmlChar *)"command")==0) response_type=1; } if(response_type==0) { int local_socket; if(xmlHasProp(curNode,(xmlChar *)"local_socket")) //判断结点curNode是否具有属性attribute { xmlChar *local_socket_tmp; local_socket_tmp= xmlGetProp(curNode, "local_socket"); //获取属性值 int i=0; while(local_socket_tmp[i]!='\0') { local_socket=local_socket*10+local_socket_tmp[i]-'0'; i++; } xmlFree(local_socket_tmp); //释放内存 } xmlSetProp(curNode,(const xmlChar *)"local_socket", (xmlChar *)"no"); int buffersize; xmlDocDumpFormatMemory(doc, &xmlbuf, &buffersize, 1); int num=0; char *ptr=xmlbuf; while(*ptr) { if(*ptr=='<') num++; if(num==2) break; ptr++; } ptr[strlen(ptr)-1]='\0'; fd_set wtfds; struct timeval timeout= {3,0}; //select等待3秒,3秒轮询,要非阻塞就置 FD_ZERO(&wtfds); //每次循环都要清空集合,否则不能检测描述符变化 FD_SET(local_socket,&wtfds); //添加描述符 select(local_socket+1,NULL,&wtfds,NULL,&timeout); //select使用 if(FD_ISSET(local_socket,&wtfds)) //测试文件是否可写 { if(write_xml(ptr,local_socket)==0) { if(modify_num==1) { printf("发送%s成功!\n",xmlbuf); } xmlFree(xmlbuf); } else { if(modify_num==1) { printf("发送%s失败!\n",xmlbuf); } xmlFree(xmlbuf); } } } if(response_type==1) { xmlChar *key; key = xmlNodeListGetString(doc,curNode->xmlChildrenNode, 1); //获取文本结点的>文本,需用其子结点 sprintf(buffer,"%s",key); xmlFree(key); char *jid=(char *)malloc(50*sizeof(char)); memset(jid,'\0',50); char *buffer_tmp=(char *)malloc(256*sizeof(char)); memset(buffer_tmp,'\0',256); int i=0; while(buffer[i]!=' '&&buffer[i]!='\0') { buffer_tmp[i]=buffer[i]; i++; } buffer_tmp[i]='\0'; int j=0; while(buffer[i]!='\0') { if(buffer[i]==' ') { i++; continue; } jid[j]=buffer[i]; i++; j++; } jid[j]='\0'; int num=-1; for(int i=0; i<5; i++) if(strcmp(buffer_tmp,command[i])==0) { num=i; break; } free(buffer_tmp); switch(num) { case 0: client_ll(server_socket,mysql_conn); break; case 1: *exit_num=1; break; case 3: if(remote_login(server_socket,jid,mysql_conn)==-1) return -1; break; case 4: break; default: memset(buffer,'\0',256); sprintf(buffer,"%s","命令不存在!"); xmlChar *xmlbuf_head="<message>"; xmlChar *xmlbuf_tail="</message>"; xmlChar *xmlbuf; xmlbuf=xmlchar_construct(xmlbuf_head,buffer,xmlbuf_tail); if(send_xml(xmlbuf,server_socket)==0) { if(modify_num==1) { printf("发送%s成功!\n",xmlbuf); } xmlFree(xmlbuf); } else { if(modify_num==1) { printf("发送%s失败!\n",xmlbuf); } xmlFree(xmlbuf); return -1; } } free(jid); } free(buffer); xmlFreeDoc(doc); return 0; }
/** * Callback function used to answer clients's connection (MHD_AccessHandlerCallback) * * @param cls Custom value selected at callback registration time, used to initialize the done flag * * @param connection The client connection * * @param url The url on which the client made its request * * @param method The http method with which the client made its request (Only GET and PUT supported) * * @param version The HTTP version string (i.e. HTTP/1.1) * * @param upload_data Data beeing uploaded when receiving PUT * * @param upload_data_size Size of the data beeing uploaded when receiving PUT * * @param con_cls reference to a pointer, initially set to NULL, that this callback can set to some * address and that will be preserved by MHD for future calls for this request * * @return MHD_YES to pursue the request handling, MHD_NO in case of error with * the request, return value of the send_* functions otherwise */ int answer_to_connection ( void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls ) { Service *requested_service; char *xmlbuff = NULL; int ret; int *done = cls; static int aptr; const char *get_arg; struct sockaddr *addr; addr = MHD_get_connection_info (connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS)->client_addr; char IP[16]; inet_ntop(addr->sa_family,addr->sa_data + 2, IP, 16); if( 0 == strcmp (method, MHD_HTTP_METHOD_GET) ) { if ( &aptr != *con_cls ) { /* do never respond on first call */ *con_cls = &aptr; return MHD_YES; } *con_cls = NULL; if( strcmp(url,"/log") == 0 ) { ret = subscribe_to_log_events(connection, con_cls, HPD_IS_UNSECURE_CONNECTION); Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL); return ret; } else if( strcmp(url,"/events") == 0 ) { ret = set_up_server_sent_event_connection( connection, HPD_IS_UNSECURE_CONNECTION ); if( ret == MHD_HTTP_NOT_FOUND ) { Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL); return send_error (connection, MHD_HTTP_NOT_FOUND); } else { Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL); return ret; } } else if( strcmp(url,"/devices") == 0 ) { xmlbuff = get_xml_device_list(); ret = send_xml (connection, xmlbuff); Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL); return ret; } else if( ( requested_service = matching_service (service_head, url) ) != NULL ) { get_arg = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "x"); if( get_arg != NULL ) { if( strcmp(get_arg, "1") == 0 ) { pthread_mutex_lock(requested_service->mutex); xmlbuff = extract_service_xml(requested_service); pthread_mutex_unlock(requested_service->mutex); ret = send_xml (connection, xmlbuff); Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, "x=1"); return ret; } } get_arg = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "p"); if( get_arg != NULL ) { if( strcmp(get_arg, "1") == 0 ) { ret = subscribe_to_service(connection, requested_service, con_cls, HPD_IS_UNSECURE_CONNECTION); Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, "p=1"); return ret; } } pthread_mutex_lock( requested_service->mutex ); ret = requested_service-> get_function( requested_service, requested_service->get_function_buffer, MHD_MAX_BUFFER_SIZE); if( ret != 0 ) requested_service->get_function_buffer[ret] = '\0'; else { pthread_mutex_unlock( requested_service->mutex ); ret = send_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR); Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL); return ret; } xmlbuff = get_xml_value (requested_service->get_function_buffer); pthread_mutex_unlock(requested_service->mutex); ret = send_xml(connection, xmlbuff); Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL); return ret; } else { ret = send_error(connection, MHD_HTTP_NOT_FOUND); Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL); return ret; } } else if( 0 == strcmp(method, MHD_HTTP_METHOD_PUT) ) { if( ( *con_cls ) == NULL ) { if( *upload_data_size == 0 ) { return MHD_YES; /* not ready yet */ } /* Add a space for a '/0' in order to clear the end of the XML */ char *put_data_temp = (char*)malloc((*upload_data_size)*sizeof(char)+1); memcpy(put_data_temp, upload_data, *upload_data_size); put_data_temp[*upload_data_size]='\0'; *con_cls = put_data_temp; *upload_data_size = 0; return MHD_YES; } else { if( ( requested_service = matching_service (service_head, url) ) !=NULL ) { pthread_mutex_lock(requested_service->mutex); if( requested_service->put_function != NULL && *con_cls != NULL ) { char* _value = get_value_from_xml_value (*con_cls); if(_value == NULL) { pthread_mutex_unlock(requested_service->mutex); ret = send_error (connection, MHD_HTTP_BAD_REQUEST); Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL); return ret; } free(*con_cls); ret = requested_service-> put_function( requested_service, requested_service->get_function_buffer, MHD_MAX_BUFFER_SIZE, _value ); free(_value); if( ret != 0 ) requested_service->get_function_buffer[ret] = '\0'; else { pthread_mutex_unlock( requested_service->mutex ); ret = send_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR); Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL); return ret; } xmlbuff = get_xml_value (requested_service->get_function_buffer); pthread_mutex_unlock(requested_service->mutex); send_event_of_value_change (requested_service, requested_service->get_function_buffer); ret = send_xml (connection, xmlbuff); Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL); return ret; } else { pthread_mutex_unlock(requested_service->mutex); ret = send_error(connection, MHD_HTTP_BAD_REQUEST); Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL); return ret; } } else return send_error (connection, MHD_HTTP_NOT_FOUND); } } return MHD_NO; }
int client_sasl(int client_socket,char *client_name_tmp) { xmlDocPtr doc; xmlChar *xmlbuf; int stream_on=0; xmlbuf="<?xml version=\"1.0\"?>\n<stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" to=\"im_server.com\" version=\"1.0\">"; if(send_xml(xmlbuf,client_socket)==0) { if(modify_num==1) { printf("发送%s成功!\n",xmlbuf); } } else { if(modify_num==1) { printf("发送%s成功!\n",xmlbuf); } return -1; } if((xmlbuf=recv_xml(client_socket))!=NULL) { if(modify_num==1) { printf("发送%s成功!\n",xmlbuf); } free(xmlbuf); stream_on=3; } else { if(modify_num==1) { printf("发送%s!失败\n",xmlbuf); } return -1; } while(stream_on) { if((xmlbuf=recv_xml(client_socket))!=NULL) { printf("接收%s成功!\n",xmlbuf); } else { if(modify_num==1) { printf("接收%s失败!\n",xmlbuf); } continue; } xmlDocPtr doc; doc=xmlchar_to_doc(xmlbuf); free(xmlbuf); xmlNodePtr curNode; //定义结点指针(你需要它为了在各个结点间移动) curNode = xmlDocGetRootElement(doc); //确定文档根元素 if(NULL == curNode) { xmlFreeDoc(doc); return -1; } curNode = curNode->xmlChildrenNode; //子节点集是链表 xmlNodePtr propNodePtr = curNode; int num_t=0; while(curNode != NULL) { //取出节点中的内容 if((!xmlStrcmp(curNode->name, (const xmlChar *)"features"))) { curNode = curNode->xmlChildrenNode; //子节点集是链表 while(curNode != NULL) { if((!xmlStrcmp(curNode->name, (const xmlChar *)"mechanisms"))) { num_t=1; break; } else { curNode=curNode->next; } } break; } else { if(!xmlStrcmp(curNode->name, (const xmlChar *)"success")) { stream_on=0; return 0; } else { if(!xmlStrcmp(curNode->name, (const xmlChar *)"challenge")) { stream_on--; num_t=2; printf("密码验证失败,请重试!\n"); break; } else { if(!xmlStrcmp(curNode->name, (const xmlChar *)"failure")) { num_t=1; stream_on--; printf("认证失败,请重试!\n"); break; } else { curNode=curNode->next; } } } } } xmlFreeDoc(doc); if(stream_on==0) return -1; if(num_t==1) { char *client_name=(char*)malloc(20*sizeof(char)); char *client_name_p=client_name; printf("请输入用户名:\n"); fgets(client_name_p,20,stdin); client_name[strlen(client_name)-1]='\0'; printf("所输入的用户名为:%s\n",client_name); char *client_password=(char*)malloc(20*sizeof(char)); char *client_password_p=client_password; printf("请输入密码:\n"); fgets(client_password_p,20,stdin); client_password[strlen(client_password)-1]='\0'; char *md5_buf=MD5_sign(client_password,strlen(client_password)); char *send_buf=(char *)malloc((strlen(client_name)+34)*sizeof(char)); memset(send_buf,'\0',strlen(client_name)+34); strcat(send_buf,client_name); send_buf[strlen(client_name)]='\n'; send_buf[strlen(client_name)+1]='\0'; strcat(send_buf,md5_buf); xmlChar *xmlbuf_head="<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"DIGEST-MD5\">"; xmlChar *xmlbuf_tail="</auth>"; xmlbuf=xmlchar_construct(xmlbuf_head,send_buf,xmlbuf_tail); if(send_xml(xmlbuf,client_socket)==0) { if(modify_num==1) { printf("发送%s成功!\n",xmlbuf); } xmlFree(xmlbuf); } else { if(modify_num==1) { printf("发送%s失败!\n",xmlbuf); } xmlFree(xmlbuf); return -1; } char *row_name_p=client_name; int i=0; while(*row_name_p) { client_name_tmp[i]=*row_name_p; row_name_p++; i++; } client_name_tmp[i]='\0'; free(send_buf); free(client_name); free(client_password); } if(num_t==2) { char *client_password=(char*)malloc(20*sizeof(char)); printf("请输入密码:\n"); fgets(client_password,20,stdin); client_password[strlen(client_password)-1]='\0'; char *md5_buf=(char *)malloc(33*sizeof(char)); md5_buf=MD5_sign(client_password,strlen(client_password)); xmlChar *xmlbuf_head="<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"DIGEST-MD5\">"; xmlChar *xmlbuf_tail="</response>"; xmlbuf=xmlchar_construct(xmlbuf_head,md5_buf,xmlbuf_tail); if(send_xml(xmlbuf,client_socket)==0) { if(modify_num==1) { printf("发送%s成功!\n",xmlbuf); } xmlFree(xmlbuf); continue; } else { if(modify_num==1) { printf("发送%s失败!\n",xmlbuf); } xmlFree(xmlbuf); return -1; } free(client_password); free(md5_buf); } } return 0; }
dav_error *dav_repos_deliver_principal_property_search(request_rec * r, const dav_resource * resource, const apr_xml_doc * doc, ap_filter_t * output) { /* this buffers the output for a bit and is automatically flushed, at appropriate times, by the Apache filter system. */ apr_bucket_brigade *bb; apr_pool_t *pool = resource->pool; dav_repos_db *db = resource->info->db; dav_repos_resource *db_r = (dav_repos_resource *) resource->info->db_r; apr_xml_elem *principal_property_search; apr_xml_elem *elem; apr_xml_elem *prop; apr_xml_elem *props; apr_xml_elem *match; int flag; TRACE(); principal_property_search = dav_find_child(doc->root, "principal-property-search"); props = dav_find_child(doc->root, "prop"); sabridge_get_collection_children(db, db_r, 1, "read", NULL, NULL, NULL); bb = apr_brigade_create(pool, output->c->bucket_alloc); r->status = HTTP_MULTI_STATUS; send_xml(bb, output, "<D:multistatus xmlns:D=\"DAV:\">" DEBUG_CR); while (db_r != NULL) { flag = 1; for (elem = principal_property_search->first_child; elem && flag; elem = elem->next) { if (!strcmp(elem->name, "property-search")) { prop = dav_find_child(elem, "prop"); match = dav_find_child(elem, "match"); dav_repos_build_lpr_hash(db_r); const char *val = apr_hash_get(db_r->lpr_hash, prop->first_child->name, APR_HASH_KEY_STRING); if (!strstr(val, match->first_cdata.first->text)) flag = 0; } } if (flag) { send_xml(bb, output, "<D:response>"); send_xml(bb, output, dav_repos_mk_href(pool, db_r->uri)); send_xml(bb, output, "<D:propstat>"); send_xml(bb, output, "<D:prop>"); for (props = props->first_child; props; props = props->next) { const char *val; val = apr_hash_get(db_r->lpr_hash, props->name, APR_HASH_KEY_STRING); const char *str = apr_psprintf(pool, "<D:%s>%s</D:%s>" DEBUG_CR, props->name, apr_xml_quote_string(pool, val, 0), props->name); send_xml(bb, output, str); } send_xml(bb, output, "</D:prop>"); send_xml(bb, output, "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR); send_xml(bb, output, "</D:propstat>"); send_xml(bb, output, "</D:response>"); } db_r = db_r->next; } send_xml(bb, output, "</D:multistatus>"); /* flush the contents of the brigade */ ap_fflush(output, bb); return NULL; }
dav_error *dav_repos_deliver_principal_match(request_rec * r, const dav_resource * resource, const apr_xml_doc * doc, ap_filter_t * output) { /* this buffers the output for a bit and is automatically flushed, at appropriate times, by the Apache filter system. */ apr_bucket_brigade *bb; apr_pool_t *pool = resource->pool; dav_repos_db *db = resource->info->db; dav_repos_resource *db_r = (dav_repos_resource *) resource->info->db_r; apr_xml_elem *principal_properties; char *req_username = r->user; long principal_id; dav_error *err = NULL; TRACE(); if (!req_username) req_username = "******"; if((err = dbms_get_principal_id_from_name(pool, db, req_username, &principal_id))) { return err; } principal_properties = dav_find_child(doc->root, "principal-property"); sabridge_get_collection_children(db, db_r, DAV_INFINITY, "read", NULL, NULL, NULL); bb = apr_brigade_create(pool, output->c->bucket_alloc); r->status = HTTP_MULTI_STATUS; send_xml(bb, output, "<D:multistatus xmlns:D=\"DAV:\">" DEBUG_CR); while ((db_r = db_r->next)) { // Currently supporting DAV:owner only if ((principal_properties && !strcmp(principal_properties->name, "owner") && db_r->owner_id == principal_id) || (!principal_properties && // Found no principal_properties !strcmp(db_r->displayname, req_username))) { send_xml(bb, output, "<D:response>"); const char *str = apr_psprintf(pool, "<D:href>%s</D:href>" DEBUG_CR, apr_xml_quote_string(pool, db_r->uri, 0)); send_xml(bb, output, str); send_xml(bb, output, "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR); send_xml(bb, output, "</D:response>"); } } send_xml(bb, output, "</D:multistatus>"); /* flush the contents of the brigade */ ap_fflush(output, bb); return NULL; }
dav_error *dav_repos_deliver_acl_principal_prop_set(request_rec * r, const dav_resource * resource, const apr_xml_doc * doc, ap_filter_t * output) { /* this buffers the output for a bit and is automatically flushed, at appropriate times, by the Apache filter system. */ apr_bucket_brigade *bb; apr_pool_t *pool = resource->pool; dav_repos_db *db = resource->info->db; dav_repos_resource *db_r = (dav_repos_resource *) resource->info->db_r; apr_xml_elem *props; dav_repos_resource *principals = NULL; TRACE(); props = dav_find_child(doc->root, "prop"); dbms_get_principals(db, pool, db_r, principals); bb = apr_brigade_create(pool, output->c->bucket_alloc); r->status = HTTP_MULTI_STATUS; send_xml(bb, output, "<D:multistatus xmlns:D=\"DAV:\">" DEBUG_CR); while (principals != NULL) { sabridge_get_property(db, principals); dav_repos_build_lpr_hash(principals); send_xml(bb, output, "<D:response>"); send_xml(bb, output, dav_repos_mk_href(pool, principals->uri)); send_xml(bb, output, "<D:propstat>"); send_xml(bb, output, "<D:prop>"); for (props = props->first_child; props; props = props->next) { const char *val; val = apr_hash_get(principals->lpr_hash, props->name, APR_HASH_KEY_STRING); const char *str = apr_psprintf(pool, "<D:%s>%s</D:%s>" DEBUG_CR, props->name, apr_xml_quote_string(pool, val, 0), props->name); send_xml(bb, output, str); } send_xml(bb, output, "</D:prop>"); send_xml(bb, output, "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR); send_xml(bb, output, "</D:propstat>"); send_xml(bb, output, "</D:response>"); principals = principals->next; } send_xml(bb, output, "</D:multistatus>"); /* flush the contents of the brigade */ ap_fflush(output, bb); return NULL; }
int client_tls(int client_socket) { xmlDocPtr doc; xmlChar *xmlbuf; int stream_on=0; xmlbuf="<?xml version=\"1.0\"?>\n<stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" to=\"im_server.com\" version=\"1.0\">"; if(send_xml(xmlbuf,client_socket)==0) { if(modify_num==1) { printf("发送%s成功!\n",xmlbuf); } } else { if(modify_num==1) { printf("发送%s成功!\n",xmlbuf); } return -1; } if((xmlbuf=recv_xml(client_socket))!=NULL) { if(modify_num==1) { printf("接收%s成功!\n",xmlbuf); } free(xmlbuf); stream_on=1; } else { if(modify_num==1) { printf("接收%s!失败\n",xmlbuf); } return -1; } while(stream_on) { if((xmlbuf=recv_xml(client_socket))!=NULL) { if(modify_num==1) { printf("接收%s成功!\n",xmlbuf); } } else { if(modify_num==1) { printf("接收%s失败!\n",xmlbuf); } continue; } doc=xmlchar_to_doc(xmlbuf); free(xmlbuf); xmlNodePtr curNode; //定义结点指针(你需要它为了在各个结点间移动) curNode = xmlDocGetRootElement(doc); //确定文档根元素 if(NULL == curNode) { xmlFreeDoc(doc); return -1; } curNode = curNode->xmlChildrenNode; //子节点集是链表 xmlNodePtr propNodePtr = curNode; int num_t=0; while(curNode != NULL) { //取出节点中的内容 if((!xmlStrcmp(curNode->name, (const xmlChar *)"features"))) { curNode = curNode->xmlChildrenNode; //子节点集是链表 while(curNode != NULL) { if((!xmlStrcmp(curNode->name, (const xmlChar *)"starttls"))) { num_t=1; break; } else { curNode=curNode->next; } } break; } else { if(!xmlStrcmp(curNode->name, (const xmlChar *)"proceed")) { stream_on=0; break; } curNode=curNode->next; } } xmlFreeDoc(doc); if(num_t==1) { xmlbuf="<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>"; if(send_xml(xmlbuf,client_socket)==0) { if(modify_num==1) { printf("发送%s成功!\n",xmlbuf); } continue; } else { if(modify_num==1) { printf("发送%s失败!\n",xmlbuf); } return -1; } } } return 0; }