Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
test_file_traversal.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2016 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /*
58  * test_file_traversal.c - simple file traversal testing
59  */
60 
61 #include <unistd.h>
62 #include <sys/types.h>
63 #include <sys/stat.h>
64 #include <fcntl.h>
65 #include <dirent.h>
66 #include <errno.h>
67 
68 #include "gwlib/gwlib.h"
69 
70 #ifdef HAVE_NFTW
71 #include <ftw.h>
72 #endif
73 
74 
75 static Counter *counter;
76 
77 
78 /*
79  * This callback function for use with for_each_file() will unlink
80  * the file, and hence removing all regular files within the DLR spool.
81  */
82 #ifdef HAVE_NFTW
83 static int count_file2(const char *filename, const struct stat *sb, int tflag, struct FTW *ftwbuf)
84 {
85  /* we need to check here if we have a regular file. */
86  if (tflag != FTW_F)
87  return 0;
88 
89  counter_increase(counter);
90 
91  return 0;
92 }
93 #endif
94 
95 
96 static int count_file(const char *filename, const struct stat *sb, int tflag, void *ftwbuf)
97 {
98  counter_increase(counter);
99 
100  return 0;
101 }
102 
103 
104 /*
105  * The function traverses a directory structure and calls a callback
106  * function for each regular file within that directory structure.
107  */
108 #ifdef HAVE_NFTW
109 static int for_each_file2(const Octstr *dir_s, int ignore_err,
110  int(*cb)(const char *, const struct stat *, int, struct FTW *))
111 {
112  int ret;
113 
114  ret = nftw(octstr_get_cstr(dir_s), cb, 20, FTW_PHYS);
115 
116  return ret;
117 }
118 #endif
119 
120 static int for_each_file(const Octstr *dir_s, int ignore_err,
121  int(*cb)(const char *, const struct stat *, int, void *))
122 {
123  DIR *dir;
124  struct dirent *ent;
125  int ret = 0;
126 #ifndef _DIRENT_HAVE_D_TYPE
127  struct stat stat;
128 #endif
129 
130  if ((dir = opendir(octstr_get_cstr(dir_s))) == NULL) {
131  error(errno, "Could not open directory `%s'", octstr_get_cstr(dir_s));
132  return -1;
133  }
134  while ((ent = readdir(dir)) != NULL) {
135  Octstr *filename;
136  if (!(strcmp((char*)ent->d_name, "." ) != 0 && strcmp((char*)ent->d_name, ".." ) != 0))
137  continue;
138  filename = octstr_format("%S/%s", dir_s, ent->d_name);
139 #ifdef _DIRENT_HAVE_D_TYPE
140  if (ent->d_type == DT_DIR && for_each_file(filename, ignore_err, cb) == -1) {
141  ret = -1;
142  } else if (ent->d_type == DT_REG && cb != NULL) {
143  cb(octstr_get_cstr(filename), NULL, 0, NULL);
144  }
145 #else
146  if (lstat(octstr_get_cstr(filename), &stat) == -1) {
147  if (!ignore_err)
148  error(errno, "Could not get stat for `%s'", octstr_get_cstr(filename));
149  ret = -1;
150  } else if (S_ISDIR(stat.st_mode) && for_each_file(filename, ignore_err, cb) == -1) {
151  ret = -1;
152  } else if (S_ISREG(stat.st_mode) && cb != NULL) {
153  cb(octstr_get_cstr(filename), &stat, 0, NULL);
154  }
155 #endif
156  octstr_destroy(filename);
157  if (ret == -1 && ignore_err)
158  ret = 0;
159  else if (ret == -1)
160  break;
161  }
162  closedir(dir);
163 
164  return ret;
165 }
166 
167 
168 int main(int argc, char **argv)
169 {
170  Octstr *os1;
171  Octstr *os2;
172  time_t start, diff;
173 
174  gwlib_init();
175 
176  os1 = octstr_create(argv[1]);
177  os2 = octstr_create(argv[2]);
178 
179  counter = counter_create();
180  start = time(NULL);
181  for_each_file(os1, 1, count_file);
182  diff = (time(NULL) - start);
183  debug("",0,"file count: %ld in %lds", (long) counter_value(counter), (long) diff);
184 
185 #ifdef HAVE_NFTW
186  counter_set(counter, 0);
187  start = time(NULL);
188  for_each_file2(os2, 1, count_file2);
189  diff = (time(NULL) - start);
190  debug("",0,"file count: %ld in %lds", (long) counter_value(counter), (long) diff);
191 #endif
192 
193  counter_destroy(counter);
194  octstr_destroy(os1);
195  octstr_destroy(os2);
196  gwlib_shutdown();
197  return 0;
198 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static int for_each_file(const Octstr *dir_s, int ignore_err, int(*cb)(const char *, const struct stat *, int, void *))
void counter_destroy(Counter *counter)
Definition: counter.c:110
unsigned long counter_set(Counter *counter, unsigned long n)
Definition: counter.c:167
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
Counter * counter_create(void)
Definition: counter.c:94
int main(int argc, char **argv)
static Counter * counter
static int count_file(const char *filename, const struct stat *sb, int tflag, void *ftwbuf)
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
char filename[FILENAME_MAX+1]
Definition: log.c:135
#define octstr_create(cstr)
Definition: octstr.h:125
unsigned long counter_value(Counter *counter)
Definition: counter.c:145
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void gwlib_shutdown(void)
Definition: gwlib.c:94
void gwlib_init(void)
Definition: gwlib.c:78
static int start
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.