|
|
@@ -0,0 +1,479 @@
|
|
|
+/*
|
|
|
+ * Copyright (c) 1983-2023 Martin Atkins, Richard Dobson and Composers Desktop Project Ltd
|
|
|
+ * http://people.bath.ac.uk/masrwd
|
|
|
+ * http://www.composersdesktop.com
|
|
|
+ *
|
|
|
+ This file is part of the CDP System.
|
|
|
+
|
|
|
+ The CDP System is free software; you can redistribute it
|
|
|
+ and/or modify it under the terms of the GNU Lesser General Public
|
|
|
+ License as published by the Free Software Foundation; either
|
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
|
+
|
|
|
+ The CDP System is distributed in the hope that it will be useful,
|
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
+ GNU Lesser General Public License for more details.
|
|
|
+
|
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
|
+ License along with the CDP System; if not, write to the Free Software
|
|
|
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
|
+ 02111-1307 USA
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+/*
|
|
|
+ * Sound Filing System Utility - Directory
|
|
|
+ *
|
|
|
+ * Copyright M. C. Atkins, 1986, 1987
|
|
|
+ * All Rights Reserved.
|
|
|
+ */
|
|
|
+/* RWD identify B-Format files */
|
|
|
+
|
|
|
+/*
|
|
|
+ * $Log: dirsf.c%v $
|
|
|
+
|
|
|
+
|
|
|
+ * Revision 4.1 1.99 RWD full sfsysEx version: support all formats
|
|
|
+
|
|
|
+ * Revision 4.0 8.98 RWD
|
|
|
+ * add -h and -? flags, adapt -d usage for Win32
|
|
|
+ * link with sfsys97 for all cdp extensions
|
|
|
+
|
|
|
+
|
|
|
+ * Revision 3.5 1994/11/12 20:09:02 martin
|
|
|
+ * Fix rcs string
|
|
|
+ *
|
|
|
+ * Revision 3.4 1994/10/31 16:52:56 martin
|
|
|
+ * Make rcs version number consistent with released versions
|
|
|
+ *
|
|
|
+ * Revision 1.1 1994/10/31 16:49:56 martin
|
|
|
+ * Initial revision
|
|
|
+ *
|
|
|
+ */
|
|
|
+/*****
|
|
|
+
|
|
|
+ * RWD OCT97: Revision 3.6: under CDP97 (sfsys97.lib) recompile to recognize 8bit sfiles
|
|
|
+ * RWD FEB98: recognise WIN32 shortcuts. Gives name of shortcut (with .lnk extension),
|
|
|
+ * but statistics of the aliased file. Don't know what to do if the shortcut name's unrelated to the
|
|
|
+ * target - not enough room on a console for two filenames!
|
|
|
+ * RWD.9.98 removed -p option (for WIN32) - Atari-death!
|
|
|
+ * RWD.6.99 link with sfsysEx, report many more formats!
|
|
|
+ * RWD 8.09 fixed report of length > 2GB (sfsysEx64)
|
|
|
+ * JAN 2013 rebuild with fixed getsfsysadtl bug in sfsys (sfsys2010)
|
|
|
+ *****/
|
|
|
+
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <time.h>
|
|
|
+#include <string.h>
|
|
|
+#if defined(_WIN32) || defined(__SC__)
|
|
|
+#include <direct.h>
|
|
|
+#include <ctype.h>
|
|
|
+#endif
|
|
|
+#ifdef unix
|
|
|
+#include <unistd.h>
|
|
|
+#endif
|
|
|
+#include <sfsys.h>
|
|
|
+#include "sffuncs.h"
|
|
|
+#include "wildcard.h"
|
|
|
+static char *VERSION = "DIRSF: Revision 7.0 (c) 1999,2005,2014 CDP";
|
|
|
+char cdp_ver_str[]="~CDPVER~dirsf $Revision: 7.0 1999,2005,2009,2014 $";
|
|
|
+
|
|
|
+char longhdr[] = "Bytes\t\tChannel\tSample\tRate\tSeconds\tfmt Name\n\n";
|
|
|
+/* char posnhdr[] = "Flags\tFirst\tSectors\tName\n\n"; */
|
|
|
+/* char sdisk[] = "\t%d\t\t---- start of disk: device %d sector %d\n"; */
|
|
|
+
|
|
|
+int SFCALLS lpr(struct sf_direct *);
|
|
|
+/*int SFCALLS pospr(struct sf_direct *);*/
|
|
|
+int SFCALLS pr(struct sf_direct *);
|
|
|
+int SFCALLS tpr(struct sf_direct *);
|
|
|
+int preflg = 0; /* all prefixes flag */
|
|
|
+int prefix_set = 0; /* there currently is a prefix set */
|
|
|
+
|
|
|
+struct filename {
|
|
|
+ struct wildcard *pat; /* non-zero => pattern */
|
|
|
+ char *pic; /* argv string */
|
|
|
+ struct filename *next; /* chained up */
|
|
|
+};
|
|
|
+
|
|
|
+struct filename *filelist = 0;
|
|
|
+
|
|
|
+struct rdskcfg cfg;
|
|
|
+struct partinfo *pi = &cfg.pinfo[0];
|
|
|
+
|
|
|
+#define FSTVERWPREF (0x201L)
|
|
|
+
|
|
|
+void
|
|
|
+usage()
|
|
|
+{
|
|
|
+ fprintf(stderr,
|
|
|
+#ifdef ATARI
|
|
|
+ "usage: dirsf [-g][-l or -p or -t] [-d prefix] [filespec ...]\n");
|
|
|
+#else
|
|
|
+ "\n%s\nusage: dirsf [-l or -t] [-d path] [filespec ...]\n",VERSION);
|
|
|
+#endif
|
|
|
+#ifdef ATARI
|
|
|
+ fprintf(stderr, "\tg - list files with all prefixes\n");
|
|
|
+#endif
|
|
|
+ fprintf(stderr, "\tl - list names only\n");
|
|
|
+ fprintf(stderr, "\tt - list modification dates and times\n");
|
|
|
+#ifdef ATARI
|
|
|
+ fprintf(stderr, "\td - list only files with the given prefix\n");
|
|
|
+#else
|
|
|
+ fprintf(stderr, "\td - list files in directory path\n");
|
|
|
+#endif
|
|
|
+ exit(1);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+isprefix()
|
|
|
+{
|
|
|
+ char buf[MAXPREFIX];
|
|
|
+
|
|
|
+ sfgetprefix(buf);
|
|
|
+
|
|
|
+ prefix_set = (buf[0] != '\0');
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+mkfilelist(char **argv)
|
|
|
+{
|
|
|
+ struct filename **thisp = &filelist;
|
|
|
+
|
|
|
+ while(*argv != 0) {
|
|
|
+ if((*thisp = (struct filename *)
|
|
|
+ malloc(sizeof(struct filename))) == 0) {
|
|
|
+ fprintf(stderr, "dirsf: can't get memory for file list\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ (*thisp)->next = 0;
|
|
|
+ (*thisp)->pic = *argv;
|
|
|
+ if(!iswildcard(*argv))
|
|
|
+ (*thisp)->pat = 0;
|
|
|
+ else if(((*thisp)->pat = wildcomp(*argv)) == 0) {
|
|
|
+ fprintf(stderr, "dirsf: can't compile pattern %s\n", *argv);
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ thisp = &(*thisp)->next;
|
|
|
+ argv++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+PROGRAM_NUMBER(0x94589004);
|
|
|
+
|
|
|
+int
|
|
|
+main(int argc, char *argv[])
|
|
|
+{
|
|
|
+ int rc = SFDIR_NOTFOUND; /* a guess, to suppress warning */
|
|
|
+ int option = 0;
|
|
|
+ int cded = 0; /* did we cd? */
|
|
|
+#if defined(_WIN32) || defined(__SC__)
|
|
|
+ char opath[MAXPREFIX];
|
|
|
+ int olddrive;
|
|
|
+ int newdrive;
|
|
|
+ char *dircp;
|
|
|
+#endif
|
|
|
+
|
|
|
+ if(sflinit("dirsf")) {
|
|
|
+ sfperror("dirsf: initialisation");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ if(sfverno() < FSTVERWPREF)
|
|
|
+ fprintf(stderr, "cdfs: warning, installed sfsys does not support prefixes\n");
|
|
|
+ isprefix();
|
|
|
+ if(argc > 1 && strcmp(argv[1], "-g") == 0) {
|
|
|
+ preflg = SFDIR_IGPREFIX;
|
|
|
+ argc--;
|
|
|
+ argv++;
|
|
|
+ }
|
|
|
+ if(argc > 1 && argv[1][0] == '-')
|
|
|
+ switch(argv[1][1]) {
|
|
|
+ case 'l':
|
|
|
+ case 't':
|
|
|
+ option = argv[1][1];
|
|
|
+ argc--;
|
|
|
+ argv++;
|
|
|
+ break;
|
|
|
+ case 'd':
|
|
|
+ break;
|
|
|
+ case 'h': //RWD 7.98
|
|
|
+ case '?':
|
|
|
+ usage();
|
|
|
+ default:
|
|
|
+ usage();
|
|
|
+ }
|
|
|
+ if(argc > 1 && strcmp(argv[1], "-d") == 0) {
|
|
|
+ if(argc < 3)
|
|
|
+ usage();
|
|
|
+#if defined(unix)
|
|
|
+ cded++;
|
|
|
+ if(chdir(argv[2]) < 0) {
|
|
|
+ fprintf(stderr, "dirsf: can't change directory\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+#elif defined(_WIN32) || defined(__SC__)
|
|
|
+ olddrive = _getdrive();
|
|
|
+ if(argv[2][1] == ':') {
|
|
|
+ newdrive = toupper(argv[2][0]) - 'A' + 1;
|
|
|
+ dircp = &argv[2][2];
|
|
|
+ } else {
|
|
|
+ newdrive = olddrive;
|
|
|
+ dircp = &argv[2][0];
|
|
|
+ }
|
|
|
+ if(_chdrive(newdrive) < 0
|
|
|
+ ||_getcwd(opath, MAXPREFIX) == NULL
|
|
|
+ ||((dircp[0] != '\0') ? _chdir(dircp) : 0) < 0) {
|
|
|
+ fprintf(stderr, "dirsf: error changing current directory\n");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+ cded++;
|
|
|
+#else
|
|
|
+#error "Unknown system"
|
|
|
+#endif
|
|
|
+ argc -= 2;
|
|
|
+ argv += 2;
|
|
|
+ }
|
|
|
+ if(argc > 1)
|
|
|
+ mkfilelist(&argv[1]);
|
|
|
+
|
|
|
+ switch(option) {
|
|
|
+ case 0:
|
|
|
+ printf("Sfsys Version %x.%02x\n", (unsigned int)(sfverno()>>8), (unsigned int)(sfverno()&0xff));
|
|
|
+ puts( longhdr);
|
|
|
+ rc = sfdir(lpr, SFDIR_USED|preflg);
|
|
|
+ break;
|
|
|
+ case 'l':
|
|
|
+ rc = sfdir(pr, SFDIR_USED|preflg);
|
|
|
+ break;
|
|
|
+ case 't':
|
|
|
+ rc = sfdir(tpr, SFDIR_USED|preflg);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ usage();
|
|
|
+ }
|
|
|
+
|
|
|
+#if defined(_WIN32) || defined(__SC__)
|
|
|
+ if(cded) {
|
|
|
+ if(_chdir(opath) < 0
|
|
|
+ ||_chdrive(olddrive) < 0)
|
|
|
+ fprintf(stderr, "dirsf: can't restore current path\n");
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ if(rc != SFDIR_NOTFOUND) {
|
|
|
+ sfperror("dirsf");
|
|
|
+ exit(1);
|
|
|
+ }
|
|
|
+// sffinish();
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * do we want this file?
|
|
|
+ */
|
|
|
+int
|
|
|
+dofile(char *name)
|
|
|
+{
|
|
|
+ char *basename;
|
|
|
+ struct filename *this;
|
|
|
+
|
|
|
+ if(filelist == 0)
|
|
|
+ return 1;
|
|
|
+ if((basename = strrchr(name, '\\')) != 0)
|
|
|
+ basename++;
|
|
|
+ else
|
|
|
+ basename = name;
|
|
|
+
|
|
|
+ for(this = filelist; this != 0; this = this->next) {
|
|
|
+ if(this->pat != 0) {
|
|
|
+ if(wildmatch(prefix_set ? basename : name, this->pat))
|
|
|
+ return 1;
|
|
|
+ } else if(strcmp(this->pic, basename) == 0)
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Just print the filename
|
|
|
+ */
|
|
|
+int SFCALLS
|
|
|
+pr(struct sf_direct *dirp)
|
|
|
+{
|
|
|
+#ifdef NOTDEF
|
|
|
+ if(dofile(dirp->name))
|
|
|
+ printf("%s\n", dirp->name);
|
|
|
+#else
|
|
|
+ if(dofile(dirp->name)) {
|
|
|
+#ifdef _WIN32
|
|
|
+ if(dirp->is_shortcut)
|
|
|
+ printf("%s\t\t%s\n",dirp->name,dirp->targetname);
|
|
|
+ else
|
|
|
+#endif
|
|
|
+ printf("%s\n", dirp->name);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Get the date/time for a file
|
|
|
+ */
|
|
|
+int
|
|
|
+getdateprop(char *name, unsigned int *timep)
|
|
|
+{
|
|
|
+ int rc;
|
|
|
+ int sfd = sndopenEx(name,0,CDP_OPEN_RDONLY);
|
|
|
+
|
|
|
+ if(sfd < 0)
|
|
|
+ return 0;
|
|
|
+ rc = sndgetprop(sfd, "DATE", (char *)timep, sizeof(int)) == sizeof(int);
|
|
|
+ sndcloseEx(sfd);
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Print date/time and name
|
|
|
+ */
|
|
|
+int SFCALLS
|
|
|
+tpr(struct sf_direct *dirp)
|
|
|
+{
|
|
|
+ time_t time;
|
|
|
+ unsigned int cdptime;
|
|
|
+ char *times;
|
|
|
+
|
|
|
+ if(!dofile(dirp->name))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if(getdateprop(dirp->name, &cdptime)) {
|
|
|
+ time = (time_t) cdptime;
|
|
|
+ times = ctime(&time);
|
|
|
+ times[24] = '\0';
|
|
|
+ printf("%-26s\t", times);
|
|
|
+ } else
|
|
|
+ printf("%-26s\t", "-");
|
|
|
+#ifdef _WIN32
|
|
|
+ if(dirp->is_shortcut)
|
|
|
+ printf("%s\t%s\n",dirp->name,dirp->targetname);
|
|
|
+ else
|
|
|
+#endif
|
|
|
+ printf("%s\n", dirp->name);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * print long information
|
|
|
+ */
|
|
|
+int SFCALLS
|
|
|
+lpr(struct sf_direct *p)
|
|
|
+{
|
|
|
+ int nosec = 0;
|
|
|
+ int scale;
|
|
|
+
|
|
|
+ if(!dofile(p->name))
|
|
|
+ return 0;
|
|
|
+ if(p->flags == SFFLG_IOERROR) /* RWD Aug 2009 solve the unsigned issue here */
|
|
|
+ printf("%d\t",-1);
|
|
|
+ else
|
|
|
+ printf("%9u\t", p->length); /*RWD Aug 2009: print as unsigned! */
|
|
|
+ switch(p->nochans) {
|
|
|
+ case '1':
|
|
|
+ printf("mono\t");
|
|
|
+ break;
|
|
|
+ case '2':
|
|
|
+ printf("stereo\t");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ if(p->nochans < 0) {
|
|
|
+ printf("-\t");
|
|
|
+ nosec++;
|
|
|
+ } else
|
|
|
+ printf("%d\t", p->nochans);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ switch(p->samptype) {
|
|
|
+ case SAMP_SHORT:
|
|
|
+ if(p->origwordsize==8)
|
|
|
+ printf("8bit \t");
|
|
|
+ else
|
|
|
+ printf("short\t");
|
|
|
+ scale = sizeof(short); //RWD: keep until I fully define SAMP_BYTE
|
|
|
+ break;
|
|
|
+ case SAMP_FLOAT:
|
|
|
+ printf("float\t");
|
|
|
+ scale = sizeof(float);
|
|
|
+ break;
|
|
|
+ case SAMP_LONG:
|
|
|
+ printf("long\t");
|
|
|
+ scale = sizeof(long);
|
|
|
+ break;
|
|
|
+ case SAMP_2424:
|
|
|
+ printf("24(p) \t");
|
|
|
+ scale = 3;
|
|
|
+ break;
|
|
|
+ case SAMP_2432:
|
|
|
+ printf("24:32\t");
|
|
|
+ scale = sizeof(long);
|
|
|
+ break;
|
|
|
+ case SAMP_2024:
|
|
|
+ printf("20:24\t");
|
|
|
+ scale = 3;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ if(p->samptype < 0)
|
|
|
+ printf("-\t");
|
|
|
+ else
|
|
|
+ printf("?\t");
|
|
|
+ nosec++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if(p->samprate > 0)
|
|
|
+ printf("%5d\t", p->samprate);
|
|
|
+ else {
|
|
|
+ printf("-\t");
|
|
|
+ nosec++;
|
|
|
+ }
|
|
|
+ if(nosec)
|
|
|
+ printf("-\t");
|
|
|
+ else {
|
|
|
+ float time = (float)p->length;
|
|
|
+ if(p->origwordsize==8)
|
|
|
+ time *= 2.0f;
|
|
|
+
|
|
|
+ time /= (float)(scale * p->nochans * p->samprate);
|
|
|
+ printf("%7.3f\t", time);
|
|
|
+ }
|
|
|
+ if(p->fmt== WAVE)
|
|
|
+ printf(" W ");
|
|
|
+ else if(p->fmt== WAVE_EX) {
|
|
|
+ channelformat fmt = -1;
|
|
|
+ int sfd;
|
|
|
+ sfd = sndopenEx(p->name,0,CDP_OPEN_RDONLY);
|
|
|
+ if(sfd >=0){
|
|
|
+ snd_getchanformat(sfd, &fmt);
|
|
|
+ if(fmt >=0){
|
|
|
+ if(fmt==MC_BFMT)
|
|
|
+ printf(" WB ");
|
|
|
+ else
|
|
|
+ printf(" WX ");
|
|
|
+ }
|
|
|
+ sndcloseEx(sfd);
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ printf(" WX ");
|
|
|
+ }
|
|
|
+ else if(p->fmt==AIFF)
|
|
|
+ printf(" A ");
|
|
|
+ else if(p->fmt==AIFC)
|
|
|
+ printf(" AC ");
|
|
|
+#ifdef ENABLE_PVX
|
|
|
+ else if(p->fmt==PVOCEX)
|
|
|
+ printf(" PX ");
|
|
|
+#endif
|
|
|
+ else //FMT_UNKNOWN
|
|
|
+ printf(" ? ");
|
|
|
+
|
|
|
+ printf("%s\n", p->name);
|
|
|
+ return 0;
|
|
|
+}
|