Tizen 2.0 Release
[adaptation/system-plugin-slp.git] / src / with-dev-root-do.c
1 /* -*- c-basic-offset: 8 -*- */
2 /*
3  * Query udev for the real name of the device currently mounted
4  * as root filesystem and use it as an argument for a command.
5  *
6  * Copyright (C) 2012 Samsung Electronics
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  *
21  * Author: Ćukasz Stelmach <l.stelmach@samsung.com>
22  *
23  */
24
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <stdio.h>
29 #include <libudev.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 void usage() {
34         fprintf(stderr, "Usage:\n\n  with-dev-root-do <cmdline>\n\n");
35         fprintf(stderr, "Execute the cmdline with the real name of the device currently mounted\n");
36         fprintf(stderr, "as root file-system appended at the end or substituted for '{}'. Examples\n");
37         fprintf(stderr, "assuming /dev/sda1 holds root file-system:\n\n");
38         fprintf(stderr, "  with-dev-root-do /sbin/fsck\n\n");
39         fprintf(stderr, "runs \"/sbin/fsck /dev/sda1\"\n\n");
40         fprintf(stderr, "  with-dev-root-do /sbin/e2image {} /tmp/root.e2img\n\n");
41         fprintf(stderr, "runs \"/sbin/e2image /dev/sda1 /tmp/root.e2img\"\n");
42 }
43
44 const char* find_node() {
45         struct stat s;
46         struct udev* udev=NULL;
47         struct udev_device *udev_device = NULL;
48         const char* node=NULL;
49
50         if(stat("/", &s) < 0) {
51                 perror("stat");
52                 return NULL;
53         }
54
55         if (s.st_dev == 0)
56                 return NULL;
57
58         udev=udev_new();
59         if(udev==NULL) {
60                 fprintf(stderr, "I don't remember.\n");
61                 return NULL;
62         }
63
64         udev_device=udev_device_new_from_devnum(udev, 'b', s.st_dev);
65         if(udev_device==NULL) {
66                 fprintf(stderr, "Where do we come from?\n");
67                 return NULL;
68         }
69
70         node=udev_device_get_devnode(udev_device);
71         if(node==NULL) {
72                 fprintf(stderr, "Where are we going to?\n");
73                 return NULL;
74         }
75         return node;
76 }
77
78 int main(int argc, char* argv[]) {
79         const char** cmdline;
80         const char* node;
81         int i;
82         int placeholder_found=0;
83
84         if(argc < 2) {
85                 usage();
86                 fprintf(stderr, "\nI don't want to be alone.\n");
87                 exit(1);
88         }
89
90         cmdline=malloc((1+argc) * sizeof(char*));
91         if(cmdline==NULL) {
92                 perror("malloc");
93                 exit(1);
94         }
95         memset((char*)cmdline, 0, (1+argc) * sizeof(char*));
96
97         if((node=find_node())==NULL) {
98                 free(cmdline);
99                 exit(1);
100         }
101
102         for (i=0; i < argc && argv[i+1]; i++) {
103                 if(strncmp("{}", argv[i+1], 3)==0) {
104                         placeholder_found=1;
105                         cmdline[i] = node;
106                 } else
107                         cmdline[i] = argv[i+1];
108         }
109
110         if (!placeholder_found)
111                 cmdline[i]=node;
112
113         execv(cmdline[0], (char**) cmdline);
114         return 1;
115 }