• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Android Open Source Project
2 //
3 // This software is licensed under the terms of the GNU General Public
4 // License version 2, as published by the Free Software Foundation, and
5 // may be copied, distributed, and modified under those terms.
6 //
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 // GNU General Public License for more details.
11 
12 #include "android/filesystems/fstab_parser.h"
13 
14 #include <ctype.h>
15 #include <stdlib.h>
16 #include <string.h>
17 
18 namespace {
19 
skipWhitespace(const char * p,const char * end)20 const char* skipWhitespace(const char* p, const char* end) {
21     while (p < end && isspace(*p)) {
22         p++;
23     }
24     return p;
25 }
26 
skipNonWhitespace(const char * p,const char * end)27 const char* skipNonWhitespace(const char* p, const char* end) {
28     while (p < end && !isspace(*p)) {
29         p++;
30     }
31     return p;
32 }
33 
skipExpectedToken(const char * p,const char * end)34 const char* skipExpectedToken(const char* p, const char* end) {
35     p = skipWhitespace(p, end);
36     if (p == end) {
37         return NULL;
38     }
39     return skipNonWhitespace(p, end);
40 }
41 
getTokenLen(const char * p,const char * end)42 size_t getTokenLen(const char* p, const char* end) {
43     const char* q = skipNonWhitespace(p, end);
44     return (size_t)(q - p);
45 }
46 
47 }  // namespace
48 
android_parseFstabPartitionFormat(const char * fstabData,size_t fstabSize,const char * partitionName,char ** out)49 bool android_parseFstabPartitionFormat(const char* fstabData,
50                                        size_t fstabSize,
51                                        const char* partitionName,
52                                        char** out) {
53     const char* p = fstabData;
54     const char* end = p + fstabSize;
55 
56     size_t partitionNameLen = strlen(partitionName);
57 
58     while (p < end) {
59         // Find end of current line, and start of next one.
60         const char* line = p;
61         const char* line_end = ::strchr(p, '\n');
62         if (!line_end) {
63             line_end = end;
64             p = end;
65         } else {
66             p = line_end + 1;
67         }
68 
69         // Skip empty or comment lines.
70         line = skipWhitespace(line, line_end);
71         if (line == line_end || line[0] == '#') {
72             continue;
73         }
74 
75         // expected format: <device><ws><partition><ws><format><ws><options>
76 
77         // skip over device name.
78         line = skipExpectedToken(line, line_end);
79         if (!line) {
80             continue;
81         }
82 
83         line = skipWhitespace(line, line_end);
84         size_t tokenLen = getTokenLen(line, line_end);
85         if (tokenLen != partitionNameLen ||
86             memcmp(line, partitionName, tokenLen) != 0) {
87             // Not the right partition.
88             continue;
89         }
90 
91         line = skipWhitespace(line + tokenLen, line_end);
92         size_t formatLen = getTokenLen(line, line_end);
93         if (formatLen == 0) {
94             // Malformed data.
95             return false;
96         }
97 
98         *out = static_cast<char*>(malloc(formatLen + 1U));
99         memcpy(*out, line, formatLen);
100         (*out)[formatLen] = '\0';
101         return true;
102     }
103     return false;
104 }
105