1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2015 Joyent, Inc.
14 */
15
16 #include <libvarpd_impl.h>
17 #include <assert.h>
18 #include <stdio.h>
19 #include <sys/types.h>
20 #include <dirent.h>
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 const char *
libvarpd_isaext(void)26 libvarpd_isaext(void)
27 {
28 #if defined(__amd64)
29 return ("64");
30 #elif defined(__i386)
31 return ("");
32 #else
33 #error "unknown ISA"
34 #endif
35 }
36
37 int
libvarpd_dirwalk(varpd_impl_t * vip,const char * path,const char * suffix,libvarpd_dirwalk_f func,void * arg)38 libvarpd_dirwalk(varpd_impl_t *vip, const char *path, const char *suffix,
39 libvarpd_dirwalk_f func, void *arg)
40 {
41 int ret;
42 size_t slen;
43 char *dirpath, *filepath;
44 DIR *dirp;
45 struct dirent *dp;
46 assert(vip != NULL && path != NULL);
47
48 if (asprintf(&dirpath, "%s/%s", path, libvarpd_isaext()) == -1)
49 return (errno);
50
51 if ((dirp = opendir(dirpath)) == NULL) {
52 ret = errno;
53 return (ret);
54 }
55
56 slen = strlen(suffix);
57 for (;;) {
58 size_t len;
59
60 errno = 0;
61 dp = readdir(dirp);
62 if (dp == NULL) {
63 ret = errno;
64 break;
65 }
66
67 len = strlen(dp->d_name);
68 if (len <= slen)
69 continue;
70
71 if (strcmp(suffix, dp->d_name + (len - slen)) != 0)
72 continue;
73
74 if (asprintf(&filepath, "%s/%s", dirpath, dp->d_name) == -1) {
75 ret = errno;
76 break;
77 }
78
79 if (func(vip, filepath, arg) != 0) {
80 free(filepath);
81 ret = 0;
82 break;
83 }
84
85 free(filepath);
86 }
87
88 (void) closedir(dirp);
89 free(dirpath);
90 return (ret);
91 }
92