int main(int argc, char *args[]) { struct carlfw *fw = NULL; int err; if (argc < 3 || argc > 4) { err = -EINVAL; goto err_param; } switch (args[1][0]) { case 'a': if (argc != 4) goto err_param; fw = carlfw_load(args[2]); if (IS_ERR_OR_NULL(fw)) { err = PTR_ERR(fw); goto err_out; } err = add_mini(fw, args[3]); break; case 'd': if (argc != 3) goto err_param; fw = carlfw_load(args[2]); if (IS_ERR_OR_NULL(fw)) { err = PTR_ERR(fw); goto err_out; } err = del_mini(fw); break; default: goto err_param; break; } carlfw_release(fw); return EXIT_SUCCESS; err_out: carlfw_release(fw); fprintf(stderr, "miniboot action failed (%d).\n", err); return EXIT_FAILURE; err_param: carlfw_release(fw); mini_help(); return EXIT_FAILURE; }
int main(int argc, char* argv[]) { config_fout = stdout; config_ferr = stderr; if (argc == 1) { help(argv[0]); return -1; } int mode_specified = 0, do_init = 0; char* configpath = NULL; FILE* configfile; int c; while (1) { static struct option long_options[] = { {"help", 0, NULL, 'h'}, {"verbose", 0, NULL, 'v'}, {"log", required_argument, NULL, 'l'}, {"init", 0, NULL, 'i'}, {"update", 0, NULL, 'u'}, {0,0,0,0} }; int option_index = 0; c = getopt_long(argc, argv, "hvl:iu", long_options, &option_index); if (c == -1) {//unknown arg (doesnt match -x/--x format) if (optind >= argc) { //at end of successful parse break; } //getopt refuses to continue, so handle infile manually: int i = optind; for (; i < argc; ++i) { configpath = argv[i]; //debug("%d %d %s", argc, i, arg); configfile = fopen(configpath,"r"); if (configfile == NULL) { config_error("Unable to open config file %s: %s", configpath, strerror(errno)); mini_help(argv[0]); return -1; } } break; } switch (c) { case 'h': help(argv[0]); return -1; case 'v': config_debug_enabled = 1; break; case 'l': { FILE* logfile = fopen(optarg, "a"); if (logfile == NULL) { config_error("Unable to open log file %s: %s", optarg, strerror(errno)); return -1; } config_fout = logfile; config_ferr = logfile; } break; case 'i': mode_specified = 1; do_init = 1; break; case 'u': mode_specified = 1; do_init = 0; break; default: mini_help(argv[0]); return -1; } } if (!mode_specified) { config_error("-i/-u mode argument required."); mini_help(argv[0]); } int error = -1; if (configpath == NULL) { configpath = "<stdin>"; configfile = stdin; } config_log("Parsing %s",configpath); //Get and parse bb_frames (both STRINGs and TEXTs) from config: struct bb_frame* startframe = NULL; if (parsefile(&startframe,configfile) < 0) { fclose(configfile); config_error("Error encountered when parsing config file. "); mini_help(argv[0]); goto end_noclose; } fclose(configfile); if (startframe == NULL) { config_error("Empty config file, nothing to do. "); mini_help(argv[0]); goto end_noclose; } usbsign_handle* devh = NULL; if (hardware_init(&devh) < 0) { config_error("USB init failed: Exiting. "); mini_help(argv[0]); goto end_noclose; } char* packet = NULL; int pktsize; config_log("Writing to sign"); //send sequence header before we start sending packets if (!hardware_seqstart(devh)) { //try resetting device once config_error("Initial write failed, attempting reset."); if (!hardware_reset(&devh)) { config_error("Reset failed: Exiting."); goto end; } if (!hardware_seqstart(devh)) { config_error("Initial write retry failed, giving up."); goto end; } config_log("Reset successful, continuing"); } if (do_init) { //this packet allocates sign memory for messages: if ((pktsize = packet_buildmemconf(&packet,startframe)) < 0) { goto end; } if (hardware_sendpkt(devh,packet,pktsize) != pktsize) { goto end; } free(packet); packet = NULL; } //now on to the real messages: struct bb_frame* curframe = startframe; while (curframe != NULL) { config_debug("result: data=%s",curframe->data); if (curframe->frame_type == STRING_FRAME_TYPE) { //data will be updated often, store in a STRING file pktsize = packet_buildstring(&packet,curframe->filename, curframe->data); } else if (curframe->frame_type == TEXT_FRAME_TYPE) { if (!do_init) { curframe = curframe->next; config_debug(" ^-- SKIPPING: init-only packet"); continue; } //data wont be updated often, use a TEXT file pktsize = packet_buildtext(&packet,curframe->filename, curframe->mode,curframe->mode_special, curframe->data); } else { config_error("Internal error: Unknown frame type %d",curframe->frame_type); goto end; } if (hardware_sendpkt(devh,packet,pktsize) != pktsize) { goto end; } free(packet); packet = NULL; curframe = curframe->next; } if (do_init) { //set display order for the messages: pktsize = packet_buildrunseq(&packet,startframe); if (hardware_sendpkt(devh,packet,pktsize) != pktsize) { goto end; } free(packet); packet = NULL; } //finish it off with a sequence footer if (!hardware_seqend(devh)) { goto end; } error = 0; end: hardware_close(devh); end_noclose: if (startframe != NULL) { packet_delete(startframe); free(startframe); } return error; }