0fb82850f394348e684d4ca989977bf1edd24873
[platform/core/system/upgrade.git] / src / delta-ua / engine / fota_log.c
1 /*
2  * libtota
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stdarg.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <errno.h>
28
29 #define LOG_SIZE_OPT_PATH               "/opt/data/recovery/.ua_log_size"
30 #define DEF_MAX_LOG_SIZE                (2*1024*1024)
31 #define MAX_FILE_PATH                   512
32
33 long curr_offset = 0;
34 long next_offset = 0;
35 long backup_offset = 0;
36 long max_logfile_size = DEF_MAX_LOG_SIZE;
37
38 /*-----------------------------------------------------------------------------
39   __check_existence
40  ----------------------------------------------------------------------------*/
41 static long __check_existence(const char *file_path)
42 {
43         struct stat statbuf;
44         char filename[MAX_FILE_PATH];
45
46         if (strncpy(filename, file_path, strlen(file_path) + 1) == NULL)
47                 return 0;
48         if (stat(filename, &statbuf)) {
49                 if (ENOENT == errno)
50                         return 0;
51         }
52         return statbuf.st_size;
53 }
54
55 /*-----------------------------------------------------------------------------
56   __read_from_file
57  ----------------------------------------------------------------------------*/
58 static int __read_from_file(const char *path, char *buf, size_t size)
59 {
60         int fd;
61         ssize_t count;
62
63         if (!path)
64                 return -1;
65
66         if (size == 0)
67                 return 0;
68
69         fd = open(path, O_RDONLY, 0);
70         if (fd == -1)
71                 return -1;
72
73         count = read(fd, buf, size);
74         if (count > 0) {
75                 count = (count < (ssize_t)size) ? count : ((ssize_t)size - 1);
76                 while (count > 0 && buf[count - 1] == '\n')
77                         count--;
78                 buf[count] = '\0';
79         } else {
80                 buf[0] = '\0';
81         }
82
83         close(fd);
84
85         return (int)count;
86 }
87
88 /*-----------------------------------------------------------------------------
89   get_opt_logfile_size
90  ----------------------------------------------------------------------------*/
91 static int get_opt_logfile_size(void)
92 {
93         /*
94             if status file does not exist, status = UP_START_NONE.
95             if status file exist, read status from file.
96         */
97         char buf[256];
98
99         if (__check_existence(LOG_SIZE_OPT_PATH) == 0)
100                 return -1;
101
102         if (__read_from_file(LOG_SIZE_OPT_PATH, buf, sizeof(buf)) < 0)
103                 return -1;
104
105         return atoi(buf);
106 }
107
108 /*-----------------------------------------------------------------------------
109   set_max_logfile_size
110  ----------------------------------------------------------------------------*/
111 void set_max_logfile_size(void)
112 {
113         int size = get_opt_logfile_size();
114
115         if (size <= 0)
116                 size = DEF_MAX_LOG_SIZE;
117
118         max_logfile_size = size;
119 }
120
121 /*-----------------------------------------------------------------------------
122   log_printf
123  ----------------------------------------------------------------------------*/
124 int log_printf(FILE* log_fp, char* format_str, ...)
125 {
126         int ret = 0;
127         char log_str[4096];
128         char backup_ch;
129         int len;
130         va_list list;
131
132         va_start(list, format_str);
133         vsnprintf(log_str, sizeof(log_str), format_str, list);
134         va_end(list);
135
136         len = strlen(log_str);
137         next_offset = curr_offset + len;
138
139         if (next_offset <= max_logfile_size) {
140                 if (fprintf(log_fp, "%s", log_str) < 0) {
141                         ret = -1;
142                         goto exit;
143                 }
144                 curr_offset = next_offset;
145                 if (curr_offset == max_logfile_size) {
146                         rewind(log_fp);
147                         curr_offset = 0;
148                 }
149         } else {
150                 backup_offset = max_logfile_size - curr_offset;
151                 backup_ch = log_str[backup_offset];
152                 log_str[backup_offset] = 0x00;
153                 if (fprintf(log_fp, "%s", log_str) < 0) {
154                         ret = -1;
155                         goto exit;
156                 }
157                 rewind(log_fp);
158                 log_str[backup_offset] = backup_ch;
159                 if (fprintf(log_fp, "%s", log_str+backup_offset) < 0) {
160                         ret = -1;
161                         goto exit;
162                 }
163                 curr_offset = next_offset - max_logfile_size;
164         }
165
166 exit:
167         return ret;
168 }