• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Module Name: apfiles - File-related functions for acpidump utility
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2016, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include "acpidump.h"
45 
46 /* Local prototypes */
47 
48 static int ap_is_existing_file(char *pathname);
49 
50 /******************************************************************************
51  *
52  * FUNCTION:    ap_is_existing_file
53  *
54  * PARAMETERS:  pathname            - Output filename
55  *
56  * RETURN:      0 on success
57  *
58  * DESCRIPTION: Query for file overwrite if it already exists.
59  *
60  ******************************************************************************/
61 
ap_is_existing_file(char * pathname)62 static int ap_is_existing_file(char *pathname)
63 {
64 #ifndef _GNU_EFI
65 	struct stat stat_info;
66 
67 	if (!stat(pathname, &stat_info)) {
68 		fprintf(stderr,
69 			"Target path already exists, overwrite? [y|n] ");
70 
71 		if (getchar() != 'y') {
72 			return (-1);
73 		}
74 	}
75 #endif
76 
77 	return 0;
78 }
79 
80 /******************************************************************************
81  *
82  * FUNCTION:    ap_open_output_file
83  *
84  * PARAMETERS:  pathname            - Output filename
85  *
86  * RETURN:      Open file handle
87  *
88  * DESCRIPTION: Open a text output file for acpidump. Checks if file already
89  *              exists.
90  *
91  ******************************************************************************/
92 
ap_open_output_file(char * pathname)93 int ap_open_output_file(char *pathname)
94 {
95 	ACPI_FILE file;
96 
97 	/* If file exists, prompt for overwrite */
98 
99 	if (ap_is_existing_file(pathname) != 0) {
100 		return (-1);
101 	}
102 
103 	/* Point stdout to the file */
104 
105 	file = fopen(pathname, "w");
106 	if (!file) {
107 		fprintf(stderr, "Could not open output file: %s\n", pathname);
108 		return (-1);
109 	}
110 
111 	/* Save the file and path */
112 
113 	gbl_output_file = file;
114 	gbl_output_filename = pathname;
115 	return (0);
116 }
117 
118 /******************************************************************************
119  *
120  * FUNCTION:    ap_write_to_binary_file
121  *
122  * PARAMETERS:  table               - ACPI table to be written
123  *              instance            - ACPI table instance no. to be written
124  *
125  * RETURN:      Status
126  *
127  * DESCRIPTION: Write an ACPI table to a binary file. Builds the output
128  *              filename from the table signature.
129  *
130  ******************************************************************************/
131 
ap_write_to_binary_file(struct acpi_table_header * table,u32 instance)132 int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
133 {
134 	char filename[ACPI_NAME_SIZE + 16];
135 	char instance_str[16];
136 	ACPI_FILE file;
137 	acpi_size actual;
138 	u32 table_length;
139 
140 	/* Obtain table length */
141 
142 	table_length = ap_get_table_length(table);
143 
144 	/* Construct lower-case filename from the table local signature */
145 
146 	if (ACPI_VALIDATE_RSDP_SIG(table->signature)) {
147 		ACPI_MOVE_NAME(filename, ACPI_RSDP_NAME);
148 	} else {
149 		ACPI_MOVE_NAME(filename, table->signature);
150 	}
151 
152 	filename[0] = (char)tolower((int)filename[0]);
153 	filename[1] = (char)tolower((int)filename[1]);
154 	filename[2] = (char)tolower((int)filename[2]);
155 	filename[3] = (char)tolower((int)filename[3]);
156 	filename[ACPI_NAME_SIZE] = 0;
157 
158 	/* Handle multiple SSDts - create different filenames for each */
159 
160 	if (instance > 0) {
161 		snprintf(instance_str, sizeof(instance_str), "%u", instance);
162 		strcat(filename, instance_str);
163 	}
164 
165 	strcat(filename, FILE_SUFFIX_BINARY_TABLE);
166 
167 	if (gbl_verbose_mode) {
168 		fprintf(stderr,
169 			"Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
170 			table->signature, filename, table->length,
171 			table->length);
172 	}
173 
174 	/* Open the file and dump the entire table in binary mode */
175 
176 	file = fopen(filename, "wb");
177 	if (!file) {
178 		fprintf(stderr, "Could not open output file: %s\n", filename);
179 		return (-1);
180 	}
181 
182 	actual = fwrite(table, 1, table_length, file);
183 	if (actual != table_length) {
184 		fprintf(stderr, "Error writing binary output file: %s\n",
185 			filename);
186 		fclose(file);
187 		return (-1);
188 	}
189 
190 	fclose(file);
191 	return (0);
192 }
193 
194 /******************************************************************************
195  *
196  * FUNCTION:    ap_get_table_from_file
197  *
198  * PARAMETERS:  pathname            - File containing the binary ACPI table
199  *              out_file_size       - Where the file size is returned
200  *
201  * RETURN:      Buffer containing the ACPI table. NULL on error.
202  *
203  * DESCRIPTION: Open a file and read it entirely into a new buffer
204  *
205  ******************************************************************************/
206 
ap_get_table_from_file(char * pathname,u32 * out_file_size)207 struct acpi_table_header *ap_get_table_from_file(char *pathname,
208 						 u32 *out_file_size)
209 {
210 	struct acpi_table_header *buffer = NULL;
211 	ACPI_FILE file;
212 	u32 file_size;
213 	acpi_size actual;
214 
215 	/* Must use binary mode */
216 
217 	file = fopen(pathname, "rb");
218 	if (!file) {
219 		fprintf(stderr, "Could not open input file: %s\n", pathname);
220 		return (NULL);
221 	}
222 
223 	/* Need file size to allocate a buffer */
224 
225 	file_size = cm_get_file_size(file);
226 	if (file_size == ACPI_UINT32_MAX) {
227 		fprintf(stderr,
228 			"Could not get input file size: %s\n", pathname);
229 		goto cleanup;
230 	}
231 
232 	/* Allocate a buffer for the entire file */
233 
234 	buffer = ACPI_ALLOCATE_ZEROED(file_size);
235 	if (!buffer) {
236 		fprintf(stderr,
237 			"Could not allocate file buffer of size: %u\n",
238 			file_size);
239 		goto cleanup;
240 	}
241 
242 	/* Read the entire file */
243 
244 	actual = fread(buffer, 1, file_size, file);
245 	if (actual != file_size) {
246 		fprintf(stderr, "Could not read input file: %s\n", pathname);
247 		ACPI_FREE(buffer);
248 		buffer = NULL;
249 		goto cleanup;
250 	}
251 
252 	*out_file_size = file_size;
253 
254 cleanup:
255 	fclose(file);
256 	return (buffer);
257 }
258