void aim_log_vcommon(aim_log_t* l, aim_log_flag_t flag, aim_ratelimiter_t* rl, uint64_t time, const char* fname, const char* file, int line, const char* fmt, va_list vargs) { const char* color = NULL; if(flag == AIM_LOG_FLAG_MSG || flag == AIM_LOG_FLAG_FATAL || aim_log_enabled(l, flag)) { if(rl == NULL || aim_ratelimiter_limit(rl, time) == 0) { if(aim_pvs_isatty(l->pvs) == 1) { if((color = aim_log_flag_color__(flag))) { aim_printf(l->pvs, color); } } aim_log_output__(l, fname, file, line, fmt, vargs); if(color) { aim_printf(l->pvs, color_reset__); } } } }
int x86_64_mlnx_msn2410_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; x86_64_mlnx_msn2410_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", x86_64_mlnx_msn2410_config_settings[i].name, x86_64_mlnx_msn2410_config_settings[i].value); } return i; }
int timer_wheel_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; timer_wheel_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", timer_wheel_config_settings[i].name, timer_wheel_config_settings[i].value); } return i; }
int onlp_platform_defaults_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; onlp_platform_defaults_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", onlp_platform_defaults_config_settings[i].name, onlp_platform_defaults_config_settings[i].value); } return i; }
int powerpc_quanta_lb9_r0_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; powerpc_quanta_lb9_r0_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", powerpc_quanta_lb9_r0_config_settings[i].name, powerpc_quanta_lb9_r0_config_settings[i].value); } return i; }
int x86_64_accton_as7816_64x_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; x86_64_accton_as7816_64x_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", x86_64_accton_as7816_64x_config_settings[i].name, x86_64_accton_as7816_64x_config_settings[i].value); } return i; }
int x86_64_quanta_ly6_rangeley_r0_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; x86_64_quanta_ly6_rangeley_r0_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", x86_64_quanta_ly6_rangeley_r0_config_settings[i].name, x86_64_quanta_ly6_rangeley_r0_config_settings[i].value); } return i; }
int debug_counter_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; debug_counter_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", debug_counter_config_settings[i].name, debug_counter_config_settings[i].value); } return i; }
int x86_64_ingrasys_s9180_32x_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; x86_64_ingrasys_s9180_32x_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", x86_64_ingrasys_s9180_32x_config_settings[i].name, x86_64_ingrasys_s9180_32x_config_settings[i].value); } return i; }
int x86_64_cel_redstone_xp_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; x86_64_cel_redstone_xp_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", x86_64_cel_redstone_xp_config_settings[i].name, x86_64_cel_redstone_xp_config_settings[i].value); } return i; }
int x86_64_delta_ag9032v2_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; x86_64_delta_ag9032v2_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", x86_64_delta_ag9032v2_config_settings[i].name, x86_64_delta_ag9032v2_config_settings[i].value); } return i; }
int ofstatemanager_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; ofstatemanager_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", ofstatemanager_config_settings[i].name, ofstatemanager_config_settings[i].value); } return i; }
int x86_64_alphanetworks_snx60a0_486f_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; x86_64_alphanetworks_snx60a0_486f_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", x86_64_alphanetworks_snx60a0_486f_config_settings[i].name, x86_64_alphanetworks_snx60a0_486f_config_settings[i].value); } return i; }
void aim_pvs_logf(void* cookie, aim_log_flag_t flag, const char* str) { const char* color = NULL; aim_pvs_t* pvs = (aim_pvs_t*)cookie; if(pvs && aim_pvs_isatty(pvs) == 1) { if((color = aim_log_flag_color__(flag))) { aim_printf(pvs, color); } } aim_printf(pvs, "%s", str); if(color) { aim_printf(pvs, color_reset__); } }
int slot_allocator_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; slot_allocator_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", slot_allocator_config_settings[i].name, slot_allocator_config_settings[i].value); } return i; }
int vpi_config_show(struct aim_pvs_s* pvs) { int i; for(i = 0; vpi_config_settings[i].name; i++) { aim_printf(pvs, "%s = %s\n", vpi_config_settings[i].name, vpi_config_settings[i].value); } return i; }
void bighash_table_utilization_show(bighash_table_t *table, aim_pvs_t *pvs) { int i; int count = 0; aim_printf(pvs, "table: %d buckets\n", table->bucket_count); for(i = 0; i < table->bucket_count; i++) { int c = 0; bighash_entry_t *cur = table->buckets[i]; while (cur != NULL) { c++; cur = cur->next; } aim_printf(pvs, " %.4d: %d \n", i, c); count += c; } }
int aim_avsparse_type(const char* arg, aim_pvs_t* epvs, char c, char* type, aim_va_list_t* vargs) { int rv; aim_datatype_t* dt; aim_datatype_context_t dtc; if(arg == NULL) { return AIM_ERROR_PARAM; } if(type && type[0] == '%') { /* Immediate string specified. The argument must be that string. */ if(type[1] == 0) { /* No string */ return AIM_ERROR_PARAM; } if(!AIM_STRCMP(type+1, arg)) { return AIM_ERROR_NONE; } aim_printf(epvs, "expected '%s', not '%s'\n", type+1, arg); return AIM_ERROR_PARAM; } dt = aim_datatype_find(c, type); if(dt == NULL) { /* Unrecognized type */ aim_printf(epvs, "<bug: no handler for type '%c:%s'>\n", (c) ? c : '.', (type) ? type : "[NULL]"); return AIM_ERROR_NOT_FOUND; } dtc.dt = dt; dtc.epvs = epvs; rv = dt->from_str(&dtc, arg, vargs); if( (rv < 0) && dt->desc) { aim_printf(epvs, "'%s' is not a valid %s\n", arg, dt->desc); } return rv; }
/** * Basic output function for all log messages. */ static void aim_log_output__(aim_log_t* l, const char* fname, const char* file, int line, const char* fmt, va_list vargs) { aim_pvs_t* msg; char* pmsg; msg = aim_pvs_buffer_create(); if(AIM_BIT_GET(l->options, AIM_LOG_OPTION_TIMESTAMP)) { aim_log_time__(msg); } aim_vprintf(msg, fmt, vargs); if(l->options & (1 << AIM_LOG_OPTION_FUNC)) { aim_printf(msg, " [%s]", fname); } if(l->options & (1 << AIM_LOG_OPTION_FILE_LINE)) { aim_printf(msg, " [%s:%d]", file, line); } aim_printf(msg, "\n"); pmsg = aim_pvs_buffer_get(msg); aim_printf(l->pvs, "%s", pmsg); aim_free(pmsg); aim_pvs_destroy(msg); }
static void aim_log_time__(aim_pvs_t* pvs) { #if AIM_CONFIG_LOG_INCLUDE_LINUX_TIMESTAMP == 1 struct timeval timeval; struct tm *loctime; char lt[128]; gettimeofday(&timeval, NULL); loctime = localtime(&timeval.tv_sec); strftime(lt, sizeof(lt), "%b %d %T", loctime); aim_printf(pvs, "%s.%.03d ", lt, (int)timeval.tv_usec/1000); #else AIM_REFERENCE(pvs); AIM_REFERENCE(size); #endif }
int sff_tool(int argc, char* argv[]) { int rv = 0; int i; int c; int s = 0; int e = 0; int help = 0; int n = 0; int v = 0; biglist_t* fnames=NULL; while( (c = getopt(argc, argv, "sehnv")) != -1) { switch(c) { case 's': s = 1; break; case 'e': e = 1; break; case 'h': help=1; rv=0; break; case 'n': n=1; break; case 'v': v=1; break; default: help=1; rv = 1; break; } } if(help) { printf("Usage: %s [OPTIONS] [FILES]\n", argv[0]); printf(" -s Read filenames from stdin. \n"); printf(" -n Print the filename if successful.\n"); printf(" -v Print the filename always.\n"); printf(" -e Show the raw eeprom data.\n"); printf(" -h Help.\n"); return rv; } if(s) { /* Read filenames from stdin */ char b[PATH_MAX]; char* l; while((l = fgets(b, PATH_MAX, stdin))) { int len=SFF_STRLEN(l); if(len) { if(l[len-1] == '\n') { l[len-1] = 0; } fnames = biglist_append(fnames, aim_strdup(l)); } } } /* Read from command line. This can be used together with -s */ for(i = optind; i < argc; i++) { fnames = biglist_append(fnames, aim_strdup(argv[i])); } biglist_t* ble; char* f; BIGLIST_FOREACH_DATA(ble, fnames, char*, f) { sff_info_t info; memset(&info, 0, sizeof(info)); if( (rv = sff_info_init_file(&info, f)) >= 0) { if(n || v) { aim_printf(&aim_pvs_stdout, "%s\n", f); } if(e) { aim_printf(&aim_pvs_stdout, "eeprom:\n%{data}\n", info.eeprom, sizeof(info.eeprom)); } sff_info_show(&info, &aim_pvs_stdout); } else if(v) { aim_printf(&aim_pvs_stdout, "%s: failed.\n", f); } }
int aim_main(int argc, char* argv[]) { /* * Fixme -- this is just a hacked placeholder for * a more fully-functional tool. */ uint32_t pa; int size; uint8_t* va = NULL; #define USAGE() \ do { \ fprintf(stderr, "usage: mtool dump PHYSADDR BYTES\n"); \ fprintf(stderr, "usage: mtool odump PHYSADDR [json]\n"); \ return 1; \ } while(0) if(argc < 3) { USAGE(); } if(sscanf(argv[2], "0x%x", &pa) != 1) { USAGE(); } if(!strcmp(argv[1], "dump")) { if(argv[3] == NULL || sscanf(argv[3], "%d", &size) != 1) { USAGE(); } va = onlp_mmap(pa, size, "mtool"); if(va) { aim_printf(&aim_pvs_stdout, "%{data}\n", va, size); } } else if(!strcmp(argv[1], "odump")) { size = 1024*512; /* arbitrary */ va = onlp_mmap(pa, size, "mtool"); if(va) { onlp_onie_info_t info; if(onlp_onie_decode(&info, va, size) == 0) { if(argv[3] && !strcmp(argv[3], "json")) { onlp_onie_show_json(&info, &aim_pvs_stdout); } else { onlp_onie_show(&info, &aim_pvs_stdout); } onlp_onie_info_free(&info); } else { int dsize = 128; aim_printf(&aim_pvs_stdout, "Here are the first %d bytes:\n%{data}\n", dsize, va, dsize); } } } else { USAGE(); } if(va) { munmap(va, size); } return 0; }
int aim_main(int argc, char* argv[]) { int i; { const char* tstStrings[] = { "This", "is", "a", "complete", "sentence." }; char* join = aim_strjoin(" ", tstStrings, AIM_ARRAYSIZE(tstStrings)); if(strcmp(join, "This is a complete sentence.")) { printf("fail: join='%s'\n", join); } AIM_FREE(join); } for(i = 0; i < argc; i++) { aim_printf(&aim_pvs_stdout, "arg%d: '%s'\n", i, argv[i]); } { /* Test data */ char data[2500]; memset(data, 0xFF, sizeof(data)); aim_printf(&aim_pvs_stdout, "data is %{data}", data, sizeof(data)); } { char* sdata = "DEADBEEFCAFE"; char* data; int size; aim_sparse(&sdata, &aim_pvs_stdout, "{data}", &data, &size); aim_printf(&aim_pvs_stdout, "data is %{data}\n", data, size); aim_free(data); } utest_list(); AIM_LOG_MSG("Should print 1-27"); AIM_LOG_MSG("%d %d %d %d %d %d %d %d %d " "%d %d %d %d %d %d %d %d %d " "%d %d %d %d %d %d %d %d %d", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27); aim_printf(&aim_pvs_stdout, "aim_pvs_stdout from %s:%d\n", __FILE__, __LINE__); { char c; aim_pvs_t* pvs = aim_pvs_buffer_create(); aim_printf(pvs, "\nConsider "); aim_printf(pvs, "%s ", "the"); aim_printf(pvs, "alphabet: "); for(c = 'A'; c <= 'Z'; c++) { aim_printf(pvs, "%c", c); } aim_printf(pvs, "\n"); { char* s = aim_pvs_buffer_get(pvs); aim_printf(&aim_pvs_stdout, "first: %s", s); free(s); aim_printf(pvs, "(second)"); s = aim_pvs_buffer_get(pvs); aim_printf(&aim_pvs_stdout, "second: %s", s); free(s); aim_pvs_destroy(pvs); } { aim_ratelimiter_t rl; aim_ratelimiter_init(&rl, 10, 5, NULL); /* 5 (6?) tokens available at t=0 */ assert(aim_ratelimiter_limit(&rl, 0) == 0); assert(aim_ratelimiter_limit(&rl, 0) == 0); assert(aim_ratelimiter_limit(&rl, 0) == 0); assert(aim_ratelimiter_limit(&rl, 0) == 0); assert(aim_ratelimiter_limit(&rl, 0) == 0); assert(aim_ratelimiter_limit(&rl, 0) == 0); assert(aim_ratelimiter_limit(&rl, 0) < 0); /* Another token at t=10 */ assert(aim_ratelimiter_limit(&rl, 10) == 0); assert(aim_ratelimiter_limit(&rl, 10) < 0); /* Nothing at t=15 */ assert(aim_ratelimiter_limit(&rl, 15) < 0); /* 4 more tokens granted by t=50 */ assert(aim_ratelimiter_limit(&rl, 50) == 0); assert(aim_ratelimiter_limit(&rl, 50) == 0); assert(aim_ratelimiter_limit(&rl, 50) == 0); assert(aim_ratelimiter_limit(&rl, 50) == 0); assert(aim_ratelimiter_limit(&rl, 50) < 0); } { aim_printf(&aim_pvs_stdout, "valgrind_status=%d\n", aim_valgrind_status()); } AIM_LOG_MSG("%{aim_error}", AIM_ERROR_PARAM); } return 0; }
int onlpdump_main(int argc, char* argv[]) { int show = 0; uint32_t showflags = 0; int help = 0; int c; int rv = -1; int j = 0; int o = 0; int m = 0; int i = 0; int p = 0; int x = 0; const char* O = NULL; const char* t = NULL; while( (c = getopt(argc, argv, "srehdojmipxt:O:")) != -1) { switch(c) { case 's': show=1; break; case 'r': show=1; showflags |= ONLP_OID_SHOW_F_RECURSE; break; case 'e': show=1; showflags |= ONLP_OID_SHOW_F_EXTENDED; break; case 'd': show=0; break; case 'h': help=1; rv = 0; break; case 'j': j=1; break; case 'o': o=1; break; case 'x': x=1; break; case 'm': m=1; break; case 'i': i=1; break; case 'p': p=1; show=-1; break; case 't': t = optarg; break; case 'O': O = optarg; break; default: help=1; rv = 1; break; } } if(help) { printf("Usage: %s [OPTIONS]\n", argv[0]); printf(" -d Use dump(). This is the default.\n"); printf(" -s Use show() instead of dump().\n"); printf(" -r Recursive show(). Implies -s\n"); printf(" -e Extended show(). Implies -s\n"); printf(" -o Dump ONIE data only.\n"); printf(" -x Dump Platform Info only.\n"); printf(" -j Dump ONIE data in JSON format.\n"); printf(" -m Run platform manager.\n"); printf(" -i Iterate OIDs.\n"); printf(" -p Show SFP presence.\n"); printf(" -t <file> Decode TlvInfo data.\n"); printf(" -O <oid> Dump OID.\n"); return rv; } if(t){ int rv; onlp_onie_info_t onie; rv = onlp_onie_decode_file(&onie, t); if(rv >= 0) { onlp_onie_show(&onie, &aim_pvs_stdout); onlp_onie_info_free(&onie); return 0; } else { aim_printf(&aim_pvs_stdout, "Decode failed."); return 1; } } onlp_init(); if(O) { int oid; if(sscanf(O, "0x%x", &oid) == 1) { onlp_oid_dump(oid, &aim_pvs_stdout, ONLP_OID_DUMP_F_RECURSE | ONLP_OID_DUMP_F_EVEN_IF_ABSENT); } return 0; } if(i) { iterate_oids__(); return 0; } if(o || x) { onlp_sys_info_t si; if(onlp_sys_info_get(&si) < 0) { fprintf(stderr, "onlp_sys_info_get() failed."); return 1; } if(o) { if(j) { onlp_onie_show_json(&si.onie_info, &aim_pvs_stdout); } else { onlp_onie_show(&si.onie_info, &aim_pvs_stdout); } } if(x) { if(j) { onlp_platform_info_show_json(&si.platform_info, &aim_pvs_stdout); } else { onlp_platform_info_show(&si.platform_info, &aim_pvs_stdout); } } onlp_sys_info_free(&si); return 0; } if(show >= 0) { if(show == 0) { /* Default to full dump */ onlp_platform_dump(&aim_pvs_stdout, ONLP_OID_DUMP_F_RECURSE | ONLP_OID_DUMP_F_EVEN_IF_ABSENT); } else { onlp_platform_show(&aim_pvs_stdout, showflags); } } if(m) { printf("Running the platform manager for 600 seconds...\n"); onlp_sys_platform_manage_start(); sleep(600); printf("Stopping the platform manager.\n"); onlp_sys_platform_manage_stop(); } if(p) { onlp_sfp_bitmap_t presence; onlp_sfp_bitmap_t_init(&presence); int rv = onlp_sfp_presence_bitmap_get(&presence); aim_printf(&aim_pvs_stdout, "Presence: "); if(rv < 0) { aim_printf(&aim_pvs_stdout, "Error %{onlp_status}\n", rv); } else { aim_printf(&aim_pvs_stdout, "%{aim_bitmap}\n", &presence); } } return 0; }
-help\n\ \n"; int faultd_main(int argc, char* argv[]) { char** arg; char* pidfile = NULL; int daemonize = 0; int restart = 0; int test = 0; char* pipename = FAULTD_CONFIG_MAIN_PIPENAME; aim_pvs_t* aim_pvs_syslog = NULL; faultd_server_t* faultd_server = NULL; int sid = -1; for(arg = argv+1; *arg; arg++) { if(!strcmp(*arg, "-dr")) { daemonize=1; restart=1; } else if(!strcmp(*arg, "-d")) { daemonize=1; restart=0; } else if(!strcmp(*arg, "-pid")) { arg++; pidfile = *arg; if(!pidfile) { fprintf(stderr, "-pid requires an argument.\n"); exit(1); } } else if(!strcmp(*arg, "-p")) { arg++; pipename = *arg; if(!pipename) { fprintf(stderr, "-p requires an argument.\n"); exit(1); } } else if(!strcmp(*arg, "-t")) { test = 1; } else if(!strcmp(*arg, "-h") || !strcmp(*arg, "--help")) { printf(help__, FAULTD_CONFIG_MAIN_PIPENAME); exit(0); } } if(test) { return test__(argv[0], pipename); } /** * Start Server */ aim_pvs_syslog = aim_pvs_syslog_open("faultd", LOG_PID, LOG_DAEMON); aim_printf(aim_pvs_syslog, "faultd starting"); faultd_server_create(&faultd_server); sid = faultd_server_add(faultd_server, pipename); if(sid < 0) { perror("server_add:"); abort(); } if(daemonize) { aim_daemon_restart_config_t rconfig; aim_daemon_config_t config; memset(&config, 0, sizeof(config)); aim_daemon_restart_config_init(&rconfig, 1, 1); AIM_BITMAP_CLR(&rconfig.signal_restarts, SIGTERM); AIM_BITMAP_CLR(&rconfig.signal_restarts, SIGKILL); rconfig.maximum_restarts=0; rconfig.pvs = aim_pvs_syslog_get(); config.wd = "/"; if(restart) { aim_daemonize(&config, &rconfig); } else { aim_daemonize(&config, NULL); } } /* * Write our PID file if requested. */ if(pidfile) { FILE* fp = fopen(pidfile, "w"); if(fp == NULL) { int e = errno; aim_printf(aim_pvs_syslog, "fatal: open(%s): %s\n", pidfile, strerror(e)); aim_printf(&aim_pvs_stderr, "fatal: open(%s): %s\n", pidfile, strerror(e)); /* Don't attempt restart */ raise(SIGTERM); } fprintf(fp, "%d\n", getpid()); fclose(fp); } /** * Process Fault Messages */ for(;;) { faultd_info_t faultd_info; memset(&faultd_info, 0, sizeof(faultd_info)); if(faultd_server_read(faultd_server, &faultd_info, sid) >= 0) { faultd_info_show(&faultd_info, aim_pvs_syslog, 0); if(aim_pvs_isatty(&aim_pvs_stderr)) { faultd_info_show(&faultd_info, &aim_pvs_stderr, 0); } } } }
/** * Show log settings. */ void aim_log_show(aim_log_t* lobj, aim_pvs_t* pvs) { int i; int count; aim_map_si_t* map; aim_printf(pvs, "name: %s\n", lobj->name); aim_printf(pvs, "dest: %s\n", aim_pvs_desc_get(lobj->pvs)); count = 0; aim_printf(pvs, "enabled options: "); /* @fixme */ for(i = 0; i <= AIM_LOG_OPTION_TIMESTAMP; i++) { if(AIM_BIT_GET(lobj->options, i)) { aim_printf(pvs, "%s ", aim_log_option_name(i)); count++; } } if(count == 0) { aim_printf(pvs, "none."); } aim_printf(pvs, "\n"); count = 0; aim_printf(pvs, "disabled options: "); for(i = 0; i <= AIM_LOG_OPTION_TIMESTAMP; i++) { if(AIM_BIT_GET(lobj->options, i) == 0) { aim_printf(pvs, "%s ", aim_log_option_name(i)); count++; } } if(count == 0) { aim_printf(pvs, "none. "); } aim_printf(pvs, "\n"); aim_printf(pvs, "enabled: "); count = 0; /* @fixme */ for(i = 0; i <= AIM_LOG_FLAG_FTRACE; i++) { if(AIM_BIT_GET(lobj->common_flags, i)) { aim_printf(pvs, "%s ", aim_log_flag_name(i)); count++; } } for(map = lobj->custom_map; map && map->s; map++) { if(AIM_BIT_GET(lobj->custom_flags, map->i)) { aim_printf(pvs, "%s ", map->s); count++; } } if(count == 0) { aim_printf(pvs, "none."); } aim_printf(pvs, "\n"); aim_printf(pvs, "disabled: "); count = 0; for(i = 0; i < AIM_LOG_FLAG_FTRACE; i++) { if(AIM_BIT_GET(lobj->common_flags, i) == 0) { aim_printf(pvs, "%s ", aim_log_flag_name(i)); count++; } } for(map = lobj->custom_map; map && map->s; map++) { if(AIM_BIT_GET(lobj->custom_flags, map->i) == 0) { aim_printf(pvs, "%s ", map->s); count++; } } if(count == 0) { aim_printf(pvs, "none"); } aim_printf(pvs, "\n"); }
int wnc_sys_eeprom_show(aim_pvs_t* pvs, wnc_sys_eeprom_t* e) { aim_printf(pvs, "Product Name: %s\n", e->product_name); aim_printf(pvs, "Model Name: %s\n", e->model_name); aim_printf(pvs, "Part Number: %s\n", e->part_number); aim_printf(pvs, "Serial Number: %s\n", e->serial_number); aim_printf(pvs, "Manufacture Date: %s\n", e->manufacture_date); aim_printf(pvs, "Label Version: %s\n", e->label_version); aim_printf(pvs, "MAC: %{mac}\n", e->mac_address); aim_printf(pvs, "Hardware Version: 0x%x (%d)\n", e->hardware_version, e->hardware_version); aim_printf(pvs, "Software Version: 0x%x (%d)\n", e->software_version, e->software_version); aim_printf(pvs, "Card Type: 0x%x (%d)\n", e->card_type, e->card_type); aim_printf(pvs, "CRC: 0x%.2x\n", e->crc); return 0; }