Source code of Windows XP (NT5)
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.

210 lines
5.5 KiB

  1. /* chmode - change mode/attribute of file
  2. *
  3. * 17-Apr-1986 daniel lipkie add /R flag
  4. * 18-Jul-1986 daniel lipkie add /N flag
  5. * 17-Jun-1987 bw Hard-code '/' as switch char ( '-' conflicts with off )
  6. * 19-Oct-1990 w-barry Added forward function declaraions.
  7. * 27-Nov-1990 w-barry Began switch to Win32 API (including replacement of
  8. * getattr() with the Win32 equivalent.
  9. *
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <windows.h>
  15. #include <tools.h>
  16. #define ATTRLEN 8
  17. flagType fSetAttr = FALSE;
  18. flagType fRecurse = FALSE;
  19. flagType fNondirOnly = FALSE;
  20. char strPattern[MAX_PATH];
  21. char strAttr[ATTRLEN];
  22. DWORD maskOR = FILE_ATTRIBUTE_NORMAL;
  23. DWORD maskAND = 0xff;
  24. // Forward Function Declartions...
  25. void attr2str( char, char * );
  26. void walkdir( char *, struct findType *, void * );
  27. void walk( char *, struct findType *, void * );
  28. int dochmode( char * );
  29. void Usage( void );
  30. int __cdecl main( int, char ** );
  31. void
  32. attr2str(
  33. char attr,
  34. char *pStr
  35. )
  36. {
  37. *pStr++ = (char)(HASATTR(attr, FILE_ATTRIBUTE_DIRECTORY ) ? 'd' : '-');
  38. *pStr++ = '-';
  39. *pStr++ = ' ';
  40. *pStr++ = (char)(HASATTR(attr, FILE_ATTRIBUTE_HIDDEN ) ? 'H' : '-');
  41. *pStr++ = (char)(HASATTR(attr, FILE_ATTRIBUTE_SYSTEM ) ? 'S' : '-');
  42. *pStr++ = (char)(HASATTR(attr, FILE_ATTRIBUTE_ARCHIVE ) ? 'A' : '-');
  43. *pStr++ = (char)(HASATTR(attr, FILE_ATTRIBUTE_READONLY ) ? 'R' : '-');
  44. *pStr = '\0';
  45. }
  46. void
  47. walkdir(
  48. char *p,
  49. struct findType *b,
  50. void *dummy
  51. )
  52. {
  53. char *pBuf;
  54. if (!HASATTR(b->fbuf.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY) ||
  55. !strcmp (b->fbuf.cFileName, ".") || !strcmp (b->fbuf.cFileName, "..") ||
  56. (HASATTR(b->fbuf.dwFileAttributes, FILE_ATTRIBUTE_HIDDEN) ||
  57. HASATTR(b->fbuf.dwFileAttributes, FILE_ATTRIBUTE_SYSTEM)))
  58. /* do not enum "." and ".."
  59. * do not enum contents of non-directories
  60. * do not enum contents of hidden/system directories */
  61. return;
  62. if ((pBuf = malloc(MAX_PATH)) == NULL)
  63. return;
  64. strcpy(pBuf, p);
  65. if (!fPathChr((strend(pBuf))[-1]))
  66. strcat(pBuf, "\\");
  67. strcat(pBuf, strPattern);
  68. printf("subdirectory: %s\n", pBuf);
  69. dochmode(pBuf);
  70. free(pBuf);
  71. }
  72. void
  73. walk (
  74. char *p,
  75. struct findType *b,
  76. void *dummy
  77. )
  78. {
  79. if (TESTFLAG(b->fbuf.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY) &&
  80. (!strcmp (b->fbuf.cFileName,".") || !strcmp (b->fbuf.cFileName, "..")))
  81. /* don't show mode of . and .. */
  82. return;
  83. if (fSetAttr) {
  84. if (TESTFLAG(b->fbuf.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY) && fNondirOnly)
  85. /* Is a directory and /N flag so do NOT set attr */
  86. return;
  87. if (!SetFileAttributes(p, (b->fbuf.dwFileAttributes | maskOR) & maskAND) ) {
  88. attr2str( (char)((b->fbuf.dwFileAttributes | maskOR) & maskAND), strAttr);
  89. printf("error: attributes not set to %s %s\n", strAttr, p);
  90. }
  91. } else {
  92. attr2str( (char)b->fbuf.dwFileAttributes, strAttr);
  93. printf("%s %s\n", strAttr, p);
  94. }
  95. dummy;
  96. }
  97. int
  98. dochmode(
  99. char *pstr
  100. )
  101. {
  102. char *pBuf;
  103. if (!forfile (pstr, -1, walk, NULL))
  104. printf ("%s does not exist\n", pstr);
  105. if (fRecurse) {
  106. if ((pBuf = malloc(MAX_PATH)) == NULL)
  107. return( 0 );
  108. drive(pstr, pBuf);
  109. path(pstr, pBuf);
  110. /* do NOT append pathchar, we want to enum sub dir in this dir */
  111. strcat(pBuf, "*.*");
  112. forfile(pBuf, -1, walkdir, NULL);
  113. free(pBuf);
  114. }
  115. return 0;
  116. }
  117. void
  118. Usage ()
  119. {
  120. puts("Usage: CHMODE [/RN] {[-+][hsar]}+ {filespec}+\n"
  121. " /R - Recurse to subdirectories\n"
  122. " /N - Non-directory files only");
  123. exit( 1 );
  124. }
  125. int
  126. __cdecl
  127. main (
  128. int c,
  129. char *v[]
  130. )
  131. {
  132. register char *p;
  133. char ch;
  134. DWORD attr;
  135. ConvertAppToOem( c, v );
  136. SHIFT (c,v);
  137. while (c > 0 && ((ch = *v[0]) == '-' || ch == '+' || ch == '/')) {
  138. p = *v;
  139. if (ch == '/') {
  140. while (*++p != '\0') {
  141. if (*p == 'R') {
  142. fRecurse = TRUE;
  143. } else if (*p == 'N') {
  144. fNondirOnly = TRUE;
  145. } else {
  146. Usage();
  147. }
  148. }
  149. } else {
  150. fSetAttr = TRUE;
  151. attr = 0;
  152. while (*++p != '\0')
  153. switch (*p) {
  154. case 'h':
  155. SETFLAG(attr, FILE_ATTRIBUTE_HIDDEN);
  156. break;
  157. case 's':
  158. SETFLAG(attr, FILE_ATTRIBUTE_SYSTEM);
  159. break;
  160. case 'a':
  161. SETFLAG(attr, FILE_ATTRIBUTE_ARCHIVE);
  162. break;
  163. case 'r':
  164. SETFLAG(attr, FILE_ATTRIBUTE_READONLY);
  165. break;
  166. default:
  167. Usage ();
  168. }
  169. if (ch == '+')
  170. SETFLAG(maskOR, attr);
  171. else
  172. RSETFLAG(maskAND, attr);
  173. }
  174. SHIFT(c,v);
  175. }
  176. if (c == 0) {
  177. if (fSetAttr) {
  178. /* if switches set then require filenames */
  179. Usage();
  180. } else {
  181. strcpy(strPattern, "*.*");
  182. dochmode("*.*");
  183. }
  184. } else while (c) {
  185. if (!fileext(*v, strPattern)) {
  186. strcpy(strPattern, "*.*");
  187. }
  188. dochmode(*v);
  189. SHIFT(c, v);
  190. }
  191. return( 0 );
  192. }