home *** CD-ROM | disk | FTP | other *** search
- /***
- *dirent.c - disked disk directory maintenence.
- *
- *Copyright (c) 1993-1995, Gregg Jennings. All wrongs reserved.
- * P O Box 200, Falmouth, MA 02541-0200
- *
- *Purpose:
- * Handles the displaying and editing of directory sectors.
- *
- *Notice:
- * This progam may be freely used and distributed. Any distrubution
- * with modifications must retain the above copyright statement and
- * modifications noted.
- * No pulp-publication, in whole or in part, permitted without
- * permission (magazines or books).
- *******************************************************************************/
-
- /*
- Versions:
-
- 1.3 13-Nov-1993 more use of structures, cleaned up changedir()
- 1.2 14-Jan-1994 =0 bug fix in changedir()
- 1.1 13-Nov-1993 Started structures
- 1.0 June 1993
-
- Release Notes:
-
- This is all "Brute Force" code. Written in a couple a days after
- I wanted to arange all my directories is a certain non-sorted way
- easier than a touch program.
- */
-
- #include <stdio.h>
- #include <conio.h>
- #include <ctype.h>
-
- #include "mylib.h" /* getnum() */
- #include "keys.h"
- #include "dirent.h" /* DosTime, DosDate, dDIR */
- #include "console.h" /* input, output, cursor stuff */
-
-
- /* NO globals referenced here */
-
- /* NO globals defined here */
-
-
- #define isexten(c) ( (c>0x7f) && (c<255) )
-
- static int command(int c);
- static int text(int len, unsigned char *b);
- static int attrib(unsigned char *b);
- static int dostime(DosTime time, DosTime *t);
- static int dosdate(DosDate date, DosDate *d);
- static int pdirent(dDIR *);
-
- /* ...filename.txt...ttri...hh:mm:ss...mm/dd/yy...1234567...1234567 */
- static char
- *dir_header=" File Attr Time Date Cluster Size\n";
-
- /* display directory */
-
- extern void dumpdir(unsigned char *buf, int sec_size)
- {
- int i;
- dDIR *dir = (dDIR *)buf;
-
- output('\n');
- output('\n');
- print(dir_header); /* print header */
-
- for (i = 0; i < sec_size; i+=sizeof(dDIR),dir++) /* and each entry */
- {
- output('\n');
- put(3,' ');
- pdirent(dir);
- }
- output('\n');
- }
-
- /* change dir command structure */
-
- /* ...filename.txt...ttri...hh:mm:ss...mm/dd/yy...1234567...1234567 */
- struct fields {
- int beg; /* starting column */
- int end; /* ending column */
- int (*inp)(); /* function to do the change */
- } field[] = {
- {4,7, command},
- {9,16, text},
- {18,20,text},
- {24,28,attrib},
- {32,33,dostime},
- {43,44,dosdate},
- };
-
- /***
- *changedir() - edit directory entry(s) in sector buffer
- *
- * ver 1.1 fixed =0 bug
- ****/
-
-
- #define NUMFIELDS (sizeof(field)/sizeof(struct fields)-1)
- #define LASTENTRY ((int)(sec_size/sizeof(dDIR))-1)
-
- extern int changedir(unsigned char *buf,int sec_size)
- {
- int i;
- unsigned int a,x;
- unsigned int *b;
- unsigned int c;
- unsigned int n;
- int o; /* offset into buffer (dDIR pointer) */
- int r;
- int p; /* absolute position */
- int f; /* field in */
-
- get_cursor(&a,&x);
- print("\n\n %s",dir_header);
-
- i = r = 0;
- for (;;)
- {
- c = f = 0; /* start off at command function */
- p = field[f].beg;
- print("\n%03d ",i+1);
-
- o = i*sizeof(dDIR);
- r = pdirent((dDIR *)(buf+o));
- get:
- set_cursor(a,p);
-
- switch (f)
- {
- case 0: /* command */
- c = (*field[f].inp)(r); /* arg: entry type */
- break;
- case 1: /* file name */
- c = (*field[f].inp)(8,buf+o); /* args: length, char* */
- break;
- case 2: /* file extension */
- c = (*field[f].inp)(3,buf+o+8); /* args: length, char* */
- break;
- case 3: /* attribute */
- c = (*field[f].inp)(buf+o+11); /* arg: int* */
- break;
- case 4: /* time */
- b=(unsigned int *)(buf+o+0x16); /* arg: DosTime* */
- c = (*field[f].inp)(*b,b);
- break;
- case 5: /* date */
- b=(unsigned int *)(buf+o+0x18); /* arg: DosDate* */
- c = (*field[f].inp)(*b,b);
- break;
- }
-
- /* deal with key returned from functions */
-
- switch (c) /* convert scancodes to ASCII */
- {
- case RIGHT: /* next field */
- case CRIGHT:
- c = '\t';
- break;
- case SHTAB: /* previous field */
- case CLEFT:
- case LEFT:
- c = 0x7f;
- break;
- case DOWN: /* next entry */
- c = '\r';
- break;
- case UP: /* previous entry */
- c = '\b';
- break;
- default:
- c &= 0xff; /* convert to ASCII */
- break;
- }
-
- /* ASCII */
-
- switch (c)
- {
- case 0x7f: /* previous field */
- if (f > 0)
- p = field[--f].beg;
- break;
- case '\t': /* next field */
- if (f < NUMFIELDS)
- p = field[++f].beg;
- break;
- case '\r':
- case ' ': /* next entry */
- if (i == LASTENTRY) /* if at end */
- { /* wrap */
- i = 0;
- print("\n\n %s",dir_header); /* redisplay header */
- }
- else
- i++;
- continue; /* redisplay entry */
- break;
- case '\b': /* previous entry */
- if (i == 0) /* if at beginning */
- { /* wrap */
- i = LASTENTRY;
- print("\n\n %s",dir_header); /* redisplay header */
- }
- else
- i--;
- continue;
- break;
- case '=': /* select entry */
- output(c);
- if (getnum(sec_size/sizeof(dDIR),&n,10) > 0 && n > 0)
- i = n-1;
- continue;
- break;
- case '/':
- case '?':
- print("\n\n\tCR/SP next file");
- print("\n\tBS previous file");
- print("\n\tTAB next field");
- print("\n\tSHTAB previous field");
- print("\n\t=n goto file n");
- print("\n\t'C' goto filename");
- print("\n\t.|ESC exit\n");
- continue;
- break;
- case '.':
- case ESC:
- output('\n');
- return 0;
- break;
- default:
- if (isalnum(c)) /* letter? */
- {
- int j;
- c = toupper(c);
- for (j = i+1; ;j++)
- {
- if (j > LASTENTRY)
- j = 0;
- if (*(buf+(j*sizeof(dDIR))) == c)
- break;
- if (j == i)
- break;
- }
- if (j != i)
- {
- i = j;
- continue;
- }
- }
- break;
- }
- goto get;
- }
- }
-
-
- static int command(int c)
- {
- int i;
-
- i = scankey();
- if (c < 1 && (i==RIGHT || i==TAB))
- i = 0;
- return i;
- }
-
- /***
- *text() -- edit a text entry (filename/ext)
- *
- * can enter ALL printable characters including '.' and ' '
- ****/
-
- static int text(int len, unsigned char *buf)
- {
- int c;
- int i;
-
- for (i=0;;)
- {
- c=scankey();
- if (c==RIGHT)
- {
- if (i==len-1)
- break;
- curright();
- ++i;
- continue;
- }
- if (c==LEFT || c==BACKSP)
- {
- if (!i)
- break;
- --i;
- curleft();
- continue;
- }
- if (c==RETURN || c==TAB || c==SHTAB || c==DOWN || c==UP)
- break;
- if (c==ESCAPE)
- return(0);
- if (c>0x352f) continue;
- c&=0xff;
- if (isgraph(c) || isexten(c))
- {
- *(buf+i)=(char)c;
- i++;
- output(c);
- if (i==len)
- {
- c=RIGHT;
- break;
- }
- }
- }
- return(c);
- }
-
- /***
- *attrib() - toggle filename attributes, except for dir
- *
- ****/
-
- static int attrib(unsigned char *buf)
- {
- int i;
- int b,c,p,d;
- byte isvol;
-
- /* 01234 */
- /* RHSDA */
-
- isvol = (byte)(*buf&8);
- b=d=p=0; /* no need to set d,b but it gets rid of */
- /* MSC warning C4701 */
- for (;;)
- {
- i=scankey();
- if (i==RETURN || i==TAB || i==SHTAB || i==DOWN || i==UP)
- break;
- if (i==ESCAPE)
- {
- i=0;
- break;
- }
- if (i==RIGHT)
- {
- if (p==4) /* end */
- break;
- curright();
- ++p;
- continue;
- }
- if (i==LEFT || i==BACKSP)
- {
- if (p==0)
- break;
- --p;
- curleft();
- continue;
- }
-
- if ( !isvol && p!=3 && (i&0xff)==' ')
- {
- if (p==0)
- {
- b=1;
- d='R';
- }
- else if (p==1)
- {
- b=2;
- d='H';
- }
- else if (p==2)
- {
- b=4;
- d='S';
- }
- else if (p==4)
- {
- b=0x20;
- d='A';
- }
- if (*buf&b)
- {
- c='_';
- *buf&=~b;
- }
- else
- {
- c=d;
- *buf|=b;
- }
- output(c);
- curleft();
- }
- }
- return(i);
- }
-
- static int dostime(DosTime time, DosTime *t)
- {
- int i;
- int h,m,s;
- unsigned int r,x;
- int c,p;
-
- /* 01234567 */
- /* hh:mm:ss */
-
- get_cursor(&r,&x);
- c = x; /* set starting column */
- p = c; /* set the working column pointer */
-
- h = time.hours; /* set the working values */
- m = time.minutes;
- s = time.seconds;
-
- for (;;)
- {
- set_cursor(r,p);
-
- i=scankey();
-
- if (i==TAB || i==RETURN || i==SHTAB || i==DOWN || i==UP)
- return(i);
-
- if (i==ESCAPE)
- {
- i=0;
- break;
- }
-
- if (i==LEFT || i==BACKSP)
- {
- if (p==c && i==LEFT)
- return(i);
- if (p==c && i==BACKSP)
- continue;
- if (p==c+3 || p==c+6)
- p-=2;
- else
- p--;
- continue;
- }
- right:
- if (i==RIGHT)
- {
- if (p==c+7)
- return(i);
- if (p==c+1 || p==c+4)
- p+=2;
- else
- p++;
- continue;
- }
- i&=0xff;
- if (isdigit(i))
- {
- output(i);
- i=i-'0'; /* convert ascii to bin */
-
- /* based on column, */
- /* calculate new time with the */
- /* number input */
-
- if (p==c)
- h=(i*10)+(h%10);
- else if (p==c+1)
- h=i+((h/10)*10);
- else if (p==c+3)
- m=(i*10)+(m%10);
- else if (p==c+4)
- m=i+((m/10)*10);
- else if (p==c+6)
- s=(i*10)+(s%10);
- else if (p==c+7)
- s=i+((s/10)*10);
-
- time.hours = h;
- time.minutes = m;
- time.seconds = s;
- *t = time;
-
- i = RIGHT;
- goto right;
- }
- }
- return i;
- }
-
- /***
- *dosdate() - edit date field
- *
- * ver 1.1 fixed right arrow at last number from wrapping
- ****/
-
- static int dosdate(DosDate date, DosDate *dt)
- {
- int i;
- int m,d,y;
- unsigned int r,x;
- int c,p;
-
- /* 01234567 */
- /* mm/dd/yy */
-
- get_cursor(&r,&x);
- c = x;
- p = c;
- m = date.month;
- d = date.day;
- y = date.year+80;
-
- for (;;)
- {
- set_cursor(r,p);
- i=scankey();
-
- if (i==TAB || i==RETURN || i==SHTAB || i==DOWN || i==UP)
- break;
-
- if (i==ESCAPE)
- return 0;
-
- if (i==LEFT || i==BACKSP)
- {
- if (p==c && i==LEFT)
- return(i);
- if (p==c && i==BACKSP)
- continue;
- if (p==c+3 || p==c+6)
- p-=2;
- else
- p--;
- continue;
- }
- right:
- if (i==RIGHT)
- {
- if (p==c+7)
- continue;
- if (p==c+1 || p==c+4)
- p+=2;
- else
- p++;
- continue;
- }
- i&=0xff;
- if (isdigit(i))
- {
- output(i);
- i=i-'0';
-
- if (p==c)
- m=(i*10)+(m%10);
- else if (p==c+1)
- m=i+((m/10)*10);
- else if (p==c+3)
- d=(i*10)+(d%10);
- else if (p==c+4)
- d=i+((d/10)*10);
- else if (p==c+6)
- y=(i*10)+(y%10);
- else if (p==c+7)
- y=i+((y/10)*10);
- if (y>80)
- y-=80;
- else
- y=0;
-
- date.month = m;
- date.day = d;
- date.year = y;
- y += 80;
- *dt = date;
-
- i=RIGHT;
- goto right;
- }
- }
- return i;
- }
-
- /***
- *pdirent() - print directory entry
- *
- * Returns: 0 unused, 1 normal, -1 for directory or erased
- *
- * 1.2 11/12/94 references a dDIR structure, can't edit '.' dirs
- * v1.1 removed superfluous pointer
- ****/
-
- static int pdirent(dDIR *dir)
- {
- int i,r;
- unsigned char c;
-
- r = 1;
- if (dir->name[0] == 0)
- {
- print(" unused");
- r = 0;
- }
- else
- {
- /* set can't edit return flag */
-
- if (dir->name[0] == 0xE5 || dir->name[0] == '.')
- r = -1;
-
- /* check for bad chars in case and non-dir sector is displayed */
-
- for (i = 0; i < 8; i++)
- {
- c = dir->name[i];
- if (isspace((int)c) || c==255 || !c || c==7 || c==8)
- output(' ');
- else
- output(c);
- }
- output('.');
- for (i = 0; i < 3; i++)
- {
- c = dir->ext[i];
- if (isspace((int)c) || c==255 || !c || c==7 || c==8)
- output(' ');
- else
- output(c);
- }
- print(" ");
- if (dir->attr.volume)
- print(" Vol ");
- else
- {
- output(dir->attr.rdonly ? 'R' : '_');
- output(dir->attr.hidden ? 'H' : '_');
- output(dir->attr.system ? 'S' : '_');
- output(dir->attr.subdir ? 'D' : '_');
- output(dir->attr.archiv ? 'A' : '_');
- }
- print(" %02d:%02d:%02d",dir->time.hours,dir->time.minutes,dir->time.seconds);
- print(" %02d/%02d/%02d",dir->date.month,dir->date.day,dir->date.year+80);
- print(" % 7u",dir->start);
- if (!dir->attr.subdir)
- print(" % 7lu",dir->size);
- }
- return r;
- }
-