• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include "android/avd/scanner.h"
15 
16 #include "android/avd/util.h"
17 #include "android/emulation/bufprint_config_dirs.h"
18 #include "android/utils/bufprint.h"
19 #include "android/utils/debug.h"
20 #include "android/utils/dirscanner.h"
21 #include "android/utils/path.h"
22 #include "android/utils/system.h"
23 
24 #include <string.h>
25 
26 #define D(...) VERBOSE_PRINT(init,__VA_ARGS__)
27 
28 struct AvdScanner {
29     DirScanner* scanner;
30     char temp[PATH_MAX];
31     char name[PATH_MAX];
32 };
33 
avdScanner_new(const char * sdk_home)34 AvdScanner* avdScanner_new(const char* sdk_home) {
35     AvdScanner* s;
36 
37     ANEW0(s);
38 
39     char* p = s->temp;
40     char* end = p + sizeof(s->temp);
41 
42     if (!sdk_home) {
43         p = bufprint_avd_home_path(p, end);
44     } else {
45         p = bufprint(p, end, "%s" PATH_SEP ANDROID_AVD_DIR, sdk_home);
46     }
47 
48     if (p >= end) {
49         // Path is too long, no search will be performed.
50         D("Path too long: %s\n", s->temp);
51         return s;
52     }
53     if (!path_is_dir(s->temp)) {
54         // Path does not exist, no search will be performed.
55         D("Path is not a directory: %s\n", s->temp);
56         return s;
57     }
58     s->scanner = dirScanner_new(s->temp);
59     return s;
60 }
61 
avdScanner_next(AvdScanner * s)62 const char* avdScanner_next(AvdScanner* s) {
63     if (s->scanner) {
64         for (;;) {
65             const char* entry = dirScanner_next(s->scanner);
66             if (!entry) {
67                 // End of enumeration.
68                 break;
69             }
70             size_t entry_len = strlen(entry);
71             if (entry_len < 4 ||
72                 memcmp(entry + entry_len - 4U, ".ini", 4) != 0) {
73                 // Can't possibly be a <name>.ini file.
74                 continue;
75             }
76 
77             // It's a match, get rid of the .ini suffix and return it.
78             entry_len -= 4U;
79             if (entry_len >= sizeof(s->name)) {
80                 D("Name too long: %s\n", entry);
81                 continue;
82             }
83             memcpy(s->name, entry, entry_len);
84             s->name[entry_len] = '\0';
85             return s->name;
86         }
87     }
88     return NULL;
89 }
90 
avdScanner_free(AvdScanner * s)91 void avdScanner_free(AvdScanner* s) {
92     if (s) {
93         if (s->scanner) {
94             dirScanner_free(s->scanner);
95             s->scanner = NULL;
96         }
97         AFREE(s);
98     }
99 }
100