discover: Don't depend on tftp failure for type detection
[petitboot] / lib / system / system.c
1
2 #if defined(HAVE_CONFIG_H)
3 #include "config.h"
4 #endif
5
6 #include <assert.h>
7 #include <errno.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <sys/stat.h>
12 #include <sys/types.h>
13 #include <sys/wait.h>
14
15 #include "log/log.h"
16 #include <talloc/talloc.h>
17 #include "system.h"
18
19 const struct pb_system_apps pb_system_apps = {
20         .prefix         = PREFIX,
21         .cp             = HOST_PROG_CP,
22         .kexec          = HOST_PROG_KEXEC,
23         .mount          = HOST_PROG_MOUNT,
24         .shutdown       = HOST_PROG_SHUTDOWN,
25         .sftp           = HOST_PROG_SFTP,
26         .tftp           = HOST_PROG_TFTP,
27         .umount         = HOST_PROG_UMOUNT,
28         .wget           = HOST_PROG_WGET,
29         .ip             = HOST_PROG_IP,
30         .udhcpc         = HOST_PROG_UDHCPC,
31 };
32
33 #ifndef TFTP_TYPE
34 #define TFTP_TYPE TFTP_TYPE_UNKNOWN
35 #endif
36
37 enum tftp_type tftp_type = TFTP_TYPE;
38
39 int pb_mkdir_recursive(const char *dir)
40 {
41         struct stat statbuf;
42         char *str, *sep;
43         int mode = 0755;
44
45         if (!*dir)
46                 return 0;
47
48         if (!stat(dir, &statbuf)) {
49                 if (!S_ISDIR(statbuf.st_mode)) {
50                         pb_log("%s: %s exists, but isn't a directory\n",
51                                         __func__, dir);
52                         return -1;
53                 }
54                 return 0;
55         }
56
57         str = talloc_strdup(NULL, dir);
58         sep = strchr(*str == '/' ? str + 1 : str, '/');
59
60         while (1) {
61
62                 /* terminate the path at sep */
63                 if (sep)
64                         *sep = '\0';
65
66                 if (mkdir(str, mode) && errno != EEXIST) {
67                         pb_log("mkdir(%s): %s\n", str, strerror(errno));
68                         return -1;
69                 }
70
71                 if (!sep)
72                         break;
73
74                 /* reset dir to the full path */
75                 strcpy(str, dir);
76                 sep = strchr(sep + 1, '/');
77         }
78
79         talloc_free(str);
80
81         return 0;
82 }
83
84 int pb_rmdir_recursive(const char *base, const char *dir)
85 {
86         char *cur, *pos;
87
88         /* sanity check: make sure that dir is within base */
89         if (strncmp(base, dir, strlen(base)))
90                 return -1;
91
92         cur = talloc_strdup(NULL, dir);
93
94         while (strcmp(base, dir)) {
95
96                 rmdir(dir);
97
98                 /* null-terminate at the last slash */
99                 pos = strrchr(dir, '/');
100                 if (!pos)
101                         break;
102
103                 *pos = '\0';
104         }
105
106         talloc_free(cur);
107
108         return 0;
109 }