1 /*
2  * Copyright (C) 2018-2022 Intel Corporation.
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 /*
7  * Copyright (C) 2018-2022 Intel Corporation.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #include <openssl/sha.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include "property.h"
28 #include "log_sys.h"
29 #include "fsutils.h"
30 
31 #define MACHINE_ID		"/etc/machine-id"
32 #define OS_VERSION		"/usr/lib/os-release"
33 #define OS_VERSION_KEY		"VERSION_ID="
34 #define DEVICE_ID_UNKNOWN	"UnknownId"
35 #define LOG_UUID		"uuid.txt"
36 #define LOG_BUILDID		"buildid.txt"
37 
get_device_id(struct sender_t * sender)38 static void get_device_id(struct sender_t *sender)
39 {
40 	int ret;
41 	char *loguuid;
42 
43 
44 	ret = asprintf(&loguuid, "%s/%s", sender->outdir, LOG_UUID);
45 	if (ret < 0) {
46 		LOGE("compute string failed, out of memory\n");
47 		return;
48 	}
49 
50 	ret = file_read_string(MACHINE_ID, guuid, BUILD_VERSION_SIZE);
51 	if (ret <= 0)
52 		LOGE("Could not get mmc id: %d (%s)\n",
53 		     ret, strerror(-ret));
54 	else
55 		goto write;
56 
57 	LOGE("Could not find DeviceId, set it to '%s'\n",
58 	     DEVICE_ID_UNKNOWN);
59 	strncpy(guuid, DEVICE_ID_UNKNOWN, UUID_SIZE);
60 	guuid[UUID_SIZE - 1] = '\0';
61 
62 write:
63 	overwrite_file(loguuid, guuid);
64 	free(loguuid);
65 }
66 
get_buildversion(struct sender_t * sender)67 static int get_buildversion(struct sender_t *sender)
68 {
69 	int ret;
70 	char lastbuild[BUILD_VERSION_SIZE];
71 	char *logbuildid;
72 	char *currentbuild = gbuildversion;
73 
74 	ret = file_read_key_value(gbuildversion, sizeof(gbuildversion),
75 				  OS_VERSION, OS_VERSION_KEY,
76 				  strlen(OS_VERSION_KEY));
77 	if (ret <= 0) {
78 		LOGE("failed to get version from %s, error (%s)\n",
79 		     OS_VERSION, strerror(-ret));
80 		return ret;
81 	}
82 
83 	ret = asprintf(&logbuildid, "%s/%s", sender->outdir, LOG_BUILDID);
84 	if (ret < 0) {
85 		LOGE("compute string failed, out of memory\n");
86 		return ret;
87 	}
88 
89 	ret = file_read_string(logbuildid, lastbuild, BUILD_VERSION_SIZE);
90 	if (ret == -ENOENT ||
91 	    !ret ||
92 	    (ret > 0 && strcmp(currentbuild, lastbuild))) {
93 		/* build changed or file not found, overwrite it */
94 		ret = overwrite_file(logbuildid, gbuildversion);
95 		if (ret) {
96 			LOGE("create (%s) failed, error (%s)\n", logbuildid,
97 			     strerror(-ret));
98 			goto free;
99 		}
100 
101 		sender->sw_updated = 1;
102 		ret = 0;
103 	} else if (ret < 0) {
104 		LOGE("Cannot read %s, error (%s)\n",
105 		     logbuildid, strerror(errno));
106 	} else {
107 		/* buildid is the same */
108 		sender->sw_updated = 0;
109 		ret = 0;
110 	}
111 free:
112 	free(logbuildid);
113 	return ret;
114 }
115 
swupdated(struct sender_t * sender)116 int swupdated(struct sender_t *sender)
117 {
118 	return sender->sw_updated;
119 }
120 
init_properties(struct sender_t * sender)121 int init_properties(struct sender_t *sender)
122 {
123 	int ret;
124 
125 	ret = get_buildversion(sender);
126 	if (ret) {
127 		LOGE("init properties failed\n");
128 		return ret;
129 	}
130 	get_device_id(sender);
131 	return 0;
132 }
133