1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of tlm (Tizen Login Manager)
6 * Copyright (C) 2013 Intel Corporation.
8 * Contact: Amarnath Valluri <amarnath.valluri@linux.intel.com>
9 * Jussi Laako <jussi.laako@linux.intel.com>
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 #include <sys/types.h>
30 #include <glib/gstdio.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
40 #include "tlm-utils.h"
43 #define HOST_NAME_SIZE 256
46 g_clear_string (gchar **str)
55 tlm_user_get_name (uid_t user_id)
59 pwent = getpwuid (user_id);
63 return pwent->pw_name;
67 tlm_user_get_uid (const gchar *username)
71 pwent = getpwnam (username);
79 tlm_user_get_gid (const gchar *username)
83 pwent = getpwnam (username);
91 tlm_user_get_home_dir (const gchar *username)
95 pwent = getpwnam (username);
103 tlm_user_get_shell (const gchar *username)
105 struct passwd *pwent;
107 pwent = getpwnam (username);
111 return pwent->pw_shell;
115 tlm_utils_delete_dir (
121 if (!dir || !(gdir = g_dir_open(dir, 0, NULL))) {
125 const gchar *fname = NULL;
127 gchar *filepath = NULL;
128 while ((fname = g_dir_read_name (gdir)) != NULL) {
129 if (g_strcmp0 (fname, ".") == 0 ||
130 g_strcmp0 (fname, "..") == 0) {
134 filepath = g_build_filename (dir, fname, NULL);
136 retval = lstat(filepath, &sent);
138 /* recurse the directory */
139 if (S_ISDIR (sent.st_mode)) {
140 retval = (gint)!tlm_utils_delete_dir (filepath);
142 retval = g_remove (filepath);
154 if (g_remove (dir) != 0) {
163 const gchar *tty_name)
166 const gchar *tmp = tty_name;
169 if (isdigit (*tmp)) {
180 const gchar *hostname)
182 gchar *hostaddress = NULL;
183 struct addrinfo hints, *info = NULL;
185 if (!hostname) return NULL;
187 memset (&hints, 0, sizeof (hints));
188 hints.ai_flags = AI_ADDRCONFIG;
190 if (getaddrinfo (hostname, NULL, &hints, &info) == 0) {
192 if (info->ai_family == AF_INET) {
193 struct sockaddr_in *sa = (struct sockaddr_in *) info->ai_addr;
194 hostaddress = g_malloc0 (sizeof(struct in_addr));
195 memcpy (hostaddress, &(sa->sin_addr), sizeof (struct in_addr));
196 } else if (info->ai_family == AF_INET6) {
197 struct sockaddr_in6 *sa = (struct sockaddr_in6 *) info->ai_addr;
198 hostaddress = g_malloc0 (sizeof(struct in6_addr));
199 memcpy (hostaddress, &(sa->sin6_addr),
200 sizeof (struct in6_addr));
210 const gchar *tty1_name,
211 const gchar *tty2_name)
213 gchar *tty1 = NULL, *tty2 = NULL;
214 gboolean res = FALSE;
216 if (tty1_name == tty2_name) return TRUE;
217 if (!tty1_name || !tty2_name) return FALSE;
219 if (*tty1_name == '/') tty1 = g_strdup (tty1_name);
220 else tty1 = g_strdup_printf ("/dev/%s", tty1_name);
221 if (*tty2_name == '/') tty2 = g_strdup (tty2_name);
222 else tty2 = g_strdup_printf ("/dev/%s", tty2_name);
224 res = (g_strcmp0 (tty1_name, tty2_name) == 0);
234 gchar *name = g_malloc0 (HOST_NAME_SIZE);
235 if (gethostname (name, HOST_NAME_SIZE) != 0) {
243 tlm_utils_log_utmp_entry (const gchar *username)
248 struct utmp *ut_tmp = NULL;
249 gchar *hostname = NULL, *hostaddress = NULL;
250 const gchar *tty_name = NULL;
251 gchar *tty_no_dev_name = NULL, *tty_id = NULL;
253 DBG ("Log session entry to utmp/wtmp");
255 hostname = _get_host_name ();
256 hostaddress = _get_host_address (hostname);
257 tty_name = ttyname (0);
259 tty_no_dev_name = g_strdup (strncmp(tty_name, "/dev/", 5) == 0 ?
260 tty_name + 5 : tty_name);
262 tty_id = _get_tty_id (tty_no_dev_name);
264 utmpname (_PATH_UTMP);
267 while ((ut_tmp = getutent())) {
268 if ( (ut_tmp->ut_pid == pid) &&
269 (ut_tmp->ut_id[0] != '\0') &&
270 (ut_tmp->ut_type == LOGIN_PROCESS ||
271 ut_tmp->ut_type == USER_PROCESS) &&
272 (_is_tty_same (ut_tmp->ut_line, tty_name))) {
277 if (ut_tmp) memcpy (&ut_ent, ut_tmp, sizeof (ut_ent));
278 else memset (&ut_ent, 0, sizeof (ut_ent));
280 ut_ent.ut_type = USER_PROCESS;
283 strncpy (ut_ent.ut_id, tty_id, sizeof (ut_ent.ut_id));
285 strncpy (ut_ent.ut_user, username, sizeof (ut_ent.ut_user));
287 strncpy (ut_ent.ut_line, tty_no_dev_name, sizeof (ut_ent.ut_line));
289 strncpy (ut_ent.ut_host, hostname, sizeof (ut_ent.ut_host));
291 memcpy (&ut_ent.ut_addr_v6, hostaddress, sizeof (ut_ent.ut_addr_v6));
293 ut_ent.ut_session = getsid (0);
294 gettimeofday (&tv, NULL);
296 ut_ent.ut_tv.tv_sec = tv.tv_sec;
297 ut_ent.ut_tv.tv_usec = tv.tv_usec;
299 ut_ent.ut_time = tv.tv_sec;
305 updwtmp (_PATH_WTMP, &ut_ent);
307 g_free (hostaddress);
309 g_free (tty_no_dev_name);
314 _split_command_line_with_regex(const char *command, GRegex *regex) {
315 gchar **temp_strv = NULL;
316 gchar **temp_iter = NULL, **args_iter = NULL;
319 temp_strv = regex ? g_regex_split (regex, command, G_REGEX_MATCH_NOTEMPTY)
320 : g_strsplit (command, " ", -1);
322 WARN("Failed to split command: %s", command);
326 argv = g_new0 (gchar *, g_strv_length (temp_strv));
327 for (temp_iter = temp_strv, args_iter = argv;
331 gchar *item = g_strstrip (*temp_iter);
333 item_len = strlen (item);
337 if ((item[0] == '\"' && item[item_len - 1] == '\"') ||
338 (item[0] == '\'' && item[item_len - 1] == '\'')) {
339 item[item_len - 1] = '\0';
340 memmove (item, item + 1, item_len - 1);
342 *args_iter = g_strcompress (item);
345 g_strfreev (temp_strv);
351 tlm_utils_split_command_line(const gchar *command) {
352 const gchar *pattern = "('.*?'|\".*?\"|\\S+)";
353 GError *error = NULL;
354 GRegex *regex = NULL;
358 WARN("Cannot pase NULL arguments string");
362 if (!(regex = g_regex_new(pattern, 0, G_REGEX_MATCH_NOTEMPTY, &error))) {
363 WARN("Failed to create regex: %s", error->message);
367 argv = _split_command_line_with_regex (command, regex);
369 g_regex_unref (regex);
375 tlm_utils_split_command_lines (const GList const *commands_list) {
376 const gchar *pattern = "('.*?'|\".*?\"|\\S+)";
377 GError *error = NULL;
378 GRegex *regex = NULL;
379 GList *argv_list = NULL;
380 const GList *tmp_list = NULL;
382 if (!commands_list) {
386 if (!(regex = g_regex_new(pattern, 0, G_REGEX_MATCH_NOTEMPTY, &error))) {
387 WARN("Failed to create regex: %s", error->message);
391 for (tmp_list = commands_list; tmp_list; tmp_list = tmp_list->next) {
392 argv_list = g_list_append (argv_list, _split_command_line_with_regex (
393 (const gchar *)tmp_list->data, regex));
396 g_regex_unref (regex);