treewide: Move device_tree to commonlib
[coreboot2.git] / util / cbfstool / flashrom.c
blobfe3fb7b3d881293975ff16839fb209a56fd3fa47
1 /* Copyright 2020 The ChromiumOS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
6 /* For strdup */
7 #define _POSIX_C_SOURCE 200809L
8 #include <fcntl.h>
9 #include <limits.h>
10 #include <stdbool.h>
11 #include <stdint.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 #include <unistd.h>
19 #include "common.h" /* from cbfstool for buffer API. */
20 #include "subprocess.h" /* from vboot_reference */
21 #include "flashrom.h"
23 #define FLASHROM_EXEC_NAME "flashrom"
24 #define FLASHROM_PROGRAMMER_INTERNAL_AP "internal"
26 /**
27 * Helper to create a temporary file.
29 * @param path_out An output pointer for the filename. Caller should free.
31 * @return 0 on success, -1 for file open error, or -2 for write error.
33 static int create_temp_file(char **path_out)
35 int fd;
36 int rv;
37 char *path;
38 mode_t umask_save;
40 #if defined(__FreeBSD__)
41 #define P_tmpdir "/tmp"
42 #endif
43 *path_out = NULL;
44 path = strdup(P_tmpdir "/flashrom.XXXXXX");
45 /* Set the umask before mkstemp for security considerations. */
46 umask_save = umask(077);
47 fd = mkstemp(path);
48 umask(umask_save);
49 if (fd < 0) {
50 rv = -1;
51 goto fail;
54 close(fd);
55 *path_out = path;
57 return 0;
58 fail:
59 free(path);
60 return rv;
63 static int run_flashrom(const char *const argv[])
65 int status = subprocess_run(argv, &subprocess_null, &subprocess_null,
66 &subprocess_null);
67 if (status) {
68 fprintf(stderr, "Flashrom invocation failed (exit status %d):",
69 status);
70 for (const char *const *argp = argv; *argp; argp++)
71 fprintf(stderr, " %s", *argp);
72 fprintf(stderr, "\n");
73 return -1;
76 return 0;
79 int flashrom_host_read(struct buffer *buffer, const char *region)
81 char *tmpfile;
82 char region_param[PATH_MAX];
83 int rv;
85 if (create_temp_file(&tmpfile) != 0)
86 return -1;
87 if (region)
88 snprintf(region_param, sizeof(region_param), "%s:%s", region,
89 tmpfile);
90 const char *const argv[] = {
91 FLASHROM_EXEC_NAME,
92 "-p",
93 FLASHROM_PROGRAMMER_INTERNAL_AP,
94 "-r",
95 region ? "-i" : tmpfile,
96 region ? region_param : NULL,
97 NULL,
99 rv = run_flashrom(argv);
100 if (!rv)
101 rv = buffer_from_file(buffer, tmpfile);
103 unlink(tmpfile);
104 free(tmpfile);
106 return rv;
109 int flashrom_host_write(struct buffer *buffer, const char *region)
111 char *tmpfile;
112 char region_param[PATH_MAX];
113 int rv;
115 if (create_temp_file(&tmpfile) != 0)
116 return -1;
117 if (buffer_write_file(buffer, tmpfile) != 0) {
118 rv = -2;
119 goto fail;
122 if (region)
123 snprintf(region_param, sizeof(region_param), "%s:%s", region,
124 tmpfile);
125 const char *const argv[] = {
126 FLASHROM_EXEC_NAME,
127 "-p",
128 FLASHROM_PROGRAMMER_INTERNAL_AP,
129 "--noverify-all",
130 "-w",
131 region ? "-i" : tmpfile,
132 region ? region_param : NULL,
133 NULL,
136 rv = run_flashrom(argv);
138 fail:
139 unlink(tmpfile);
140 free(tmpfile);
142 return rv;