dirutil.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:8k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* dirutil.c - MS-DOS directory reading routines
  2.  *
  3.  * Bdale Garbee, N3EUA, Dave Trulli, NN2Z, and Phil Karn, KA9Q
  4.  * Directory sorting by Mike Chepponis, K3MC
  5.  * New version using regs.h by Russell Nelson.
  6.  * Rewritten for Turbo-C 2.0 routines by Phil Karn, KA9Q 25 March 89
  7.  */
  8. #include <stdio.h>
  9. #include <dir.h>
  10. #include <dos.h>
  11. #include <stdlib.h>
  12. #include "global.h"
  13. #include "dirutil.h"
  14. #include "proc.h"
  15. #include "commands.h"
  16. struct dirsort {
  17. struct dirsort *next;
  18. struct ffblk de;
  19. };
  20. #define NULLSORT (struct dirsort *)0
  21. static void commas(char *dest);
  22. static int fncmp(char *a, char *b);
  23. static void format_fname_full(FILE *file,struct ffblk *sbuf,int full,
  24. int n);
  25. static void free_clist(struct dirsort *this);
  26. #ifdef notdef
  27. static int getdir_nosort(char *path,int full,FILE *file);
  28. #endif
  29. static int nextname(int command, char *name, struct ffblk *sbuf);
  30. static void print_free_space(FILE *file,int n);
  31. static void undosify(char *s);
  32. static char *wildcardize(char *path);
  33. #define REGFILE (FA_HIDDEN|FA_SYSTEM|FA_DIREC)
  34. #define insert_ptr(list,new) (new->next = list,list = new)
  35. /* Create a directory listing in a temp file and return the resulting file
  36.  * descriptor. If full == 1, give a full listing; else return just a list
  37.  * of names.
  38.  */
  39. FILE *
  40. dir(path,full)
  41. char *path;
  42. int full;
  43. {
  44. FILE *fp;
  45. if((fp = tmpfile()) != NULL){
  46. getdir(path,full,fp);
  47. rewind(fp);
  48. }
  49. return fp;
  50. }
  51. /* find the first or next file and lowercase it. */
  52. static int
  53. nextname(command, name, sbuf)
  54. int command;
  55. char *name;
  56. struct ffblk *sbuf;
  57. {
  58. int found;
  59. switch(command){
  60. case 0:
  61. found = findfirst(name,sbuf,REGFILE);
  62. break;
  63. default:
  64. found = findnext(sbuf);
  65. }
  66. found = found == 0;
  67. if(found)
  68. strlwr(sbuf->ff_name);
  69. return found;
  70. }
  71. /* wildcard filename lookup */
  72. int
  73. filedir(name,times,ret_str)
  74. char *name;
  75. int times;
  76. char *ret_str;
  77. {
  78. static struct ffblk sbuf;
  79. int rval;
  80. switch(times){
  81. case 0:
  82. rval = findfirst(name,&sbuf,REGFILE);
  83. break;
  84. default:
  85. rval = findnext(&sbuf);
  86. break;
  87. }
  88. if(rval == -1){
  89. ret_str[0] = '';
  90. } else {
  91. /* Copy result to output */
  92. strcpy(ret_str, sbuf.ff_name);
  93. }
  94. return rval;
  95. }
  96. /* do a directory list to the stream 
  97.  * full = 0 -> short form, 1 is long
  98. */
  99. int
  100. getdir(path,full,file)
  101. char *path;
  102. int full;
  103. FILE *file;
  104. {
  105. struct ffblk sbuf;
  106. int command = 0;
  107. int n = 0;
  108. struct dirsort *head, *here, *new;
  109. path = wildcardize(path);
  110. head = NULLSORT; /* No head of chain yet... */
  111. for(;;){
  112. if (!nextname(command, path, &sbuf))
  113. break;
  114. command = 1; /* Got first one already... */
  115. if (sbuf.ff_name[0] == '.') /* drop "." and ".." */
  116. continue;
  117. new = (struct dirsort *) mallocw(sizeof(struct dirsort));
  118. new->de = sbuf; /* Copy contents of directory entry struct */
  119. /* insert it into the list */
  120. if (!head || fncmp(new->de.ff_name, head->de.ff_name) < 0) {
  121. insert_ptr(head, new);
  122. } else {
  123. register struct dirsort *this;
  124. for (this = head;
  125.     this->next != NULLSORT;
  126.     this = this->next)
  127. if (fncmp(new->de.ff_name, this->next->de.ff_name) < 0)
  128. break;
  129. insert_ptr(this->next, new);
  130. }
  131. } /* infinite FOR loop */
  132. for (here = head; here; here = here->next)
  133. format_fname_full(file,&here->de,full,++n);
  134. /* Give back all the memory we temporarily needed... */
  135. free_clist(head);
  136. if(full)
  137. print_free_space(file, n);
  138. return 0;
  139. }
  140. static int
  141. fncmp(a,b)
  142. register char *a, *b;
  143. {
  144.         int i;
  145. for(;;){
  146. if (*a == '.')
  147. return -1;
  148. if (*b == '.')
  149. return 1;
  150. if ((i = *a - *b++) != 0)
  151. return i;
  152. if (!*a++)
  153. return -1;
  154. }
  155. }
  156. /* Change working directory */
  157. int
  158. docd(argc,argv,p)
  159. int argc;
  160. char *argv[];
  161. void *p;
  162. {
  163. char dirname[128];
  164. if(argc > 1){
  165. if(chdir(argv[1]) == -1){
  166. printf("Can't change directoryn");
  167. return 1;
  168. }
  169. }
  170. if(getcwd(dirname,128) != NULL){
  171. undosify(dirname);
  172. printf("%sn",dirname);
  173. }
  174. return 0;
  175. }
  176. /* List directory to console */
  177. int
  178. dodir(argc,argv,p)
  179. int argc;
  180. char *argv[];
  181. void *p;
  182. {
  183. char *path;
  184. if(argc >= 2)
  185. path = argv[1];
  186. else
  187. path = "*.*";
  188. getdir(path,1,stdout);
  189. return 0;
  190. }
  191. /* Create directory */
  192. int
  193. domkd(argc,argv,p)
  194. int argc;
  195. char *argv[];
  196. void *p;
  197. {
  198. if(mkdir(argv[1]) == -1)
  199. perror("Can't mkdir");
  200. return 0;
  201. }
  202. /* Remove directory */
  203. int
  204. dormd(argc,argv,p)
  205. int argc;
  206. char *argv[];
  207. void *p;
  208. {
  209. if(rmdir(argv[1]) == -1)
  210. perror("Can't rmdir");
  211. return 0;
  212. }
  213. /*
  214.  * Return a string with commas every 3 positions.
  215.  * the original string is replace with the string with commas.
  216.  *
  217.  * The caller must be sure that there is enough room for the resultant
  218.  * string.
  219.  *
  220.  *
  221.  * k3mc 4 Dec 87
  222.  */
  223. static void
  224. commas(dest)
  225. char *dest;
  226. {
  227. char *src, *core; /* Place holder for malloc */
  228. unsigned cc; /* The comma counter */
  229. unsigned len;
  230. len = strlen(dest);
  231. /* Make a copy, so we can muck around */
  232. core = src = strdup(dest);
  233. cc = (len-1)%3 + 1; /* Tells us when to insert a comma */
  234. while(*src != ''){
  235. *dest++ = *src++;
  236. if( ((--cc) == 0) && *src ){
  237. *dest++ = ','; cc = 3;
  238. }
  239. }
  240. free(core);
  241. *dest = '';
  242. }
  243. /* fix up the filename so that it contains the proper wildcard set */
  244. static char *
  245. wildcardize(path)
  246. char *path;
  247. {
  248. struct ffblk sbuf;
  249. static char ourpath[64];
  250. /* Root directory is a special case */
  251. if(path == NULL ||
  252.    *path == '' ||
  253.    strcmp(path,"\") == 0 ||
  254.    strcmp(path,"/") == 0)
  255. path = "\*.*";
  256. /* if they gave the name of a subdirectory, append *.* to it */
  257. if (nextname(0, path, &sbuf) &&
  258.     (sbuf.ff_attrib & FA_DIREC) &&
  259.     !nextname(1, path, &sbuf)) {
  260. /* if there isn't enough room, give up -- it's invalid anyway */
  261. if (strlen(path) + 4 > 63) return path;
  262. strcpy(ourpath, path);
  263. strcat(ourpath, "\*.*");
  264. return ourpath;
  265. }
  266. return path;
  267. }
  268. static void
  269. format_fname_full(file, sbuf, full, n)
  270. FILE *file;
  271. struct ffblk *sbuf;
  272. int full, n;
  273. {
  274. char line_buf[50]; /* for long dirlist */
  275. char cbuf[20]; /* for making line_buf */
  276. strcpy(cbuf,sbuf->ff_name);
  277. if(sbuf->ff_attrib & FA_DIREC) strcat(cbuf, "/");
  278. if (full) {
  279. /* Long form, give other info too */
  280. sprintf(line_buf,"%-13s",cbuf);
  281. if(sbuf->ff_attrib & FA_DIREC)
  282. strcat(line_buf,"           ");/* 11 spaces */
  283. else {
  284. sprintf(cbuf,"%ld",sbuf->ff_fsize);
  285. commas(cbuf);
  286. sprintf(line_buf+strlen(line_buf),"%10s ",cbuf);
  287. }
  288. sprintf(line_buf+strlen(line_buf),"%2d:%02d %2d/%02d/%02d%s",
  289.   (sbuf->ff_ftime >> 11) & 0x1f, /* hour */
  290.   (sbuf->ff_ftime >> 5) & 0x3f, /* minute */
  291.   (sbuf->ff_fdate >> 5) & 0xf, /* month */
  292.   (sbuf->ff_fdate ) & 0x1f, /* day */
  293.   (sbuf->ff_fdate >> 9) + 80, /* year */
  294.   (n & 1) ? "   " : "n");
  295. fputs(line_buf,file);
  296. } else {
  297. fputs(cbuf,file);
  298. fputs("n",file);
  299. }
  300. }
  301. /* Provide additional information only on DIR */
  302. static void
  303. print_free_space(file, n)
  304. FILE *file;
  305. int n;
  306. {
  307. unsigned long free_bytes, total_bytes;
  308. char s_free[11], s_total[11];
  309. char cbuf[20];
  310. struct dfree dtable;
  311. unsigned long bpcl;
  312. if(n & 1)
  313. fputs("n",file);
  314. /* Find disk free space */
  315. getdfree(0,&dtable);
  316. bpcl = dtable.df_bsec * dtable.df_sclus;
  317. free_bytes  = dtable.df_avail * bpcl;
  318. total_bytes = dtable.df_total * bpcl;
  319. sprintf(s_free,"%ld",free_bytes);
  320. commas(s_free);
  321. sprintf(s_total,"%ld",total_bytes);
  322. commas(s_total);
  323. if(n)
  324. sprintf(cbuf,"%d",n);
  325. else
  326. strcpy(cbuf,"No");
  327. fprintf(file,"%s file%s. %s bytes free. Disk size %s bytes.n",
  328. cbuf,(n==1? "":"s"),s_free,s_total);
  329. }
  330. static void
  331. free_clist(this)
  332. struct dirsort *this;
  333. {
  334. struct dirsort *next;
  335. while (this != NULLSORT) {
  336. next = this->next;
  337. free(this);
  338. this = next;
  339. }
  340. }
  341. #ifdef notdef
  342. static int
  343. getdir_nosort(path,full,file)
  344. char *path;
  345. int full;
  346. FILE *file;
  347. {
  348. struct ffblk sbuf;
  349. int command;
  350. int n = 0; /* Number of directory entries */
  351. path = wildcardize(path);
  352. command = 0;
  353. while(nextname(command, path, &sbuf)){
  354. command = 1; /* Got first one already... */
  355. if (sbuf.ff_name[0] == '.') /* drop "." and ".." */
  356. continue;
  357. format_fname_full(file, &sbuf, full, ++n);
  358. }
  359. if(full)
  360. print_free_space(file, n);
  361. return 0;
  362. }
  363. #endif
  364. /* Translate those %$#@!! backslashes to proper form */
  365. static void
  366. undosify(s)
  367. char *s;
  368. {
  369. while(*s != ''){
  370. if(*s == '\')
  371. *s = '/';
  372. s++;
  373. }
  374. }