1 /*
2  * virfirmware.c: Definition of firmware object and supporting functions
3  *
4  * Copyright (C) 2016 SUSE LINUX Products GmbH, Nuernberg, Germany.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library.  If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 
23 #include "viralloc.h"
24 #include "virerror.h"
25 #include "virfirmware.h"
26 #include "virlog.h"
27 #include "virstring.h"
28 
29 #define VIR_FROM_THIS VIR_FROM_NONE
30 
31 VIR_LOG_INIT("util.firmware");
32 
33 
34 void
virFirmwareFree(virFirmware * firmware)35 virFirmwareFree(virFirmware *firmware)
36 {
37     if (!firmware)
38         return;
39 
40     g_free(firmware->name);
41     g_free(firmware->nvram);
42     g_free(firmware);
43 }
44 
45 
46 void
virFirmwareFreeList(virFirmware ** firmwares,size_t nfirmwares)47 virFirmwareFreeList(virFirmware **firmwares, size_t nfirmwares)
48 {
49     size_t i;
50 
51     for (i = 0; i < nfirmwares; i++)
52         virFirmwareFree(firmwares[i]);
53 
54     g_free(firmwares);
55 }
56 
57 
58 int
virFirmwareParse(const char * str,virFirmware * firmware)59 virFirmwareParse(const char *str, virFirmware *firmware)
60 {
61     int ret = -1;
62     g_auto(GStrv) token = NULL;
63 
64     if (!(token = g_strsplit(str, ":", 0)))
65         goto cleanup;
66 
67     if (token[0]) {
68         virSkipSpaces((const char **) &token[0]);
69         if (token[1])
70             virSkipSpaces((const char **) &token[1]);
71     }
72 
73     /* Exactly two tokens are expected */
74     if (!token[0] || !token[1] || token[2] ||
75         STREQ(token[0], "") || STREQ(token[1], "")) {
76         virReportError(VIR_ERR_CONF_SYNTAX,
77                        _("Invalid nvram format: '%s'"),
78                        str);
79         goto cleanup;
80     }
81 
82     firmware->name = g_strdup(token[0]);
83     firmware->nvram = g_strdup(token[1]);
84 
85     ret = 0;
86  cleanup:
87     return ret;
88 }
89 
90 
91 int
virFirmwareParseList(const char * list,virFirmware *** firmwares,size_t * nfirmwares)92 virFirmwareParseList(const char *list,
93                      virFirmware ***firmwares,
94                      size_t *nfirmwares)
95 {
96     int ret = -1;
97     g_auto(GStrv) token = NULL;
98     size_t i, j;
99 
100     if (!(token = g_strsplit(list, ":", 0)))
101         goto cleanup;
102 
103     for (i = 0; token[i]; i += 2) {
104         if (!token[i] || !token[i + 1] ||
105             STREQ(token[i], "") || STREQ(token[i + 1], "")) {
106             virReportError(VIR_ERR_INTERNAL_ERROR,
107                            _("Invalid --with-loader-nvram list: %s"),
108                            list);
109             goto cleanup;
110         }
111     }
112 
113     if (i) {
114         *firmwares = g_new0(virFirmware *, i / 2);
115         *nfirmwares = i / 2;
116 
117         for (j = 0; j < i / 2; j++) {
118             virFirmware **fws = *firmwares;
119 
120             fws[j] = g_new0(virFirmware, 1);
121             fws[j]->name = g_strdup(token[2 * j]);
122             fws[j]->nvram = g_strdup(token[2 * j + 1]);
123         }
124     }
125 
126     ret = 0;
127  cleanup:
128     return ret;
129 }
130