🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
3.7 KiB

  1. /*
  2. * An example demonstrating recursive directory traversal.
  3. *
  4. * Compile this file with Visual Studio and run the produced command in
  5. * console with a directory name argument. For example, command
  6. *
  7. * find "C:\Program Files"
  8. *
  9. * will output thousands of file names such as
  10. *
  11. * c:\Program Files/7-Zip/7-zip.chm
  12. * c:\Program Files/7-Zip/7-zip.dll
  13. * c:\Program Files/7-Zip/7z.dll
  14. * c:\Program Files/Adobe/Reader 10.0/Reader/logsession.dll
  15. * c:\Program Files/Adobe/Reader 10.0/Reader/LogTransport2.exe
  16. * c:\Program Files/Windows NT/Accessories/wordpad.exe
  17. * c:\Program Files/Windows NT/Accessories/write.wpc
  18. *
  19. * The find command provided by this file is only an example: the command does
  20. * not provide options to restrict the output to certain files as the Linux
  21. * version does.
  22. *
  23. * Copyright (C) 1998-2019 Toni Ronkko
  24. * This file is part of dirent. Dirent may be freely distributed
  25. * under the MIT license. For all details and documentation, see
  26. * https://github.com/tronkko/dirent
  27. */
  28. #define _CRT_SECURE_NO_WARNINGS
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <dirent.h>
  33. #include <errno.h>
  34. #include <locale.h>
  35. static int find_directory (const char *dirname);
  36. int
  37. main(
  38. int argc, char *argv[])
  39. {
  40. int i;
  41. int ok;
  42. /* Select default locale */
  43. setlocale (LC_ALL, "");
  44. /* For each directory in command line */
  45. i = 1;
  46. while (i < argc) {
  47. ok = find_directory (argv[i]);
  48. if (!ok) {
  49. exit (EXIT_FAILURE);
  50. }
  51. i++;
  52. }
  53. /* List current working directory if no arguments on command line */
  54. if (argc == 1) {
  55. find_directory (".");
  56. }
  57. return EXIT_SUCCESS;
  58. }
  59. /* Find files and subdirectories recursively */
  60. static int
  61. find_directory(
  62. const char *dirname)
  63. {
  64. DIR *dir;
  65. char buffer[PATH_MAX + 2];
  66. char *p = buffer;
  67. const char *src;
  68. char *end = &buffer[PATH_MAX];
  69. int ok;
  70. /* Copy directory name to buffer */
  71. src = dirname;
  72. while (p < end && *src != '\0') {
  73. *p++ = *src++;
  74. }
  75. *p = '\0';
  76. /* Open directory stream */
  77. dir = opendir (dirname);
  78. if (dir != NULL) {
  79. struct dirent *ent;
  80. /* Print all files and directories within the directory */
  81. while ((ent = readdir (dir)) != NULL) {
  82. char *q = p;
  83. char c;
  84. /* Get final character of directory name */
  85. if (buffer < q) {
  86. c = q[-1];
  87. } else {
  88. c = ':';
  89. }
  90. /* Append directory separator if not already there */
  91. if (c != ':' && c != '/' && c != '\\') {
  92. *q++ = '/';
  93. }
  94. /* Append file name */
  95. src = ent->d_name;
  96. while (q < end && *src != '\0') {
  97. *q++ = *src++;
  98. }
  99. *q = '\0';
  100. /* Decide what to do with the directory entry */
  101. switch (ent->d_type) {
  102. case DT_LNK:
  103. case DT_REG:
  104. /* Output file name with directory */
  105. printf ("%s\n", buffer);
  106. break;
  107. case DT_DIR:
  108. /* Scan sub-directory recursively */
  109. if (strcmp (ent->d_name, ".") != 0
  110. && strcmp (ent->d_name, "..") != 0) {
  111. find_directory (buffer);
  112. }
  113. break;
  114. default:
  115. /* Ignore device entries */
  116. /*NOP*/;
  117. }
  118. }
  119. closedir (dir);
  120. ok = 1;
  121. } else {
  122. /* Could not open directory */
  123. fprintf (stderr, "Cannot open %s (%s)\n", dirname, strerror (errno));
  124. ok = 0;
  125. }
  126. return ok;
  127. }