Extract file name using /usr/apps keyword
[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 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;
56
57         if (fgets(cmdline_buf, PROC_NAME_MAX-1, fp) == NULL) {
58                 fclose(fp);
59                 return STC_ERROR_FAIL;
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
84         return STC_ERROR_NONE;
85 }
86
87 pid_t find_pid_from_cmdline(char *cmdline)
88 {
89         pid_t pid = -1, foundpid = -1;
90         int ret = 0;
91         DIR *dp;
92         struct dirent *dentry;
93         char appname[PROC_NAME_MAX];
94
95         dp = opendir("/proc");
96         if (!dp) {
97                 STC_LOGE("BACKGRD MANAGE : fail to open /proc");
98                 return STC_ERROR_FAIL;
99         }
100
101         while ((dentry = readdir(dp)) != NULL) {
102                 if (!isdigit(dentry->d_name[0]))
103                         continue;
104
105                 pid = atoi(dentry->d_name);
106                 if (!pid)
107                         continue;
108                 ret = proc_get_cmdline(pid, appname);
109                 if (ret == STC_ERROR_NONE) {
110                         if (!strncmp(cmdline, appname, strlen(appname)+1)) {
111                                 foundpid = pid;
112                                 break;
113                         }
114                 }
115         }
116         closedir(dp);
117         return foundpid;
118 }
119
120 int proc_get_label(pid_t pid, char *label)
121 {
122         char buf[PROC_BUF_MAX];
123         FILE *fp;
124
125         snprintf(buf, sizeof(buf), "/proc/%d/attr/current", pid);
126         fp = fopen(buf, "r");
127         if (fp == NULL)
128                 return STC_ERROR_FAIL;
129
130         if (fgets(label, PROC_NAME_MAX-1, fp) == NULL) {
131                 fclose(fp);
132                 return STC_ERROR_FAIL;
133         }
134         fclose(fp);
135         return STC_ERROR_NONE;
136 }
137
138 int proc_get_exepath(pid_t pid, char *buf, int len)
139 {
140         char path[PROC_BUF_MAX];
141         int ret = 0;
142
143         snprintf(path, sizeof(path), "/proc/%d/exe", pid);
144         ret = readlink(path, buf, len-1);
145         if (ret > 0)
146                 buf[ret] = '\0';
147         else
148                 buf[0] = '\0';
149         return STC_ERROR_NONE;
150 }
151
152 static int proc_get_data(char *path, char *buf, int len)
153 {
154         _cleanup_close_ int fd = -1;
155         int ret;
156
157         fd = open(path, O_RDONLY);
158         if (fd < 0)
159                 return STC_ERROR_FAIL;
160
161         ret = read(fd, buf, len-1);
162         if (ret < 0) {
163                 buf[0] = '\0';
164                 return STC_ERROR_FAIL;
165         }
166         buf[ret] = '\0';
167         return STC_ERROR_NONE;
168 }
169
170 int proc_get_raw_cmdline(pid_t pid, char *buf, int len)
171 {
172         char path[PROC_BUF_MAX];
173         snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
174         return proc_get_data(path, buf, len);
175 }
176
177 int proc_get_status(pid_t pid, char status[][PROC_BUF_MAX])
178 {
179         unsigned int i;
180         char path[PROC_BUF_MAX];
181         char status_buf[PROC_BUF_MAX];
182         FILE *fp;
183
184         snprintf(path, sizeof(path), "/proc/%d/status", pid);
185         fp = fopen(path, "r");
186         if (fp == NULL)
187                 return STC_ERROR_FAIL;
188
189         for (i = 0; i < PROC_STATUS_CNT; ++i) {
190                 char *token = NULL;
191                 char *saveptr = NULL;
192
193                 if (fgets(status_buf, sizeof(status_buf), fp) == NULL) {
194                         fclose(fp);
195                         return STC_ERROR_FAIL;
196                 }
197
198                 token = strtok_r(status_buf, ":", &saveptr);
199                 if (token != NULL) {
200                         token = strtok_r(NULL, "\n", &saveptr);
201                         if (token != NULL) {
202                                 while (isspace((unsigned char)*token))
203                                         token++;
204                                 strncpy(status[i], token, sizeof(status[i]));
205                         }
206                 }
207         }
208         fclose(fp);
209
210         return STC_ERROR_NONE;
211 }