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