home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
RBBS in a Box Volume 1 #2
/
RBBS_vol1_no2.iso
/
add2
/
fc_v003.exe
/
FC.C
< prev
next >
Wrap
Text File
|
1989-04-24
|
17KB
|
601 lines
/***************************************************************************
*
* Name: FC-File Commentor
* Synopsis: FC filespec [switches]
*
* Description: Allows File Comments to be appended to standard
* looking directory listings. Meant to be a substitute
* for the DIR command. Uses a linked list to store
* data for more efficient memory usage.
*
* Revision: 0.003
*
* Author: Ronald C. Bieber
*
* Compiler: Turbo C Version 2.00
*
**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <dir.h>
#include <io.h>
#include <fcntl.h>
#include <string.h>
#include <alloc.h>
#include <conio.h>
#include "fc.h"
unsigned long sig = 0x6d5945b1;
int olddrive,
drive,
fh,
no_found = 0,
flags = 0; /* integer variable to hold command line
options. Initialize to zero (no options
selected). */
char filespec[MAXPATH],
oldpath[MAXPATH],
comment_file[MAXPATH],
newpath[MAXPATH];
char *months[12] = { /* 3 digit month names */
"Jan", /* per Jeff Darling 4-23 */
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
};
/************************ Function Declarations ***************************/
void Usage();
void prtlong(long);
void format_time(unsigned short);
void splitfilespec(char *, char *, char *, int *);
void quit(int);
char *editline(char *, int);
int c_brk();
void pause(); /* for pause mode */
FILELIST *head;
main(argc, argv)
int argc;
char **argv;
{
FILELIST *next,
*found;
char *ptr,
node[9],
ext[4];
struct ffblk files;
int done,
linecount = 2,
pos = 0,
attr = FA_ARCH + FA_HIDDEN + FA_RDONLY + FA_SYSTEM + FA_DIREC;
olddrive = drive = getdisk(); /* set default drive */
getcwd(oldpath, MAXPATH);
printf("FC-File Commentor, Version %s, (C) Copr 1989, Ronald C. Bieber\n\n", VERSION);
ctrlbrk(c_brk);
argc = parms(argc, argv);
if (argc < 1)
strcpy(filespec, "*.*");
else {
if (strcmp(*(++argv), "?") == 0)
Usage();
else
splitfilespec(*argv, newpath, filespec, &drive);
}
sprintf(comment_file, "%scomments.fc", newpath);
head = (FILELIST *) calloc(1, sizeof(FILELIST));
setdisk(drive);
if ((fh = open(comment_file, O_RDWR)) < 0)
fh = mk_info();
else
read_info(head, fh);
if (flags & COMPRESS) {
close(fh);
fh = mk_info();
compress(head);
write_info(head, fh);
printf("COMMENTS.FC had been compressed.\n");
quit(FAILURE);
}
done = findfirst(filespec, &files, attr);
while(!done) {
ptr = files.ff_name;
ext[0] = 0;
pos = 0;
if (strchr(files.ff_name, '.') != NULL && strncmp(files.ff_name, ".", 1) != 0) {
while (*ptr != '.')
node[pos++] = *(ptr++);
node[pos] = 0;
ptr++;
strcpy(ext, ptr);
} else
strcpy(node, files.ff_name);
printf("%-8.8s %-3.3s ", strlwr(node), strlwr(ext));
if (!(files.ff_attrib & FA_DIREC))
prtlong(files.ff_fsize);
else
printf(" <DIR>");
printf(" %2.2d-%3.3s-%d ", files.ff_fdate &0x1f,
months[((files.ff_fdate>>5) &0x0f) - 1],
(files.ff_fdate>>9) + 80);
format_time(files.ff_ftime);
if ((found = search(head, files.ff_name)) != NULL && !(flags & ADD))
if (flags & DELETE)
node_delete(head, files.ff_name);
else
printf("%s", found->fileinfo.comment);
no_found++;
if (flags & ADD) {
if ((next = search(head, files.ff_name)) == NULL)
if ((next = mk_node(head)) == NULL) {
printf("Internal Stack Error: Not enough Memory\n");
exit(1);
}
strcpy(next->fileinfo.filename, files.ff_name);
editline(next->fileinfo.comment, 38);
if (strlen(next->fileinfo.comment) < 1) {
flags |= DELETE;
node_delete(head, next->fileinfo.filename);
}
}
putchar('\n');
if (!(flags & ADD) && (flags & PAUSE)) { /* for /P - pause option */
linecount++;
if (linecount >= 24) {
pause();
linecount = 0;
}
}
done = findnext(&files);
}
if (flags & DELETE) {
close(fh);
fh = mk_info();
}
quit(SUCCESS);
}
/****************************************************************************
*
* Name: Usage
* Synopsis: void Usage();
*
* Description: Prints usage format and command line options to
* standard output.
*
* Returns: Nothing.
*
***************************************************************************/
void Usage()
{
printf("Usage: FC [filespec] [switches] >outfile\n\n");
printf("Switches:\n");
printf(" /A Add or edit existing file comments.\n");
printf(" /COMPRESS Compress COMMENTS.FC file.\n");
printf(" /D Delete file comments.\n");
printf(" /P Pause Mode; press a key to continue.\n");
printf("\nFC was written by Ron Bieber.\n");
printf("Program design by Ron Bieber and Jeff Darling.\n\n");
printf("Courtesy of Polysyncronism BBS - (312) 358-5104\n");
exit(1);
}
/******************************************************************************
*
* Name: prtlong()
* Synopsis: void prtlong(number);
* long number;
*
* Description: Prints out a long number in formatted form (X,XXX,XXX)
*
*****************************************************************************/
void prtlong(number)
long number;
{
char newnum[17],
*ptr,
Number[17];
int count = 0,
loop,
length,
slength;
if (number <= 999) {
printf(" %3lu",number);
return;
}
ptr = newnum;
ptr = ltoa(number, ptr, 10);
length = strlen(newnum);
slength = length;
*newnum = *strrev(newnum);
for (loop = 0;loop<length;loop++) {
if ( (loop == 3 && slength > 3) || (loop == 6 && slength > 6)) {
Number[count++] = 0x2C;
length++;
}
Number[count++] = newnum[loop];
}
strncpy(newnum,Number,length);
ptr = strrev(Number);
printf("%10s", ptr);
}
/****************************************************************************
*
* Name: format_time
* Synopsis: void format_time(ttime);
* unsigned short ttime; time stored in DOS format
*
*
* Description: Prints the time in HH:MM[ap] format.
*
* Returns: Nothing.
*
***************************************************************************/
void format_time(ttime)
unsigned short ttime;
{
int hours,
minutes;
char *temp,
a_p = 'a';
hours = ((ttime & 0xF800) >> 11);
minutes = ((ttime & 0x07E0) >> 5);
if (hours >= 12)
a_p = 'p';
if (hours > 12)
hours -= 12;
else
if (hours == 0)
hours = 12;
printf("%2d:%2.2d%c ", hours, minutes, a_p);
}
/******************************************************************************
*
* Name: parms
* Synopsis: void parms(indx, ptr);
* int indx;
* char **ptr;
*
* Description: Retrieves program switches "Norton Style".
* (e.g. Progname parm1 /switch1 /switch2 /switch3)
*
* Returns: Number of regular arguments (excluding switches)
*
*****************************************************************************/
int parms(indx, ptr)
int indx;
char **ptr;
{
char c,
temp[3],
*tempptr;
int count;
count = indx - 1;
ptr += count;
while (*(ptr[0]) == '/') {
c = *(++ptr[0]);
switch(toupper(c)) {
case 'A': flags |= ADD;
break;
case 'C': if (stricmp(*ptr, "COMPRESS") == 0)
flags |= COMPRESS;
break;
case 'D': flags |= DELETE;
break;
case 'P': flags |= PAUSE;
break;
}
count--;
ptr--;
}
return(count);
}
/****************************************************************************
*
* Name: editline
* Synopsis: char *editline(line, l);
* char *line; line of text to edit
* int l; length of line
*
* Description: Allows user to edit line of text (entry description)
*
***************************************************************************/
char *editline(line, l)
char *line;
int l;
{
char c;
int count = 0,
row,
col,
ocol,
orow;
ocol = col = wherex();
orow = row = wherey();
textcolor(BLACK);
textbackground(WHITE);
for (c = 0; c < l; c++)
putch(' ');
gotoxy(col, row);
cprintf("%s", line);
gotoxy(col, row);
while ((c = getch()) != '\r')
switch(c) {
case 0: if (kbhit()) { /* extended key was pressed */
c = getch();
switch(c) {
case 77: if (count < l - 1) {
c = line[count++]; /* right arrow */
putch(c);
gotoxy(wherex(), row);
} else
BEEP();
continue;
case 75: if (count > 0) {
c = line[count--]; /* left arrow */
putch(c);
gotoxy(wherex() - 2, row);
} else
BEEP();
default: continue;
}
}
case 8: /* backspace was pressed */
if (count > 0) {
col = wherex();
row = wherey();
gotoxy(col - 1, row);
putch(' ');
gotoxy(col - 1, row);
line[--count] = 0;
} else
BEEP();
break;
case 27: /* ESCAPE key was pressed */
normvideo();
gotoxy(ocol, orow);
clreol();
printf("%s", line);
putc('\n', stdout);
quit(SUCCESS);
break;
default: if (count < l) {
line[count] = c;
count++;
} else {
col = wherex() - 1;
row = wherey();
if (count < l)
line[count] = c;
gotoxy(col, row);
}
putch(c);
if (count > l - 1) /* sound bell if at end of field */
BEEP();
break;
}
line[strlen(line)] = 0;
normvideo();
gotoxy(ocol, orow);
clreol();
printf("%s", line);
return(line);
}
/******************************************************************************
*
* Name: splitfilespec
* Synopsis: void splitfilespec(filespec, file, drive);
* char *filespec, filespec to split
* *file; variable to hold filename.ext
* int drive; variable to store new drive #
*
* Description: parses filespec and returns the drive number and filename
*
*****************************************************************************/
void splitfilespec(filespec, path, file, driveno)
char *filespec,
*path,
*file;
int *driveno;
{
char drive[MAXDRIVE],
dir[MAXDIR],
name[MAXFILE],
ext[MAXEXT],
temp[MAXPATH],
newspec[MAXPATH];
struct ffblk files;
int status,
result;
strupr(filespec);
status = fnsplit(filespec, drive, dir, name, ext);
if (status & DRIVE)
*driveno = drive[0] - 65;
else
*driveno = getdisk();
if (status & DIRECTORY) {
sprintf(path, "%s%s", drive, dir);
} else
path[0] = 0;
if (status & FILENAME) {
if (strchr(name, '*') == NULL && strchr(name, '?') == NULL) {
sprintf(temp, "%s%s%s%s", drive, dir, name, ext);
result = findfirst(temp, &files, FA_ARCH + FA_HIDDEN + FA_RDONLY + FA_SYSTEM + FA_DIREC);
if (result == 0) {
if (files.ff_attrib & FA_DIREC) {
sprintf(temp, "%s%s%s\\", drive, dir, name);
strcpy(path, temp);
status ^= FILENAME;
name[0] = 0;
ext[0] = 0;
}
}
}
}
if (!(status & FILENAME))
strcpy(name, "*");
if (!(status & EXTENSION) || strlen(ext) < 1)
strcpy(ext, ".*");
sprintf(file, "%s%s%s", path, name, ext);
}
/******************************************************************************
*
* Name: c_brk
* Synopsis: int cbrk(void);
*
* Description: Control Break interrupt handler
*
*****************************************************************************/
int c_brk()
{
setdisk(olddrive);
exit(3);
}
/****************************************************************************
*
* Name: quit
* Synopsis: void quit(status);
* int status; status of quit
*
* Description: Stops program. If status is SUCCESS, print number
* found and disk free space. If status is FAILURE, just
* quit.
*
***************************************************************************/
void quit(status)
int status;
{
long size_of_comment_file = 0;
struct dfree dfree;
write_info(head, fh);
size_of_comment_file = filelength(fh);
close(fh);
if (size_of_comment_file <= 8)
unlink(comment_file);
setdisk(olddrive);
chdir(oldpath);
if (status == SUCCESS) {
if (no_found) {
getdfree(drive + 1, &dfree);
printf("\n%d file(s) ", no_found);
prtlong((long) (dfree.df_bsec * dfree.df_sclus) * dfree.df_avail);
printf(" bytes free\n");
} else
printf("No files found.\n");
}
exit(0);
}
/***************************************************************************
*
* Name: pause
* Synopsis: void pause(void);
*
* Description: Displays 'Press a key to continue ...' message and
* waits for keypress. Then clears the line and starts
* display where it left off.
*
***************************************************************************/
void pause()
{
int row = wherey(),
col = wherex();
gotoxy(1, row);
clreol();
printf("Press a key to continue ... ");
getch();
gotoxy(1, row);
clreol();
gotoxy(col, row);
}