dirsf.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /*
  2. * Copyright (c) 1983-2023 Martin Atkins, Richard Dobson and Composers Desktop Project Ltd
  3. * http://people.bath.ac.uk/masrwd
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. /*
  22. * Sound Filing System Utility - Directory
  23. *
  24. * Copyright M. C. Atkins, 1986, 1987
  25. * All Rights Reserved.
  26. */
  27. /* RWD identify B-Format files */
  28. /*
  29. * $Log: dirsf.c%v $
  30. * Revision 4.1 1.99 RWD full sfsysEx version: support all formats
  31. * Revision 4.0 8.98 RWD
  32. * add -h and -? flags, adapt -d usage for Win32
  33. * link with sfsys97 for all cdp extensions
  34. * Revision 3.5 1994/11/12 20:09:02 martin
  35. * Fix rcs string
  36. *
  37. * Revision 3.4 1994/10/31 16:52:56 martin
  38. * Make rcs version number consistent with released versions
  39. *
  40. * Revision 1.1 1994/10/31 16:49:56 martin
  41. * Initial revision
  42. *
  43. */
  44. /*****
  45. * RWD OCT97: Revision 3.6: under CDP97 (sfsys97.lib) recompile to recognize 8bit sfiles
  46. * RWD FEB98: recognise WIN32 shortcuts. Gives name of shortcut (with .lnk extension),
  47. * but statistics of the aliased file. Don't know what to do if the shortcut name's unrelated to the
  48. * target - not enough room on a console for two filenames!
  49. * RWD.9.98 removed -p option (for WIN32) - Atari-death!
  50. * RWD.6.99 link with sfsysEx, report many more formats!
  51. * RWD 8.09 fixed report of length > 2GB (sfsysEx64)
  52. * JAN 2013 rebuild with fixed getsfsysadtl bug in sfsys (sfsys2010)
  53. *****/
  54. #include <stdio.h>
  55. #include <stdlib.h>
  56. #include <time.h>
  57. #include <string.h>
  58. #if defined(_WIN32) || defined(__SC__)
  59. #include <direct.h>
  60. #include <ctype.h>
  61. #endif
  62. #ifdef unix
  63. #include <unistd.h>
  64. #endif
  65. #include <sfsys.h>
  66. #include "sffuncs.h"
  67. #include "wildcard.h"
  68. static char *VERSION = "DIRSF: Revision 7.0 (c) 1999,2005,2014 CDP";
  69. char cdp_ver_str[]="~CDPVER~dirsf $Revision: 7.0 1999,2005,2009,2014 $";
  70. char longhdr[] = "Bytes\t\tChannel\tSample\tRate\tSeconds\tfmt Name\n\n";
  71. /* char posnhdr[] = "Flags\tFirst\tSectors\tName\n\n"; */
  72. /* char sdisk[] = "\t%d\t\t---- start of disk: device %d sector %d\n"; */
  73. int SFCALLS lpr(struct sf_direct *);
  74. /*int SFCALLS pospr(struct sf_direct *);*/
  75. int SFCALLS pr(struct sf_direct *);
  76. int SFCALLS tpr(struct sf_direct *);
  77. int preflg = 0; /* all prefixes flag */
  78. int prefix_set = 0; /* there currently is a prefix set */
  79. struct filename {
  80. struct wildcard *pat; /* non-zero => pattern */
  81. char *pic; /* argv string */
  82. struct filename *next; /* chained up */
  83. };
  84. struct filename *filelist = 0;
  85. struct rdskcfg cfg;
  86. struct partinfo *pi = &cfg.pinfo[0];
  87. #define FSTVERWPREF (0x201L)
  88. void
  89. usage(void)
  90. {
  91. fprintf(stderr,
  92. #ifdef ATARI
  93. "usage: dirsf [-g][-l or -p or -t] [-d prefix] [filespec ...]\n");
  94. #else
  95. "\n%s\nusage: dirsf [-l or -t] [-d path] [filespec ...]\n",VERSION);
  96. #endif
  97. #ifdef ATARI
  98. fprintf(stderr, "\tg - list files with all prefixes\n");
  99. #endif
  100. fprintf(stderr, "\tl - list names only\n");
  101. fprintf(stderr, "\tt - list modification dates and times\n");
  102. #ifdef ATARI
  103. fprintf(stderr, "\td - list only files with the given prefix\n");
  104. #else
  105. fprintf(stderr, "\td - list files in directory path\n");
  106. #endif
  107. exit(1);
  108. }
  109. void
  110. isprefix(void)
  111. {
  112. char buf[MAXPREFIX];
  113. sfgetprefix(buf);
  114. prefix_set = (buf[0] != '\0');
  115. }
  116. void
  117. mkfilelist(char **argv)
  118. {
  119. struct filename **thisp = &filelist;
  120. while(*argv != 0) {
  121. if((*thisp = (struct filename *)
  122. malloc(sizeof(struct filename))) == 0) {
  123. fprintf(stderr, "dirsf: can't get memory for file list\n");
  124. exit(1);
  125. }
  126. (*thisp)->next = 0;
  127. (*thisp)->pic = *argv;
  128. if(!iswildcard(*argv))
  129. (*thisp)->pat = 0;
  130. else if(((*thisp)->pat = wildcomp(*argv)) == 0) {
  131. fprintf(stderr, "dirsf: can't compile pattern %s\n", *argv);
  132. exit(1);
  133. }
  134. thisp = &(*thisp)->next;
  135. argv++;
  136. }
  137. }
  138. PROGRAM_NUMBER(0x94589004);
  139. int
  140. main(int argc, char *argv[])
  141. {
  142. int rc = SFDIR_NOTFOUND; /* a guess, to suppress warning */
  143. int option = 0;
  144. #if defined(_WIN32) || defined(__SC__)
  145. int cded = 0; /* did we cd? */
  146. char opath[MAXPREFIX];
  147. int olddrive = 0;
  148. int newdrive = 0;
  149. char *dircp = 0;
  150. #endif
  151. if(sflinit("dirsf")) {
  152. sfperror("dirsf: initialisation");
  153. exit(1);
  154. }
  155. if(sfverno() < FSTVERWPREF)
  156. fprintf(stderr, "cdfs: warning, installed sfsys does not support prefixes\n");
  157. isprefix();
  158. #ifdef ATARI
  159. if(argc > 1 && strcmp(argv[1], "-g") == 0) {
  160. preflg = SFDIR_IGPREFIX;
  161. argc--;
  162. argv++;
  163. }
  164. #endif
  165. if(argc > 1 && argv[1][0] == '-')
  166. switch(argv[1][1]) {
  167. case 'l':
  168. case 't':
  169. option = argv[1][1];
  170. argc--;
  171. argv++;
  172. break;
  173. case 'd':
  174. break;
  175. case 'h': //RWD 7.98
  176. case '?':
  177. usage();
  178. default:
  179. usage();
  180. }
  181. if(argc > 1 && strcmp(argv[1], "-d") == 0) {
  182. if(argc < 3)
  183. usage();
  184. #if defined(unix)
  185. if(chdir(argv[2]) < 0) {
  186. fprintf(stderr, "dirsf: can't change directory\n");
  187. exit(1);
  188. }
  189. #elif defined(_WIN32) || defined(__SC__)
  190. olddrive = _getdrive();
  191. if(argv[2][1] == ':') {
  192. newdrive = toupper(argv[2][0]) - 'A' + 1;
  193. dircp = &argv[2][2];
  194. } else {
  195. newdrive = olddrive;
  196. dircp = &argv[2][0];
  197. }
  198. if(_chdrive(newdrive) < 0
  199. ||_getcwd(opath, MAXPREFIX) == NULL
  200. ||((dircp[0] != '\0') ? _chdir(dircp) : 0) < 0) {
  201. fprintf(stderr, "dirsf: error changing current directory\n");
  202. exit(1);
  203. }
  204. cded++;
  205. #else
  206. #error "Unknown system"
  207. #endif
  208. argc -= 2;
  209. argv += 2;
  210. }
  211. if(argc > 1)
  212. mkfilelist(&argv[1]);
  213. switch(option) {
  214. case 0:
  215. printf("Sfsys Version %x.%02x\n", (unsigned int)(sfverno()>>8), (unsigned int)(sfverno()&0xff));
  216. puts( longhdr);
  217. rc = sfdir(lpr, SFDIR_USED|preflg);
  218. break;
  219. case 'l':
  220. rc = sfdir(pr, SFDIR_USED|preflg);
  221. break;
  222. case 't':
  223. rc = sfdir(tpr, SFDIR_USED|preflg);
  224. break;
  225. default:
  226. usage();
  227. }
  228. #if defined(_WIN32) || defined(__SC__)
  229. if(cded) {
  230. if(_chdir(opath) < 0
  231. ||_chdrive(olddrive) < 0)
  232. fprintf(stderr, "dirsf: can't restore current path\n");
  233. }
  234. #endif
  235. if(rc != SFDIR_NOTFOUND) {
  236. sfperror("dirsf");
  237. exit(1);
  238. }
  239. // sffinish();
  240. return 0;
  241. }
  242. /*
  243. * do we want this file?
  244. */
  245. int
  246. dofile(char *name)
  247. {
  248. char *basename;
  249. struct filename *this;
  250. if(filelist == 0)
  251. return 1;
  252. if((basename = strrchr(name, '\\')) != 0)
  253. basename++;
  254. else
  255. basename = name;
  256. for(this = filelist; this != 0; this = this->next) {
  257. if(this->pat != 0) {
  258. if(wildmatch(prefix_set ? basename : name, this->pat))
  259. return 1;
  260. } else if(strcmp(this->pic, basename) == 0)
  261. return 1;
  262. }
  263. return 0;
  264. }
  265. /*
  266. * Just print the filename
  267. */
  268. int SFCALLS
  269. pr(struct sf_direct *dirp)
  270. {
  271. if(dofile(dirp->name)) {
  272. #ifdef _WIN32
  273. if(dirp->is_shortcut)
  274. printf("%s\t\t%s\n",dirp->name,dirp->targetname);
  275. else
  276. #endif
  277. printf("%s\n", dirp->name);
  278. }
  279. return 0;
  280. }
  281. /*
  282. * Get the date/time for a file
  283. */
  284. int
  285. getdateprop(char *name, unsigned int *timep)
  286. {
  287. int rc;
  288. int sfd = sndopenEx(name,0,CDP_OPEN_RDONLY);
  289. if(sfd < 0)
  290. return 0;
  291. rc = sndgetprop(sfd, "DATE", (char *)timep, sizeof(int)) == sizeof(int);
  292. sndcloseEx(sfd);
  293. return rc;
  294. }
  295. /*
  296. * Print date/time and name
  297. */
  298. int SFCALLS
  299. tpr(struct sf_direct *dirp)
  300. {
  301. time_t time;
  302. unsigned int cdptime;
  303. char *times;
  304. if(!dofile(dirp->name))
  305. return 0;
  306. if(getdateprop(dirp->name, &cdptime)) {
  307. time = (time_t) cdptime;
  308. times = ctime(&time);
  309. times[24] = '\0';
  310. printf("%-26s\t", times);
  311. } else
  312. printf("%-26s\t", "-");
  313. #ifdef _WIN32
  314. if(dirp->is_shortcut)
  315. printf("%s\t%s\n",dirp->name,dirp->targetname);
  316. else
  317. #endif
  318. printf("%s\n", dirp->name);
  319. return 0;
  320. }
  321. /*
  322. * print long information
  323. */
  324. int SFCALLS
  325. lpr(struct sf_direct *p)
  326. {
  327. int nosec = 0;
  328. int scale = 0;
  329. if(!dofile(p->name))
  330. return 0;
  331. if(p->flags == SFFLG_IOERROR) /* RWD Aug 2009 solve the unsigned issue here */
  332. printf("%d\t",-1);
  333. else
  334. printf("%9u\t", p->length); /*RWD Aug 2009: print as unsigned! */
  335. switch(p->nochans) {
  336. case '1':
  337. printf("mono\t");
  338. break;
  339. case '2':
  340. printf("stereo\t");
  341. break;
  342. default:
  343. if(p->nochans < 0) {
  344. printf("-\t");
  345. nosec++;
  346. } else
  347. printf("%d\t", p->nochans);
  348. break;
  349. }
  350. switch(p->samptype) {
  351. case SAMP_SHORT:
  352. if(p->origwordsize==8)
  353. printf("8bit \t");
  354. else
  355. printf("short\t");
  356. scale = sizeof(short); //RWD: keep until I fully define SAMP_BYTE
  357. break;
  358. case SAMP_FLOAT:
  359. printf("float\t");
  360. scale = sizeof(float);
  361. break;
  362. case SAMP_LONG:
  363. printf("long\t");
  364. scale = sizeof(long);
  365. break;
  366. case SAMP_2424:
  367. printf("24(p) \t");
  368. scale = 3;
  369. break;
  370. case SAMP_2432:
  371. printf("24:32\t");
  372. scale = sizeof(long);
  373. break;
  374. case SAMP_2024:
  375. printf("20:24\t");
  376. scale = 3;
  377. break;
  378. default:
  379. if(p->samptype < 0)
  380. printf("-\t");
  381. else
  382. printf("?\t");
  383. nosec++;
  384. break;
  385. }
  386. if(p->samprate > 0)
  387. printf("%5d\t", p->samprate);
  388. else {
  389. printf("-\t");
  390. nosec++;
  391. }
  392. if(nosec)
  393. printf("-\t");
  394. else {
  395. float time = (float)p->length;
  396. if(p->origwordsize==8)
  397. time *= 2.0f;
  398. time /= (float)(scale * p->nochans * p->samprate);
  399. printf("%7.3f\t", time);
  400. }
  401. if(p->fmt== WAVE)
  402. printf(" W ");
  403. else if(p->fmt== WAVE_EX) {
  404. channelformat fmt = -1;
  405. int sfd;
  406. sfd = sndopenEx(p->name,0,CDP_OPEN_RDONLY);
  407. if(sfd >=0){
  408. snd_getchanformat(sfd, &fmt);
  409. if(fmt >=0){
  410. if(fmt==MC_BFMT)
  411. printf(" WB ");
  412. else
  413. printf(" WX ");
  414. }
  415. sndcloseEx(sfd);
  416. }
  417. else
  418. printf(" WX ");
  419. }
  420. else if(p->fmt==AIFF)
  421. printf(" A ");
  422. else if(p->fmt==AIFC)
  423. printf(" AC ");
  424. #ifdef ENABLE_PVX
  425. else if(p->fmt==PVOCEX)
  426. printf(" PX ");
  427. #endif
  428. else //FMT_UNKNOWN
  429. printf(" ? ");
  430. printf("%s\n", p->name);
  431. return 0;
  432. }