blkid-print: fix partition path for /dev/sdX devices
[platform/core/system/upgrade.git] / src / blkid-print / blkid-print.c
1 /*
2  * tota-ua
3  *
4  * Copyright (c) 2021 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 <string.h>
21 #include <limits.h>
22 #include <stdlib.h>
23 #include "blkid-api.h"
24
25 void usage(const char* msg) {
26         if (msg) {
27                 printf("%s\n", msg);
28         }
29         printf("USAGE: blkid-print device_name partition_label suffix\n"
30         "device_name: block device e.g. /dev/mmcblk0\n"
31         "partition_label: partiton label to search for e.g. rootfs,ramdisk etc.\n"
32         "suffix: a|b partiton slot\n");
33 }
34
35 blkid_partition partition_for(char *device_name, char *part_name, char *new_slot) {
36         char part_name_with_slot[MAX_PARTNAME_LEN];
37         int found_part_n = -1;
38         if (!device_name || !part_name || !new_slot){
39                 printf("partition_for: one or more argument is NULL\n");
40                 return NULL;
41         }
42         if (snprintf(part_name_with_slot, MAX_PARTNAME_LEN, "%s_%s", part_name, new_slot) < 0) {
43                 return NULL;
44         }
45         blkid_probe pr = blkid_new_probe_from_filename(device_name);
46         if (pr == NULL) {
47                 printf("ERROR: blkid error for %s\n", device_name);
48                 usage(NULL);
49                 return NULL;
50         }
51         blkid_partlist ls = blkid_probe_get_partitions(pr);
52         if (!ls) {
53                 printf("ERROR: unable to probe partitions.\n");
54                 blkid_free_probe(pr);
55                 return NULL;
56         }
57         int nparts = blkid_partlist_numof_partitions(ls);
58         if (nparts == -1) {
59                 printf("ERROR: unable to get partition count\n");
60                 blkid_free_probe(pr);
61                 return NULL;
62         }
63
64
65         for (int i = 0; i < nparts; i++) {
66                 blkid_partition part = blkid_partlist_get_partition(ls, i);
67                 const char *p;
68
69                 p = blkid_partition_get_name(part);
70                 if (!p)
71                         continue;
72
73                 if (found_part_n < 0 && strncmp(p, part_name, strlen(part_name)+1) == 0)
74                         found_part_n = i;
75                 else if (strncmp(p, part_name_with_slot, strlen(part_name_with_slot)+1) == 0)
76                         found_part_n = i;
77         }
78
79         blkid_free_probe(pr);
80         if (found_part_n >= 0) {
81                 blkid_partition par = blkid_partlist_get_partition(ls, found_part_n);
82                 return par;
83         }
84         return NULL;
85 }
86
87 const char *get_part_label(blkid_partlist ls, int part_nr) {
88         blkid_partition part = blkid_partlist_get_partition(ls, part_nr);
89         return blkid_partition_get_name(part);
90 }
91
92 int main(int argc, char *argv[]) {
93         char device_name_path[PATH_MAX];
94         if (argc != 4) {
95                 usage("Please specify correct argument number\n");
96                 return 1;
97         }
98         char *device_name = realpath(argv[1], device_name_path);
99         if (!device_name) {
100                 printf("ERROR: Unable to determine realpath for: %s\n", argv[1]);
101                 usage(NULL);
102                 return 1;
103         }
104         char *partition_label = argv[2];
105         char *suffix = argv[3];
106         blkid_partition part = partition_for(device_name, partition_label, suffix);
107         if (part == NULL) {
108                 printf("ERROR: Partition '%s' not found.\n", partition_label);
109                 usage(NULL);
110                 return 2;
111         }
112         int part_nr = blkid_partition_get_partno(part);
113         if (part_nr < 0) {
114                 printf("ERROR: Partition '%s' not found", partition_label);
115                 return 3;
116         }
117         const char *part_label = blkid_partition_get_name(part);
118         char part_path[PATH_MAX];
119         // /dev/sda1 vs /dev/mmcblk0p1 /dev/nvme0n1p1
120         // no_separator vs "p" separator
121         if (strncmp("/dev/sd", device_name, strlen("/dev/sd")) == 0)
122                 snprintf(part_path, PATH_MAX, "%s%d", device_name, part_nr);
123         else
124                 snprintf(part_path, PATH_MAX, "%sp%d", device_name, part_nr);
125         printf("part_nr: %d (%s): %s\n", part_nr, part_label, part_path);
126                 return 0;
127 }
128