int client_init(int argc, char *const argv[]) { /*配置 1. 默认设置 2. 配置文件 * 3. 命令参数 */ /*默认设置*/ cli_conf.recv_port = DEFAULT_RCV_PORT; cli_conf.mgroup = DEFAULT_MGROUP; cli_conf.player = DEFAULT_PLAYER; struct option cli_option[] = { { "port", required_argument, NULL, 'p'}, { "player", required_argument, NULL, 'P'}, { "mgroup", required_argument, NULL, 'm'}, { "help", no_argument, NULL, 'h'}, }; /*命令行参数*/ int c; while ((c = getopt_long(argc, argv, "p:P:m:h", cli_option, NULL)) != -1) { switch (c) { case 'p': cli_conf.recv_port = optarg; break; case 'P': cli_conf.player = optarg; break; case 'm': cli_conf.mgroup = optarg; break; case 'h': case '?': usage(argv[0]); exit(0); break; default: fprintf(stderr, "ERROR: unkown opt '%c'\n", c); exit(-1); break; } } #ifdef _DEBUG printf("port: %s\n", cli_conf.recv_port); printf("mgroup: %s\n", cli_conf.mgroup); printf("player: %s\n", cli_conf.player); #endif /*网络连接*/ int sock_fd; sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if (sock_fd < 0) { perror("socket"); exit(-1); } struct sockaddr_in l_addr; socklen_t addr_len = sizeof(l_addr); int sw_loop_multicast = 1; //加入到组播域 struct ip_mreqn mreq; bzero(&mreq, sizeof(mreq)); inet_pton(AF_INET, cli_conf.mgroup, &mreq.imr_multiaddr); inet_pton(AF_INET, "0.0.0.0", &mreq.imr_address); mreq.imr_ifindex = if_nametoindex("eth0"); /*加入指定组播组*/ CHK_EXIT(setsockopt(sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))); /*可以收到本地发送的组播*/ CHK_EXIT(setsockopt(sock_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &sw_loop_multicast, sizeof(sw_loop_multicast))); bzero(&l_addr, sizeof(l_addr)); l_addr.sin_family = AF_INET; l_addr.sin_port = htons(atoi(cli_conf.recv_port)); inet_pton(AF_INET, "0.0.0.0", &l_addr.sin_addr); CHK_EXIT(bind(sock_fd, (const struct sockaddr *)&l_addr, addr_len)); DEBUG("bind ok, sock_fd: %d, listen: %s\n", sock_fd, cli_conf.recv_port); return sock_fd; }
/******************************************************************** * FUNCTION consume_yang_arg * * Parse the next N tokens as an argument-stmt * Fill in the arg anf argel fields in the ext_template_t struct * * Error messages are printed by this function!! * Do not duplicate error messages upon error return * * Current token is the 'argument' keyword * * INPUTS: * tkc == token chain * mod == module in progress * ext == extension template in progress * argdone == address of duplicate entry error flag * * OUTPUTS: * *argdone == TRUE upon exit * * RETURNS: * status of the operation *********************************************************************/ static status_t consume_yang_arg (tk_chain_t *tkc, ncx_module_t *mod, ext_template_t *ext, boolean *argdone) { const xmlChar *val; const char *expstr; xmlChar *errstr; dlq_hdr_t errQ; tk_type_t tktyp; boolean done, yinel, save, errsave; status_t res, retres; #ifdef DEBUG if (!tkc || !mod) { return SET_ERROR(ERR_INTERNAL_PTR); } #endif val = NULL; expstr = NULL; done = FALSE; yinel = FALSE; save = TRUE; res = NO_ERR; retres = NO_ERR; dlq_createSQue(&errQ); /* check duplicate entry error first */ if (*argdone) { retres = ERR_NCX_ENTRY_EXISTS; ncx_print_errormsg(tkc, mod, retres); save = FALSE; } else { *argdone = TRUE; } /* Get the mandatory argument name */ if (save) { res = yang_consume_id_string(tkc, mod, &ext->arg); } else { errstr = NULL; res = yang_consume_id_string(tkc, mod, &errstr); if (errstr) { m__free(errstr); } } CHK_EXIT(res, retres); /* Get the starting left brace for the sub-clauses * or a semi-colon to end the extension-stmt */ res = TK_ADV(tkc); if (res != NO_ERR) { ncx_print_errormsg(tkc, mod, res); return res; } switch (TK_CUR_TYP(tkc)) { case TK_TT_SEMICOL: done = TRUE; break; case TK_TT_LBRACE: break; default: retres = ERR_NCX_WRONG_TKTYPE; expstr = "semi-colon or left brace"; ncx_mod_exp_err(tkc, mod, retres, expstr); done = TRUE; } /* get the extension statements and any appinfo extensions */ while (!done) { /* get the next token */ res = TK_ADV(tkc); if (res != NO_ERR) { ncx_print_errormsg(tkc, mod, res); return res; } tktyp = TK_CUR_TYP(tkc); val = TK_CUR_VAL(tkc); /* check the current token type */ switch (tktyp) { case TK_TT_NONE: res = ERR_NCX_EOF; ncx_print_errormsg(tkc, mod, res); return res; case TK_TT_MSTRING: /* vendor-specific clause found instead */ if (save) { res = ncx_consume_appinfo(tkc, mod, &ext->appinfoQ); } else { res = ncx_consume_appinfo(tkc, mod, &errQ); ncx_clean_appinfoQ(&errQ); } CHK_EXIT(res, retres); continue; case TK_TT_RBRACE: done = TRUE; continue; case TK_TT_TSTRING: break; /* YANG clause assumed */ default: retres = ERR_NCX_WRONG_TKTYPE; ncx_mod_exp_err(tkc, mod, retres, expstr); continue; } /* Got a token string so check the value */ if (!xml_strcmp(val, YANG_K_YIN_ELEMENT)) { if (save) { res = yang_consume_boolean(tkc, mod, &ext->argel, &yinel, &ext->appinfoQ); } else { res = yang_consume_boolean(tkc, mod, &errsave, NULL, NULL); } } else { res = ERR_NCX_WRONG_TKVAL; ncx_mod_exp_err(tkc, mod, res, expstr); } CHK_EXIT(res, retres); } return retres; } /* consume_yang_arg */