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 *
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
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