Leaked source code of windows server 2003
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.

207 lines
5.4 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4. #include <direct.h>
  5. #define MALLOC(x,y) (x *)malloc(sizeof(x) * (y))
  6. #define Empty 0
  7. #define Not_Empty 1
  8. BOOL Verbose = FALSE;
  9. BOOL Execute = FALSE;
  10. BOOL Remove = FALSE;
  11. BOOL SubDir = FALSE;
  12. void Usage(char *Message);
  13. void VerboseUsage(char *Message);
  14. BOOL CheckIfEmpty(char *Directory, BOOL PrintIt);
  15. void Usage(char *Message)
  16. {
  17. fprintf (stderr, "Usage: %s [/d] [/e] [/v] [directory ...]\n", Message);
  18. exit(1);
  19. }
  20. void VerboseUsage(char *Message)
  21. {
  22. fprintf (stderr, "%s: Looking for empty SubDirectories\n\n", Message);
  23. fprintf (stderr, "%s%s%s%s%s%s%s",
  24. "A directory is treated as empty if it has no file or directory in it. In any\n",
  25. "case, a directory is not empty if it has file.\n",
  26. "Available switches are:\n",
  27. " /d: directory is also listed empty if it only has SubDirectory in it\n",
  28. " /e: acutally perform deletions of empty directories\n",
  29. " /v: Verbose\n",
  30. " /?: prints this message\n");
  31. exit(1);
  32. }
  33. BOOL CheckIfEmpty(char *Directory, BOOL PrintIt)
  34. {
  35. HANDLE DirHandle;
  36. WIN32_FIND_DATA FindData;
  37. WIN32_FIND_DATA *fp;
  38. BOOL IsEmpty;
  39. char Buffer[MAX_PATH];
  40. IsEmpty = TRUE;
  41. fp = &FindData;
  42. //
  43. // Make one pass to find out if directory is empty
  44. //
  45. sprintf(Buffer, "%s\\*.*", Directory);
  46. DirHandle = FindFirstFile(Buffer, fp);
  47. do {
  48. // We want to skip "." and ".." Once the control enters this scope,
  49. // the file found is not "." or ".."
  50. if (strcmp(fp->cFileName, ".") && strcmp(fp->cFileName, ".."))
  51. {
  52. if (fp->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  53. {
  54. if (!SubDir) // If -d is not given on cmd line,
  55. {
  56. IsEmpty = FALSE; // We found a directory so we're not empty unless -d is specified
  57. }
  58. } else
  59. {
  60. IsEmpty = FALSE; // We found a file so we're not empty.
  61. }
  62. }
  63. } while (FindNextFile(DirHandle, fp));
  64. FindClose(DirHandle);
  65. //
  66. // Make another pass to call CheckIfEmpty recursively
  67. //
  68. sprintf(Buffer, "%s\\*.*", Directory);
  69. DirHandle = FindFirstFile(Buffer, fp);
  70. do {
  71. // We want to skip "." and ".." Once the control enters this scope,
  72. // the file found is not "." or ".."
  73. if (strcmp(fp->cFileName, ".") && strcmp(fp->cFileName, ".."))
  74. {
  75. if (fp->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  76. {
  77. //
  78. // Recursively call CheckIfEmpty on each subdirectory.
  79. //
  80. sprintf(Buffer, "%s\\%s", Directory, fp->cFileName);
  81. if (SubDir)
  82. {
  83. IsEmpty = (CheckIfEmpty( Buffer, !IsEmpty) && IsEmpty);
  84. } else
  85. {
  86. Remove = CheckIfEmpty( Buffer, TRUE);
  87. }
  88. //
  89. // If in execute mode try to remove subdirectory, if it's empty it will be removed
  90. //
  91. if (Execute && Remove)
  92. {
  93. _rmdir( Buffer);
  94. }
  95. }
  96. }
  97. } while (FindNextFile(DirHandle, fp));
  98. FindClose(DirHandle);
  99. if (IsEmpty && PrintIt)
  100. {
  101. if (Execute)
  102. {
  103. fprintf(stdout, "empty directory %s deleted\n", Directory);
  104. }
  105. else
  106. {
  107. fprintf(stdout, "%s empty\n", Directory);
  108. }
  109. } else if (Verbose)
  110. {
  111. fprintf(stdout, "%s non-empty\n", Directory);
  112. }
  113. return (IsEmpty);
  114. }
  115. void _cdecl main(int argc, char *argv[])
  116. {
  117. char c;
  118. char *prog = argv[0];
  119. char curdir[MAX_PATH];
  120. argc--;
  121. argv++;
  122. // Parse cmd line arguments for switches or flags. Switches are not
  123. // case-sensitive
  124. while (argc > 0 && (**argv == '-' || **argv == '/'))
  125. {
  126. while (c = *++argv[0])
  127. {
  128. _tolower(c);
  129. switch (c)
  130. {
  131. case 'v':
  132. Verbose = TRUE;
  133. break;
  134. case 'd':
  135. SubDir = TRUE;
  136. //
  137. // Always try to remove the directory if using /d
  138. //
  139. Remove = TRUE;
  140. break;
  141. case 'e':
  142. Execute = TRUE;
  143. break;
  144. case '?':
  145. VerboseUsage(prog);
  146. break;
  147. default:
  148. fprintf(stderr, "%s: Invalid switch \"%c\"\n", prog, c);
  149. Usage(prog);
  150. break;
  151. }
  152. }
  153. argc--;
  154. argv++;
  155. }
  156. if (argc < 1) // No path given in cmd line. Assume 'dot'
  157. {
  158. CheckIfEmpty(".", TRUE);
  159. }
  160. while (*argv) // Check all the directories specified on
  161. // the cmd line.
  162. {
  163. CheckIfEmpty(argv[0], TRUE);
  164. argv++;
  165. }
  166. }