home *** CD-ROM | disk | FTP | other *** search
- /*
-
- WILDCARD FILE RENAME PROGRAM
-
- By David Brown, Australia
-
- Version list, most recent version first
-
- 21/Jul/83
- Expanded usage message so that it gave meaningful help.
- Version list and this descriptive header added,
- Version 2.1, Bill Bolton
-
- Fixed initial bugs in version 1. Version 2, David Brown
-
- Initial implementation, placed on "Software Tools" RCPM.
- Version 1, David Brown
-
- */
-
- #include <bdscio.h>
- #include <bdos.h>
-
- #define VERSION "2.1" /* version 1 didn't work */
- #define FCBSIZ 36 /* size of a CP/M File Control Block */
- #define NAMLEN 20 /* should be plenty for a filename */
-
-
- char oldfcb[FCBSIZ], newfcb[FCBSIZ];
-
- #define LIST struct lst_entry
- #define LISTSIZ (NAMLEN+2)
- LIST {
- char name[NAMLEN]; /* name in CP/M format e.g. 1/B:FOO.BAR */
- LIST *next;
- };
- LIST *o_head, *n_head, *a_head; /* lists of filenames */
-
- char def_usr; /* saves the current user area */
- char def_drv;
- int count; /* counts how many renames were done */
-
- main(argc, argv)
- char **argv;
- {
-
- char usr_new, usr_old;
- char drv_new, drv_old;
-
- count = 0;
-
- def_usr = bdos(USERCODE,0xff);
- def_drv = bdos(GETCURRENT); /* 0=A 1=B ... */
-
- o_head = n_head = a_head = NULL;
-
- printf("\nCP/M 'Wildcard' File Rename Utility, Version %s\n",VERSION);
- if (argc != 3) {
- printf("\nUsage:\n");
- printf("\tRENAME filename1 filename2\n\n");
- printf("Where:\tfilename1\tis any legal CP/M 'ambiguous' file identifier\n");
- printf("\t\t\tand is the 'NEW' filename\n\n");
- printf("\tfilename2\tis any legal CP/M 'ambiguous' file identifier\n");
- printf("\t\t\twith the wildcard characters in the same place\n");
- printf("\t\t\tas filename1. It is the 'EXISTING' filename\n\n");
- printf("Note:\t? and * are wildcard characters in CP/M file indentifiers\n\n");
- printf("See RENAME.DOC for a full explanation of command line syntax\n\n");
- bye(ERROR);
- }
-
- usr_new = stripusr(&argv[1]); /* remove user area prefix, */
- usr_old = stripusr(&argv[2]); /* if it is there.. */
- if (usr_new != usr_old) {
- printf("\nUser areas must be the same\n");
- bye(ERROR);
- }
-
- drv_new = stripdrv(&argv[1]); /* remove drive prefixes */
- drv_old = stripdrv(&argv[2]);
- if (drv_new != drv_old) {
- printf("\nDrives must be the same\n");
- bye(ERROR);
- }
-
- setfcb(oldfcb,argv[2]); /* make up the fcb's */
- setfcb(newfcb,argv[1]);
- if (chkwild() == ERROR) {
- printf("\nNames must be 'ambiguous' in a reasonable way.\n\n");
- printf("See RENAME.DOC file for a definition of \"reasonable\"\n");
- bye(ERROR);
- }
-
- bdos(SELECTDISK,drv_new); /* change to required drive */
- bdos(USERCODE,usr_new); /* and user area */
-
- makeold(); /* generate list of old names */
- makenew();
- makeall(); /* generate list of all filenames */
-
- dorens(); /* rename all the files */
-
- if (count)
- printf("\n%d files renamed.\n",count);
- else
- printf("\nNo files renamed.\n");
-
- bye(OK);
- }
-
- bye(status)
- {
- bdos(SELECTDISK,def_drv); /* reset drive and user */
- bdos(USERCODE,def_usr);
- exit(status);
- }
-
- char stripusr(s)
- char **s; /* need ptr to ptr as will update it */
- {
-
- char *t; /* scan ptr */
- int usr;
-
- t = *s;
- while (isdigit(*t)) /* advance to first non-numeric */
- t++;
- if (*t++ != '/')
- return def_usr; /* no user area prefix */
-
- usr = atoi(*s); /* get user area */
-
- if (usr > 31 || usr < 0) /* not possible, thus must be part of */
- return def_usr; /* name, so go back with default */
-
- *s = t; /* delete prefix from our input string */
- return usr;
- }
-
- chkwild() /* ensures that are wild in correct manner - see .DOC */
- {
- char i;
-
- for (i=0; i<12; i++)
- if (oldfcb[i] != '?' && newfcb[i] == '?')
- return ERROR;
- }
-
- char stripdrv(s)
- char **s; /* need ptr to ptr as will update it */
- {
-
- int drv;
-
- if ((*s)[1] != ':') /* no drive prefix if no colon */
- return def_drv;
-
- drv = toupper(**s) - 'A';
- if (drv < 0 || drv > 15)
- return def_drv;
-
- *s += 2; /* advance past drive */
-
- return drv;
-
- }
-
- makeold()
- {
-
- char dma[SECSIZ], nme[NAMLEN];
- char index; /* returned by search function */
-
- bdos(SETADDRESS,dma);
-
- index = bdos(SEARCHFIRST,oldfcb);
- while (index != 255) {
- unsetfcb(dma+index*32,nme);
- addlst(&o_head,nme);
- index = bdos(SEARCHNEXT,oldfcb);
- }
- }
-
- makenew()
- {
- char o_fcb[FCBSIZ]; /* holds ufn of current old file */
- char n_fcb[FCBSIZ]; /* " " " " new " */
- char nme[NAMLEN];
-
- LIST *trav;
- int i;
-
- trav = o_head;
- while (trav != NULL) { /* traverse old names */
- setfcb(o_fcb,trav->name);
- for (i=1;i<12;i++) { /* scan the wild version */
- if (oldfcb[i]=='?') { /* needs to change ? */
- if (newfcb[i] == '?') /* yes .. */
- n_fcb[i]=o_fcb[i];
- else
- n_fcb[i]=newfcb[i];
- } else
- n_fcb[i]=newfcb[i]; /* No, just copy */
- }
- unsetfcb(n_fcb,nme);
- addlst(&n_head,nme);
- trav = trav->next;
- }
- }
-
- makeall()
- {
-
- char dma[SECSIZ], nme[NAMLEN], fcb[FCBSIZ];
- char index; /* returned by search function */
-
-
- setfcb(fcb,"*.*"); /* all files */
-
- bdos(SETADDRESS,dma);
-
- index = bdos(SEARCHFIRST,fcb);
- while (index != 255) {
- unsetfcb(dma+index*32,nme);
- addlst(&a_head,nme);
- index = bdos(SEARCHNEXT,fcb);
- }
- }
-
- dorens() /* do actual renames */
- {
-
- char ch;
-
- while (o_head) {
- if (exists(n_head)) { /* if exists, what do I do now ? */
- printf("%s to %s, exists - ",
- o_head->name,n_head->name);
- printf("(Q)uit,(S)kip,(K)ill : ");
- scanf("%c",&ch);
- switch(toupper(ch)) {
- case 'Q' : bye(ERROR);
- case 'K' : unlink(n_head->name);
- rename(o_head->name,n_head->name);
- }
- } else {
- rename(o_head->name,n_head->name);
- count++;
- }
- o_head = o_head->next;
- n_head = n_head->next;
- }
- }
-
- unsetfcb(f,n) /* do opposite of "setfcb". This IGNORES the drive field */
- char *f, *n;
- {
- char *f_save;
-
- f_save = f++; /* save initial pos and ignore drive */
-
- while (*f != ' ' && f < f_save+9)
- *n++ = *f++; /* copy till a blank */
- *n++ = '.';
- f = f_save + 9; /* point at type */
- while (*f != ' ' && f < f_save+12)
- *n++ = *f++;
- *n = '\0';
- }
-
- addlst(h,n)
- char **h, *n;
- {
-
- char *trav;
-
- trav = *h;
-
- if (*h == NULL) {
- *h = getmem(LISTSIZ);
- (*h)->next = NULL;
- strcpy((*h)->name,n);
- } else {
- trav = *h;
- while (trav->next != NULL)
- trav = trav->next;
- trav->next = getmem(LISTSIZ);
- trav = trav->next;
- trav->next = NULL;
- strcpy(trav->name,n);
- }
- }
-
- char *getmem(n)
- {
- char *s;
- s = alloc(n);
- if (!s) {
- printf("\nOut of memory - see notes RENAME.C source file\n");
- bye(ERROR);
- /* this will only happen if you have a lot of
- directory entries that need to be matched
- e.g. for 128 entries, need 20K free at MOST
- otherwise I have a bug
- */
- }
- return s;
- }
-
- exists(n) /* does n exist in list of all files in drive/user */
- char *n;
- {
-
- LIST *trav;
-
- trav = a_head;
- while (trav) {
- if (strcmp(trav->name,n) == 0)
- return TRUE;
- trav = trav->next;
- }
- return FALSE;
- }