From 034b600107a72f30eef95ea9d7a62c25ff00f565 Mon Sep 17 00:00:00 2001 From: Erwan Velu Date: Thu, 28 Apr 2011 20:26:24 +0200 Subject: [PATCH] hdt: Adding dump_filename= option This option allow the user to redefine the way filename is made-of. By default that's "mac_address+dmi_vendor_name+dmi_product_name" This can be overidded by the following syntax: dump_filename=your_filename Note that it's mandatory not to add "" or '' around your_filename. your_filename could be a regular filename but can also includes %{} directives as defined by : %{m} = mac address %{v} = vendor name of the machine %{p} = product name of the machine %{ba} = Asset tag of the base board %{bs} = Serial number of the base board %{ca} = Asset tag of the chassis %{cs} = Serial number of the chassis %{sk} = SKU number of the system %{ss} = Serial number of the system Here come a possible command line : APPEND nomenu auto='dump;' dump_path=hdt2 tftp_ip=192.168.1.254 dump_filename=%{m}+%{bs}+%{ba}+%{cs}+%{ca}+%{sk}+%{ss}+%{p}+%{v} --- com32/hdt/hdt-common.c | 5 ++ com32/hdt/hdt-common.h | 1 + com32/hdt/hdt-dump.c | 192 ++++++++++++++++++++++++++++++++----------------- 3 files changed, 132 insertions(+), 66 deletions(-) diff --git a/com32/hdt/hdt-common.c b/com32/hdt/hdt-common.c index aac50eb..1857cc0 100644 --- a/com32/hdt/hdt-common.c +++ b/com32/hdt/hdt-common.c @@ -106,6 +106,9 @@ void detect_parameters(const int argc, const char *argv[], max_console_lines = MAX_CLI_LINES; } else if (!strncmp(argv[i], "nomenu", 6)) { menumode = false; + } else if (!strncmp(argv[i], "dump_filename=", 14)) { + strlcpy(hardware->dump_filename, argv[i] + 14, + sizeof(hardware->dump_filename)); } else if (!strncmp(argv[i], "dump_path=", 10)) { strlcpy(hardware->dump_path, argv[i] + 10, sizeof(hardware->dump_path)); @@ -204,9 +207,11 @@ void init_hardware(struct s_hardware *hardware) memset(hardware->memtest_label, 0, sizeof hardware->memtest_label); memset(hardware->auto_label, 0, sizeof hardware->auto_label); memset(hardware->dump_path, 0, sizeof hardware->dump_path); + memset(hardware->dump_filename, 0, sizeof hardware->dump_filename); memset(hardware->vesa_background, 0, sizeof hardware->vesa_background); memset(hardware->tftp_ip, 0, sizeof hardware->tftp_ip); strcat(hardware->dump_path, "hdt"); + strcat(hardware->dump_filename, "%{m}+%{p}+%{v}"); strcat(hardware->pciids_path, "pci.ids"); strcat(hardware->modules_pcimap_path, "modules.pcimap"); strcat(hardware->modules_alias_path, "modules.alias"); diff --git a/com32/hdt/hdt-common.h b/com32/hdt/hdt-common.h index d37fcc8..f007e72 100644 --- a/com32/hdt/hdt-common.h +++ b/com32/hdt/hdt-common.h @@ -214,6 +214,7 @@ struct s_hardware { char modules_alias_path[255]; char pciids_path[255]; char dump_path[255]; /* Dump path on the tftp server */ + char dump_filename[255]; /* Dump filename on the tftp server */ char tftp_ip[255]; /* IP address of tftp server (dump mode) */ char memtest_label[255]; char auto_label[AUTO_COMMAND_SIZE]; diff --git a/com32/hdt/hdt-dump.c b/com32/hdt/hdt-dump.c index 8c22140..b963e19 100644 --- a/com32/hdt/hdt-dump.c +++ b/com32/hdt/hdt-dump.c @@ -37,56 +37,117 @@ struct print_buf p_buf; -void compute_filename(struct s_hardware *hardware, char *filename, int size) { - - snprintf(filename,size,"%s/",hardware->dump_path); - - if (hardware->is_pxe_valid) { - strncat(filename, hardware->pxe.mac_addr, sizeof(hardware->pxe.mac_addr)); - strncat(filename, "+", 1); - } - - if (hardware->is_dmi_valid) { - strncat(filename, remove_spaces(hardware->dmi.system.product_name), sizeof(hardware->dmi.system.manufacturer)); - strncat(filename, "+", 1); - strncat(filename, remove_spaces(hardware->dmi.system.manufacturer), sizeof(hardware->dmi.system.product_name)); +struct dump_option { + char *flag; + char *item; +}; + +char *get_value_from_option(struct s_hardware *hardware, char *option) +{ + struct dump_option dump_options[10]; + dump_options[0].flag = "%{m}"; + dump_options[0].item = hardware->pxe.mac_addr; + + dump_options[1].flag = "%{v}"; + dump_options[1].item = hardware->dmi.system.manufacturer; + + dump_options[2].flag = "%{p}"; + dump_options[2].item = hardware->dmi.system.product_name; + + dump_options[3].flag = "%{ba}"; + dump_options[3].item = hardware->dmi.base_board.asset_tag; + + dump_options[4].flag = "%{bs}"; + dump_options[4].item = hardware->dmi.base_board.serial; + + dump_options[5].flag = "%{ca}"; + dump_options[5].item = hardware->dmi.chassis.asset_tag; + + dump_options[6].flag = "%{cs}"; + dump_options[6].item = hardware->dmi.chassis.serial; + + dump_options[7].flag = "%{sk}"; + dump_options[7].item = hardware->dmi.system.sku_number; + + dump_options[8].flag = "%{ss}"; + dump_options[8].item = hardware->dmi.system.serial; + + dump_options[9].flag = NULL; + dump_options[9].item = NULL; + + for (int i = 0; i < 9; i++) { + if (strcmp(option, dump_options[i].flag) == 0) { + return remove_spaces(dump_options[i].item); + } + } + + return NULL; +} + +char *compute_filename(struct s_hardware *hardware) +{ + + char *filename = malloc(512); + snprintf(filename, 512, "%s/%s", hardware->dump_path, + hardware->dump_filename); + + /* Until we found some dump parameters */ + char *buffer; + while ((buffer = strstr(filename, "%{"))) { + // Find the end of the parameter + char *buffer_end = strstr(buffer, "}"); + + // Extracting the parameter between %{ and } + char option[8] = { 0 }; + strncpy(option, buffer, buffer_end - buffer + 1); + + /* Replace this option by its value in the filename + * Filename is longer than the previous filename we had + * so let's restart from the beginning */ + filename = + strreplace(filename, option, + get_value_from_option(hardware, option)); } /* We replace the ":" in the filename by some "-" * This will avoid Microsoft FS turning crazy */ - chrreplace(filename,':','-'); + chrreplace(filename, ':', '-'); /* Avoid space to make filename easier to manipulate */ - chrreplace(filename,' ','_'); + chrreplace(filename, ' ', '_'); + return filename; } -int dumpprintf(FILE *p, const char *format, ...) { - va_list ap; - int rv; - - (void) p; - va_start(ap, format); - rv = vbufprintf(&p_buf,format, ap); - va_end(ap); - return rv; +int dumpprintf(FILE * p, const char *format, ...) +{ + va_list ap; + int rv; + + (void)p; + va_start(ap, format); + rv = vbufprintf(&p_buf, format, ap); + va_end(ap); + return rv; } -void to_cpio(char *filename) { - cpio_writefile(upload,filename,p_buf.buf,p_buf.len); - if ((p_buf.buf) && (p_buf.len > 0)){ - memset(p_buf.buf,0,p_buf.len); - free(p_buf.buf); - p_buf.buf=NULL; - p_buf.size=0; - p_buf.len=0; - } +void to_cpio(char *filename) +{ + cpio_writefile(upload, filename, p_buf.buf, p_buf.len); + if ((p_buf.buf) && (p_buf.len > 0)) { + memset(p_buf.buf, 0, p_buf.len); + free(p_buf.buf); + p_buf.buf = NULL; + p_buf.size = 0; + p_buf.len = 0; + } } -void flush (ZZJSON_CONFIG *config, ZZJSON ** item) { - zzjson_print(config, *item); - zzjson_free(config, *item); - *item=NULL; +void flush(ZZJSON_CONFIG * config, ZZJSON ** item) +{ + zzjson_print(config, *item); + zzjson_free(config, *item); + *item = NULL; } /** @@ -94,53 +155,52 @@ void flush (ZZJSON_CONFIG *config, ZZJSON ** item) { **/ void dump(struct s_hardware *hardware) { - if (hardware->is_pxe_valid==false) { - printf("PXE stack was not detected, Dump feature is not available\n"); - return; + if (hardware->is_pxe_valid == false) { + printf("PXE stack was not detected, Dump feature is not available\n"); + return; } const union syslinux_derivative_info *sdi = syslinux_derivative_info(); - int err=0; + int err = 0; ZZJSON *json = NULL; ZZJSON_CONFIG config = { ZZJSON_VERY_STRICT, NULL, - (int(*)(void*)) fgetc, - NULL, - malloc, calloc, free, realloc, - stderr, NULL, stdout, - (int(*)(void *,const char*,...)) dumpprintf, - (int(*)(int,void*)) fputc + (int (*)(void *))fgetc, + NULL, + malloc, calloc, free, realloc, + stderr, NULL, stdout, + (int (*)(void *, const char *,...))dumpprintf, + (int (*)(int, void *))fputc }; - memset(&p_buf,0,sizeof(p_buf)); + memset(&p_buf, 0, sizeof(p_buf)); /* By now, we only support TFTP reporting */ - upload=&upload_tftp; - upload->name="tftp"; + upload = &upload_tftp; + upload->name = "tftp"; /* The following defines the behavior of the reporting */ char *arg[64]; - char filename[512]={0}; - compute_filename(hardware, filename, sizeof(filename)); + char *filename = compute_filename(hardware); /* The filename */ arg[0] = filename; /* The server to upload the file */ if (strlen(hardware->tftp_ip) != 0) { - arg[1] = hardware->tftp_ip; - arg[2] = NULL; + arg[1] = hardware->tftp_ip; + arg[2] = NULL; } else { - arg[1] = NULL; - snprintf(hardware->tftp_ip, sizeof(hardware->tftp_ip), - "%u.%u.%u.%u", - ((uint8_t *)&sdi->pxe.ipinfo->serverip)[0], - ((uint8_t *)&sdi->pxe.ipinfo->serverip)[1], - ((uint8_t *)&sdi->pxe.ipinfo->serverip)[2], - ((uint8_t *)&sdi->pxe.ipinfo->serverip)[3]); + arg[1] = NULL; + snprintf(hardware->tftp_ip, sizeof(hardware->tftp_ip), + "%u.%u.%u.%u", + ((uint8_t *) & sdi->pxe.ipinfo->serverip)[0], + ((uint8_t *) & sdi->pxe.ipinfo->serverip)[1], + ((uint8_t *) & sdi->pxe.ipinfo->serverip)[2], + ((uint8_t *) & sdi->pxe.ipinfo->serverip)[3]); } /* We initiate the cpio to send */ - cpio_init(upload,(const char **)arg); + cpio_init(upload, (const char **)arg); dump_cpu(hardware, &config, &json); dump_pxe(hardware, &config, &json); @@ -158,12 +218,12 @@ void dump(struct s_hardware *hardware) /* We close & flush the file to send */ cpio_close(upload); - if ((err=flush_data(upload)) != TFTP_OK) { + if ((err = flush_data(upload)) != TFTP_OK) { /* As we manage a tftp connection, let's display the associated error message */ more_printf("Dump failed !\n"); - more_printf("TFTP ERROR on : %s:/%s \n",hardware->tftp_ip, filename); - more_printf("TFTP ERROR msg : %s \n",tftp_string_error_message[-err]); + more_printf("TFTP ERROR on : %s:/%s \n", hardware->tftp_ip, filename); + more_printf("TFTP ERROR msg : %s \n", tftp_string_error_message[-err]); } else { - more_printf("Dump file sent at %s:/%s\n",hardware->tftp_ip, filename); + more_printf("Dump file sent at %s:/%s\n", hardware->tftp_ip, filename); } } -- 2.7.4