root/tools/power/acpi/tools/acpidump/apfiles.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ap_is_existing_file
  2. ap_open_output_file
  3. ap_write_to_binary_file
  4. ap_get_table_from_file

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: apfiles - File-related functions for acpidump utility
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include "acpidump.h"
  11 
  12 /* Local prototypes */
  13 
  14 static int ap_is_existing_file(char *pathname);
  15 
  16 /******************************************************************************
  17  *
  18  * FUNCTION:    ap_is_existing_file
  19  *
  20  * PARAMETERS:  pathname            - Output filename
  21  *
  22  * RETURN:      0 on success
  23  *
  24  * DESCRIPTION: Query for file overwrite if it already exists.
  25  *
  26  ******************************************************************************/
  27 
  28 static int ap_is_existing_file(char *pathname)
  29 {
  30 #if !defined(_GNU_EFI) && !defined(_EDK2_EFI)
  31         struct stat stat_info;
  32         int in_char;
  33 
  34         if (!stat(pathname, &stat_info)) {
  35                 fprintf(stderr,
  36                         "Target path already exists, overwrite? [y|n] ");
  37 
  38                 in_char = fgetc(stdin);
  39                 if (in_char == '\n') {
  40                         in_char = fgetc(stdin);
  41                 }
  42 
  43                 if (in_char != 'y' && in_char != 'Y') {
  44                         return (-1);
  45                 }
  46         }
  47 #endif
  48 
  49         return (0);
  50 }
  51 
  52 /******************************************************************************
  53  *
  54  * FUNCTION:    ap_open_output_file
  55  *
  56  * PARAMETERS:  pathname            - Output filename
  57  *
  58  * RETURN:      Open file handle
  59  *
  60  * DESCRIPTION: Open a text output file for acpidump. Checks if file already
  61  *              exists.
  62  *
  63  ******************************************************************************/
  64 
  65 int ap_open_output_file(char *pathname)
  66 {
  67         ACPI_FILE file;
  68 
  69         /* If file exists, prompt for overwrite */
  70 
  71         if (ap_is_existing_file(pathname) != 0) {
  72                 return (-1);
  73         }
  74 
  75         /* Point stdout to the file */
  76 
  77         file = fopen(pathname, "w");
  78         if (!file) {
  79                 fprintf(stderr, "Could not open output file: %s\n", pathname);
  80                 return (-1);
  81         }
  82 
  83         /* Save the file and path */
  84 
  85         gbl_output_file = file;
  86         gbl_output_filename = pathname;
  87         return (0);
  88 }
  89 
  90 /******************************************************************************
  91  *
  92  * FUNCTION:    ap_write_to_binary_file
  93  *
  94  * PARAMETERS:  table               - ACPI table to be written
  95  *              instance            - ACPI table instance no. to be written
  96  *
  97  * RETURN:      Status
  98  *
  99  * DESCRIPTION: Write an ACPI table to a binary file. Builds the output
 100  *              filename from the table signature.
 101  *
 102  ******************************************************************************/
 103 
 104 int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
 105 {
 106         char filename[ACPI_NAMESEG_SIZE + 16];
 107         char instance_str[16];
 108         ACPI_FILE file;
 109         acpi_size actual;
 110         u32 table_length;
 111 
 112         /* Obtain table length */
 113 
 114         table_length = ap_get_table_length(table);
 115 
 116         /* Construct lower-case filename from the table local signature */
 117 
 118         if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
 119                 ACPI_COPY_NAMESEG(filename, ACPI_RSDP_NAME);
 120         } else {
 121                 ACPI_COPY_NAMESEG(filename, table->signature);
 122         }
 123 
 124         filename[0] = (char)tolower((int)filename[0]);
 125         filename[1] = (char)tolower((int)filename[1]);
 126         filename[2] = (char)tolower((int)filename[2]);
 127         filename[3] = (char)tolower((int)filename[3]);
 128         filename[ACPI_NAMESEG_SIZE] = 0;
 129 
 130         /* Handle multiple SSDts - create different filenames for each */
 131 
 132         if (instance > 0) {
 133                 snprintf(instance_str, sizeof(instance_str), "%u", instance);
 134                 strcat(filename, instance_str);
 135         }
 136 
 137         strcat(filename, FILE_SUFFIX_BINARY_TABLE);
 138 
 139         if (gbl_verbose_mode) {
 140                 fprintf(stderr,
 141                         "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
 142                         table->signature, filename, table->length,
 143                         table->length);
 144         }
 145 
 146         /* Open the file and dump the entire table in binary mode */
 147 
 148         file = fopen(filename, "wb");
 149         if (!file) {
 150                 fprintf(stderr, "Could not open output file: %s\n", filename);
 151                 return (-1);
 152         }
 153 
 154         actual = fwrite(table, 1, table_length, file);
 155         if (actual != table_length) {
 156                 fprintf(stderr, "Error writing binary output file: %s\n",
 157                         filename);
 158                 fclose(file);
 159                 return (-1);
 160         }
 161 
 162         fclose(file);
 163         return (0);
 164 }
 165 
 166 /******************************************************************************
 167  *
 168  * FUNCTION:    ap_get_table_from_file
 169  *
 170  * PARAMETERS:  pathname            - File containing the binary ACPI table
 171  *              out_file_size       - Where the file size is returned
 172  *
 173  * RETURN:      Buffer containing the ACPI table. NULL on error.
 174  *
 175  * DESCRIPTION: Open a file and read it entirely into a new buffer
 176  *
 177  ******************************************************************************/
 178 
 179 struct acpi_table_header *ap_get_table_from_file(char *pathname,
 180                                                  u32 *out_file_size)
 181 {
 182         struct acpi_table_header *buffer = NULL;
 183         ACPI_FILE file;
 184         u32 file_size;
 185         acpi_size actual;
 186 
 187         /* Must use binary mode */
 188 
 189         file = fopen(pathname, "rb");
 190         if (!file) {
 191                 fprintf(stderr, "Could not open input file: %s\n", pathname);
 192                 return (NULL);
 193         }
 194 
 195         /* Need file size to allocate a buffer */
 196 
 197         file_size = cm_get_file_size(file);
 198         if (file_size == ACPI_UINT32_MAX) {
 199                 fprintf(stderr,
 200                         "Could not get input file size: %s\n", pathname);
 201                 goto cleanup;
 202         }
 203 
 204         /* Allocate a buffer for the entire file */
 205 
 206         buffer = ACPI_ALLOCATE_ZEROED(file_size);
 207         if (!buffer) {
 208                 fprintf(stderr,
 209                         "Could not allocate file buffer of size: %u\n",
 210                         file_size);
 211                 goto cleanup;
 212         }
 213 
 214         /* Read the entire file */
 215 
 216         actual = fread(buffer, 1, file_size, file);
 217         if (actual != file_size) {
 218                 fprintf(stderr, "Could not read input file: %s\n", pathname);
 219                 ACPI_FREE(buffer);
 220                 buffer = NULL;
 221                 goto cleanup;
 222         }
 223 
 224         *out_file_size = file_size;
 225 
 226 cleanup:
 227         fclose(file);
 228         return (buffer);
 229 }

/* [<][>][^][v][top][bottom][index][help] */