Replaced strncpy() with g_strlcpy() in helper-procfs.c
[platform/core/connectivity/stc-manager.git] / src / helper / helper-procfs.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 /**
19  * @file procfs.c
20  * @desc wrapper for reading profs information.
21  *
22  * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
23  *
24  */
25
26 #include <ctype.h>
27 #include <stdio.h>
28 #include <stdbool.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <dirent.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36
37 #include "stc-error.h"
38 #include "stc-manager-util.h"
39 #include "helper-procfs.h"
40
41 #define USRAPPS "/usr/apps/"
42
43 API int proc_get_cmdline(pid_t pid, char *cmdline)
44 {
45         char buf[PROC_BUF_MAX];
46         char cmdline_buf[PROC_NAME_MAX];
47         char *filename;
48         FILE *fp;
49         char *token = NULL;
50         char *saveptr = NULL;
51
52         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
53         fp = fopen(buf, "r");
54         if (fp == NULL)
55                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
56
57         if (fgets(cmdline_buf, PROC_NAME_MAX-1, fp) == NULL) {
58                 fclose(fp); //LCOV_EXCL_LINE
59                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
60         }
61         fclose(fp);
62
63         if (g_strstr_len(cmdline_buf, strlen(USRAPPS), USRAPPS) != NULL) {
64                 /* Application */
65                 filename = cmdline_buf + strlen(USRAPPS);
66                 token = strtok_r(filename, "/", &saveptr);
67                 if (token != NULL)
68                         filename = token;
69         } else {
70                 token = strtok_r(cmdline_buf, " ", &saveptr);
71                 if (token != NULL)
72                         filename = strrchr(token, '/');
73                 else
74                         filename = strrchr(cmdline_buf, '/');
75
76                 if (filename == NULL)
77                         filename = cmdline_buf;
78                 else
79                         filename = filename + 1;
80         }
81
82         strncpy(cmdline, filename, PROC_NAME_MAX - 1);
83         cmdline[PROC_NAME_MAX - 1] = '\0';
84
85         return STC_ERROR_NONE;
86 }
87
88 //LCOV_EXCL_START
89 pid_t find_pid_from_cmdline(char *cmdline)
90 {
91         pid_t pid = -1, foundpid = -1;
92         int ret = 0;
93         DIR *dp;
94         struct dirent *dentry;
95         char appname[PROC_NAME_MAX];
96
97         dp = opendir("/proc");
98         if (!dp) {
99                 STC_LOGE("BACKGRD MANAGE : fail to open /proc");
100                 return STC_ERROR_FAIL;
101         }
102
103         while ((dentry = readdir(dp)) != NULL) {
104                 if (!isdigit(dentry->d_name[0]))
105                         continue;
106
107                 pid = atoi(dentry->d_name);
108                 if (!pid)
109                         continue;
110                 ret = proc_get_cmdline(pid, appname);
111                 if (ret == STC_ERROR_NONE) {
112                         if (!strncmp(cmdline, appname, strlen(appname)+1)) {
113                                 foundpid = pid;
114                                 break;
115                         }
116                 }
117         }
118         closedir(dp);
119         return foundpid;
120 }
121
122 API void proc_foreach_pid(proc_pid_cb cb, void *user_data)
123 {
124         pid_t pid = -1;
125         int ret = 0;
126         DIR *dp;
127         struct dirent *dentry;
128
129         dp = opendir("/proc");
130         if (!dp) {
131                 STC_LOGE("failed to open /proc");
132                 return;
133         }
134
135         while ((dentry = readdir(dp)) != NULL) {
136                 if (!isdigit(dentry->d_name[0]))
137                         continue;
138
139                 pid = atoi(dentry->d_name);
140                 if (!pid)
141                         continue;
142
143                 ret = cb(pid, user_data);
144                 if (ret == false)
145                         break;
146         }
147
148         closedir(dp);
149 }
150
151 int proc_get_label(pid_t pid, char *label)
152 {
153         char buf[PROC_BUF_MAX];
154         FILE *fp;
155
156         snprintf(buf, sizeof(buf), "/proc/%d/attr/current", pid);
157         fp = fopen(buf, "r");
158         if (fp == NULL)
159                 return STC_ERROR_FAIL;
160
161         if (fgets(label, PROC_NAME_MAX-1, fp) == NULL) {
162                 fclose(fp);
163                 return STC_ERROR_FAIL;
164         }
165         fclose(fp);
166         return STC_ERROR_NONE;
167 }
168
169 int proc_get_exepath(pid_t pid, char *buf, int len)
170 {
171         char path[PROC_BUF_MAX];
172         int ret = 0;
173
174         snprintf(path, sizeof(path), "/proc/%d/exe", pid);
175         ret = readlink(path, buf, len-1);
176         if (ret > 0)
177                 buf[ret] = '\0';
178         else
179                 buf[0] = '\0';
180         return STC_ERROR_NONE;
181 }
182
183 static int proc_get_data(char *path, char *buf, int len)
184 {
185         _cleanup_close_ int fd = -1;
186         int ret;
187
188         fd = open(path, O_RDONLY);
189         if (fd < 0)
190                 return STC_ERROR_FAIL;
191
192         ret = read(fd, buf, len-1);
193         if (ret < 0) {
194                 buf[0] = '\0';
195                 return STC_ERROR_FAIL;
196         }
197         buf[ret] = '\0';
198         return STC_ERROR_NONE;
199 }
200
201 int proc_get_raw_cmdline(pid_t pid, char *buf, int len)
202 {
203         char path[PROC_BUF_MAX];
204         snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
205         return proc_get_data(path, buf, len);
206 }
207 //LCOV_EXCL_STOP
208
209 API int proc_get_status(pid_t pid, char status[][PROC_BUF_MAX])
210 {
211         unsigned int i;
212         unsigned int index = 0;
213         char path[PROC_BUF_MAX];
214         char status_buf[PROC_BUF_MAX];
215         bool updated[PROC_STATUS_CNT] = {FALSE, };
216         FILE *fp;
217
218         snprintf(path, sizeof(path), "/proc/%d/status", pid);
219         fp = fopen(path, "r");
220         if (fp == NULL)
221                 return STC_ERROR_FAIL;
222
223         for (i = 0; i < PROC_STATUS_CNT; ++i) {
224                 char *token = NULL;
225                 char *saveptr = NULL;
226
227                 if (fgets(status_buf, sizeof(status_buf), fp) == NULL) {
228                         fclose(fp); //LCOV_EXCL_LINE
229                         return STC_ERROR_FAIL; //LCOV_EXCL_LINE
230                 }
231
232                 if (!updated[PROC_STATUS_NAME] && strstr(status_buf,
233                                                          PROC_STATUS_NAME_STR))
234                         index = PROC_STATUS_NAME;
235                 else if (!updated[PROC_STATUS_STATE] && strstr(status_buf,
236                                                                PROC_STATUS_STATE_STR))
237                         index = PROC_STATUS_STATE;
238                 else if (!updated[PROC_STATUS_TGID] && strstr(status_buf,
239                                                               PROC_STATUS_TGID_STR))
240                         index = PROC_STATUS_TGID;
241                 else if (!updated[PROC_STATUS_NGID] && strstr(status_buf,
242                                                               PROC_STATUS_NGID_STR))
243                         index = PROC_STATUS_NGID;
244                 else if (!updated[PROC_STATUS_PID] && strstr(status_buf,
245                                                              PROC_STATUS_PID_STR))
246                         index = PROC_STATUS_PID;
247                 else if (!updated[PROC_STATUS_PPID] && strstr(status_buf,
248                                                               PROC_STATUS_PPID_STR))
249                         index = PROC_STATUS_PPID;
250                 else if (!updated[PROC_STATUS_TRACERPID] && strstr(status_buf,
251                                                                    PROC_STATUS_TRACERPID_STR))
252                         index = PROC_STATUS_TRACERPID;
253                 else
254                         continue;
255
256                 token = strtok_r(status_buf, ":", &saveptr);
257                 if (token != NULL) {
258                         token = strtok_r(NULL, "\n", &saveptr);
259                         if (token != NULL) {
260                                 while (isspace((unsigned char)*token))
261                                         token++;
262                                 g_strlcpy(status[index], token,
263                                         sizeof(status[index]));
264                                 updated[index] = TRUE;
265                         }
266                 }
267         }
268         fclose(fp);
269
270         return STC_ERROR_NONE;
271 }