static iz_res_t help_parse(struct iz_cmd *cmd) { const struct iz_cmd_desc *desc; if (cmd->argc > 2) { printf("Too many arguments!\n"); return IZ_STOP_ERR; } else if (cmd->argc == 1) { iz_help("iz"); return IZ_STOP_OK; } /* Search for command help */ desc = get_cmd(cmd->argv[1]); if (!desc) { printf("Unknown command %s!\n", cmd->argv[1]); return IZ_STOP_ERR; } else { printf("%s %s\n\t%s\n\n", desc->name, desc->usage, desc->doc); } return IZ_STOP_OK; }
int main(int argc, char **argv) { int c; int i; int family; int group; struct nl_sock *nl; struct nl_msg *msg; char *dummy = NULL; /* Currently processed command info */ struct iz_cmd cmd; /* Parse options */ while (1) { #ifdef HAVE_GETOPT_LONG int opt_idx = -1; c = getopt_long(argc, argv, "d::vh", iz_long_opts, &opt_idx); #else c = getopt(argc, argv, "d::vh"); #endif if (c == -1) break; switch(c) { case 'd': if (optarg) { i = strtol(optarg, &dummy, 10); if (*dummy == '\0') iz_debug = nl_debug = i; else { fprintf(stderr, "Error: incorrect debug level: '%s'\n", optarg); exit(1); } } else iz_debug = nl_debug = 1; break; case 'v': printf( "iz " VERSION "\n" "Copyright (C) 2008, 2009 by Siemens AG\n" "License GPLv2 GNU GPL version 2 <http://gnu.org/licenses/gpl.html>.\n" "This is free software: you are free to change and redistribute it.\n" "There is NO WARRANTY, to the extent permitted by law.\n" "\n" "Written by Dmitry Eremin-Solenikov, Sergey Lapin and Maxim Osipov\n"); return 0; case 'h': iz_help(argv[0]); return 0; default: iz_help(argv[0]); return 1; } } if (optind >= argc) { iz_help(argv[0]); return 1; } memset(&cmd, 0, sizeof(cmd)); cmd.argc = argc - optind; cmd.argv = argv + optind; /* Parse command */ cmd.desc = get_cmd(argv[optind]); if (!cmd.desc) { printf("Unknown command %s!\n", argv[optind]); return 1; } if (cmd.desc->parse) { i = cmd.desc->parse(&cmd); if (i == IZ_STOP_OK) { return 0; } else if (i == IZ_STOP_ERR) { printf("Command line parsing error!\n"); return 1; } } /* Prepare NL command */ nl = nl_socket_alloc(); if (!nl) { nl_perror(NLE_NOMEM, "Could not allocate NL handle"); return 1; } genl_connect(nl); family = genl_ctrl_resolve(nl, IEEE802154_NL_NAME); group = nl_get_multicast_id(nl, IEEE802154_NL_NAME, IEEE802154_MCAST_COORD_NAME); if (group < 0) { fprintf(stderr, "Could not get multicast group ID: %s\n", strerror(-group)); return 1; } nl_socket_add_membership(nl, group); iz_seq = nl_socket_use_seq(nl) + 1; nl_socket_modify_cb(nl, NL_CB_VALID, NL_CB_CUSTOM, iz_cb_valid, (void*)&cmd); nl_socket_modify_cb(nl, NL_CB_FINISH, NL_CB_CUSTOM, iz_cb_finish, (void*)&cmd); nl_socket_modify_cb(nl, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, iz_cb_seq_check, (void*)&cmd); /* Send request, if necessary */ if (cmd.desc->request) { msg = nlmsg_alloc(); if (!msg) { nl_perror(NLE_NOMEM, "Could not allocate NL message!\n"); /* FIXME: err */ return 1; } genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, cmd.flags, cmd.desc->nl_cmd, 1); if (cmd.desc->request(&cmd, msg) != IZ_CONT_OK) { printf("Request processing error!\n"); return 1; } dprintf(1, "nl_send_auto_complete\n"); nl_send_auto_complete(nl, msg); cmd.seq = nlmsg_hdr(msg)->nlmsg_seq; dprintf(1, "nlmsg_free\n"); nlmsg_free(msg); } /* Received message handling loop */ while (iz_exit == IZ_CONT_OK) { int err = nl_recvmsgs_default(nl); if (err != NLE_SUCCESS) { nl_perror(err, "Receive failed"); return 1; } } nl_close(nl); if (iz_exit == IZ_STOP_ERR) return 1; return 0; }