DIR.C
上传用户:dcs7469208
上传日期:2010-01-02
资源大小:443k
文件大小:9k
源码类别:

操作系统开发

开发平台:

DOS

  1. /****************************************************************/
  2. /* */
  3. /*       dir.c */
  4. /* */
  5. /*         DOS "dir" Command  */
  6. /* */
  7. /*  November 6, 1991 */
  8. /* */
  9. /* Copyright (c) 1995 */
  10. /* Pasquale J. Villani */
  11. /* All Rights Reserved */
  12. /* */
  13. /* This file is part of DOS-C. */
  14. /* */
  15. /* DOS-C is free software; you can redistribute it and/or */
  16. /* modify it under the terms of the GNU General Public License */
  17. /* as published by the Free Software Foundation; either version */
  18. /* 2, or (at your option) any later version. */
  19. /* */
  20. /* DOS-C is distributed in the hope that it will be useful, but */
  21. /* WITHOUT ANY WARRANTY; without even the implied warranty of */
  22. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See */
  23. /* the GNU General Public License for more details. */
  24. /* */
  25. /* You should have received a copy of the GNU General Public */
  26. /* License along with DOS-C; see the file COPYING.  If not, */
  27. /* write to the Free Software Foundation, 675 Mass Ave, */
  28. /* Cambridge, MA 02139, USA. */
  29. /****************************************************************/
  30. /* $Logfile:   C:/dos-c/src/command/dir.c_v  $ */
  31. /* $Log:   C:/dos-c/src/command/dir.c_v  $ 
  32.  * 
  33.  *    Rev 1.4   31 Jan 1998  8:12:26   patv
  34.  * Put preprocessor switch for version strings and changed log strings
  35.  * 
  36.  *    Rev 1.3   22 Jan 1998  4:51:42   patv
  37.  * Fixed bug in bytes free calculation.
  38.  * 
  39.  *    Rev 1.2   29 Aug 1996 13:07:00   patv
  40.  * Bug fixes for v0.91b
  41.  * 
  42.  *    Rev 1.1   01 Sep 1995 18:04:32   patv
  43.  * First GPL release.
  44.  * 
  45.  *    Rev 1.0   02 Jul 1995 10:01:40   patv
  46.  * Initial revision.
  47.  */
  48. /* $EndLog$ */
  49. #include "../../hdr/portab.h"
  50. #include "globals.h"
  51. #include "proto.h"
  52. #ifdef VERSION_STRINGS
  53. static BYTE *RcsId = "$Header:   C:/dos-c/src/command/dir.c_v   1.4   31 Jan 1998  8:12:26   patv  $";
  54. #endif
  55. #ifdef PROTO
  56. COUNT chk_line(COUNT);
  57. #else
  58. COUNT chk_line();
  59. #endif
  60. #define D_ALL D_NORMAL | D_RDONLY | D_HIDDEN | D_SYSTEM | D_DIR | D_ARCHIVE
  61. BOOL dir(argc, argv)
  62. COUNT argc;
  63. BYTE *argv[];
  64. {
  65. WORD count = 0, disp_line, columns = 0;
  66. ULONG total = 0l;
  67. BYTE vid[67], *ext;
  68. BYTE cudir[67];
  69. BYTE sdrive[2];
  70. dmatch dmp;
  71. COUNT at_mask, at_pat;
  72. UCOUNT free_clst, sec_size, clst_size, n_clst;
  73. BOOL wflag, pflag, lflag, bflag;
  74. COUNT driveno = -1, cudrvno;
  75. BYTE pattern[MAX_CMDLINE] = "", formatted[MAX_CMDLINE];
  76. BYTE path[MAX_CMDLINE] = "", sopt[MAX_CMDLINE] = "";
  77. /* parse for options */
  78. wflag = pflag = lflag = bflag = count = FALSE;
  79. dosopt("$d$p*[a:wplb]+", (BYTE FAR *)tail,
  80. &driveno, path, pattern, sopt, &wflag, &pflag, &lflag, &bflag);
  81. /* Set defaults for file name and path if not supplied. */
  82. if(strcmp(path, "") == 0)
  83. strcpy(path, ".");
  84. if(strcmp(pattern,"") == 0)
  85. strcpy(pattern,"*.*");
  86. /* Intialize the dta to put the dir info into */
  87. DosSetDta((BYTE FAR *)&dmp);
  88. /* Get the current drive, so we can switch back. */
  89. cudrvno = DosGetDrive();
  90. /* Switch to the requested directory to list */
  91. DosSetDrive(driveno < 0 ? cudrvno : driveno);
  92. /* Get the current directory. Note that the DOS system call */
  93. /* does not return drive or leading '', so we need to add */
  94. /* them. */
  95. cudir[0] = '\';
  96. DosPwd(DosGetDrive() + 1, (BYTE FAR *)&cudir[1]);
  97. /* Change to the path and then test the file name. If it is a */
  98. /* directory, switch to it, because the user wants a listing of */
  99. /* its content. */
  100. if(DosCd((BYTE FAR *)path) != SUCCESS)
  101. {
  102. error_message(INV_DIR);
  103. DosSetDrive(cudrvno);
  104. return FALSE;
  105. }
  106. if(!iswild(pattern))
  107. {
  108. if(DosFindFirst(D_DIR, (BYTE FAR *)pattern) != SUCCESS)
  109. {
  110. error_message(FILE_NOT_FOUND);
  111. return TRUE;
  112. }
  113. else
  114. {
  115. if(dmp.dm_attr_fnd & D_DIR)
  116. {
  117. if(DosCd((BYTE FAR *)pattern) != SUCCESS)
  118. {
  119. error_message(INV_DIR);
  120. DosSetDrive(cudrvno);
  121. return FALSE;
  122. }
  123. else
  124. strcpy(pattern, "*.*");
  125. }
  126. }
  127. }
  128. /* Get the new directory. */
  129. path[0] = '\';
  130. DosPwd(DosGetDrive() + 1, (BYTE FAR *)&path[1]);
  131. /* Intialize the dta to put the dir info into */
  132. DosSetDta((BYTE FAR *)&dmp);
  133. /* Get the volume label */
  134. if(DosFindFirst(D_VOLID, (BYTE FAR *)"*.*") != SUCCESS)
  135. sprintf(vid, "has no label");
  136. else
  137. {
  138. for(ext = dmp.dm_name; *ext != NULL; ext++)
  139. if(*ext == '.')
  140. {
  141. *ext++ = NULL;
  142. break;
  143. }
  144. sprintf(vid, "is %s%s", dmp.dm_name, ext);
  145. }
  146. /* Display the header, if not turned off */
  147. sdrive[0] = 'A' + DosGetDrive();
  148. sdrive[1] = NULL;
  149. if(bflag)
  150. disp_line = 0;
  151. else
  152. disp_line = 4;
  153. if(!bflag)
  154. {
  155. printf("n Volume in drive %s %sn", sdrive, vid);
  156. printf(" Directory of %s:%snn", sdrive, path);
  157. }
  158. /* Build the attribute mask and pattern */
  159. at_mask = *sopt == '' ? D_RDONLY | D_HIDDEN | D_SYSTEM : 0;
  160. at_pat = 0;
  161. for(ext = sopt; *ext != ''; ++ext)
  162. {
  163. if(*ext == '-')
  164. {
  165. ++ext;
  166. switch(tolower(*ext))
  167. {
  168. case 'a':
  169. at_mask |= D_ARCHIVE;
  170. at_pat &= ~D_ARCHIVE;
  171. break;
  172. case 'd':
  173. at_mask |= D_DIR;
  174. at_pat &= ~D_DIR;
  175. break;
  176. case 'r':
  177. at_mask |= D_RDONLY;
  178. at_pat &= ~D_RDONLY;
  179. break;
  180. case 'h':
  181. at_mask |= D_HIDDEN;
  182. at_pat &= ~D_HIDDEN;
  183. break;
  184. case 's':
  185. at_mask |= D_SYSTEM;
  186. at_pat &= ~D_SYSTEM;
  187. break;
  188. }
  189. }
  190. else
  191. {
  192. switch(tolower(*ext))
  193. {
  194. case 'a':
  195. at_mask |= D_ARCHIVE;
  196. at_pat |= D_ARCHIVE;
  197. break;
  198. case 'd':
  199. at_mask |= D_DIR;
  200. at_pat |= D_DIR;
  201. break;
  202. case 'r':
  203. at_mask |= D_RDONLY;
  204. at_pat |= D_RDONLY;
  205. break;
  206. case 'h':
  207. at_mask |= D_HIDDEN;
  208. at_pat |= D_HIDDEN;
  209. break;
  210. case 's':
  211. at_mask |= D_SYSTEM;
  212. at_pat |= D_SYSTEM;
  213. break;
  214. }
  215. }
  216. }
  217. if(DosFindFirst(D_ALL, (BYTE FAR *)pattern) != SUCCESS)
  218. {
  219. error_message(FILE_NOT_FOUND);
  220. return TRUE;
  221. }
  222. if(wflag)
  223. {
  224. do
  225. {
  226. char *p;
  227. if((*sopt != 0) && !((dmp.dm_attr_fnd & at_mask) == at_pat))
  228. continue;
  229. if(dmp.dm_attr_fnd & D_DIR)
  230. {
  231. if(bflag && *dmp.dm_name == '.')
  232. continue;
  233. sprintf(formatted, "[%s]", dmp.dm_name);
  234. if(lflag)
  235. strlwr(formatted);
  236. printf("%-14s ", formatted);
  237. ++columns;
  238. if(columns == 5)
  239. {
  240. if(pflag)
  241. disp_line = chk_line(disp_line);
  242. printf("n");
  243. columns = 0;
  244. }
  245. }
  246. else
  247. {
  248. ext = "   ";
  249. sprintf(formatted, "%s", dmp.dm_name);
  250. if(lflag)
  251. strlwr(formatted);
  252. printf("%-15s",formatted);
  253. ++columns;
  254. if(columns == 5)
  255. {
  256. if(pflag)
  257. disp_line = chk_line(disp_line);
  258. printf("n");
  259. columns = 0;
  260. }
  261. }
  262. ++count;
  263. total += dmp.dm_size;
  264. }
  265. while(DosFindNext() == SUCCESS);
  266. }
  267. else
  268. {
  269. do
  270. {
  271. WORD hour = TM_HOUR(dmp.dm_time);
  272. if((*sopt != 0) && !((dmp.dm_attr_fnd & at_mask) == at_pat))
  273. continue;
  274. if(dmp.dm_name[0] == '.')
  275. ext = "";
  276. else
  277. for(ext = dmp.dm_name; *ext != NULL; ext++)
  278. {
  279. if(*ext == '.')
  280. {
  281. *ext++ = NULL;
  282. break;
  283. }
  284. }
  285. if(lflag)
  286. {
  287. strlwr(dmp.dm_name);
  288. strlwr(ext);
  289. }
  290. if(dmp.dm_attr_fnd & D_DIR)
  291. {
  292. if(bflag && *dmp.dm_name == '.')
  293. continue;
  294. if(pflag)
  295. disp_line = chk_line(disp_line);
  296. printf(bflag ? "n%s.%s" : "n   %8s %3s  <DIR>      %-2d-%-02d-%-02d  %-2d:%-02d%s",
  297. dmp.dm_name, ext,
  298. DT_MONTH(dmp.dm_date),
  299. DT_DAY(dmp.dm_date),
  300. (DT_YEAR(dmp.dm_date) + 1980) % 100,
  301. hour > 12 ? hour - 12 : (hour == 0) ? 12 : hour,
  302. TM_MIN(dmp.dm_time),
  303. hour >= 12 ? "p" : "a");
  304. }
  305. else
  306. {
  307. if(pflag)
  308. disp_line = chk_line(disp_line);
  309. printf(bflag ? "n%s.%s" : "n   %8s %3s %-10ld  %-2d-%-02d-%-02d  %-2d:%-02d%s",
  310. dmp.dm_name, ext, dmp.dm_size,
  311. DT_MONTH(dmp.dm_date),
  312. DT_DAY(dmp.dm_date),
  313. (DT_YEAR(dmp.dm_date) + 1980) % 100,
  314. hour > 12 ? hour - 12 : (hour == 0) ? 12 : hour,
  315. TM_MIN(dmp.dm_time),
  316. hour >= 12 ? "p" : "a");
  317. }
  318. ++count;
  319. total += dmp.dm_size;
  320. }
  321. while(DosFindNext() == SUCCESS);
  322. }
  323. /* /b does not print any statistics */
  324. if(bflag)
  325. {
  326. printf("nn");
  327. }
  328. else
  329. /* Now print the available free bytes (It's really clusters */
  330. /* translated to bytes. */
  331. {
  332. DosFree(0, (COUNT FAR *)&clst_size,(COUNT FAR *) &free_clst, (COUNT FAR *)&sec_size, (COUNT FAR *)&n_clst);
  333. printf("n  %-10d file(s)   %-10ld bytesn", count, total);
  334. printf(  "                       %-10lu bytes freenn",
  335. (ULONG)free_clst
  336. * (ULONG)sec_size
  337. * (ULONG)clst_size);
  338. }
  339. /* Change back to the current drive and directory, so that we */
  340. /* look like we just did a listing without all the gymnastics. */
  341. if((DosCd((BYTE FAR *)cudir)) != SUCCESS)
  342. {
  343. DosSetDrive(cudrvno);
  344. error_message(INV_DIR);
  345. return FALSE;
  346. }
  347. else
  348. {
  349. DosSetDrive(cudrvno);
  350. return TRUE;
  351. }
  352. }
  353. static COUNT chk_line(disp_line)
  354. COUNT disp_line;
  355. {
  356. BYTE line[MAX_CMDLINE];
  357. if(disp_line == 23)
  358. {
  359. printf("nStrike a key when ready . . .");
  360. DosRead(STDIN, line, MAX_CMDLINE);
  361. return 0;
  362. }
  363. return ++disp_line;
  364. }