/*--------------------------------------------------------------------*/ /* */ /* Filename: QUICK.C */ /* */ /* Language: Borland C++ 2.0 */ /* */ /* Author: Greig Greenwald (GREENWAG at WMAVM7) */ /* */ /* Description: Combines the function of SETFILE, QUICKADR, and */ /* QUICKDRY. It either loads a file in the system */ /* data file and uses a batch file to invoke */ /* the proper internal application (based on the */ /* file extension) or it displays a screen-full of */ /* either a diary or addressbook (based on the file */ /* extension.) */ /* */ /* Change History: Jan 27, 1991 Release 1.00 */ /* - Initial Release */ /* */ /*--------------------------------------------------------------------*/ #include #include #include #include #include #include /*====================================================================*/ /* DEFINES */ /*====================================================================*/ #define PERM_DATA_FILE "c:\\system\\permdata.dat" #define PERM_DATA_LENGTH 730 #define SCREEN_SIZE 7 #define SCREEN_WIDTH 39 #define LINE_LENGTH 200 #define FALSE 0 #define TRUE 1 #define EQUAL 0 #define LESS_THAN 1 #define GREATER_THAN 2 #define DATE_WIDTH 19 #define TODAY_MARKER "***>" #define OTHER_MARKER "===>" /*====================================================================*/ /* TYPES */ /*====================================================================*/ /*====================================================================*/ /* DATA */ /*====================================================================*/ /*====================================================================*/ /* INTERNAL FUNCTION PROTOTYPES */ /*====================================================================*/ void setfile ( char file_name[], char batch_file[], int batch_offset ); int quickadr ( FILE *fp, int argc, char *argv[] ); int quickdry ( FILE *fp, int argc, char *argv[] ); /*====================================================================*/ /* EXTERNAL FUNCTIONS */ /*====================================================================*/ void main ( int argc, char *argv[] ) { FILE *fp; int printing; char *p, file_name[40]; struct ffblk file_block; /* Display Useage. */ if (argc < 4) { fwrite( "v1.00\nQUICK L file_spec batch_file offset\nQUICK Q addressbook name\nQUICK Q diary offset [d [m [y]]]", 99, 1, stdout ); exit( 1 ); } /* end if */ /* Add wildcards onto the end of the file_spec. */ strcpy( file_name, argv[2]); strcat( file_name, "*.*" ); /* Search for any file name that matches. */ if (findfirst( file_name, &file_block, 0 )) { fwrite( "File not found.", 15, 1, stdout ); exit( 2 ); } /* endif */ /* Complete the file name (since the one passed in many have been a */ /* partial name). */ p = strrchr( file_name, '\\' ); if (p == NULL) { p = file_name; } else { p++; } /* endif */ strcpy( p, file_block.ff_name ); /* If the "Load" option was selected, call setfile. */ if (toupper(argv[1][0]) == 'L') { setfile( file_name, argv[3], atoi( argv[4] ) ); /* If the "Quick" option was selected, determine whether it is a ADR or DRY */ } else if (toupper(argv[1][0]) == 'Q') { /* Open the file. */ if ((fp = fopen(file_name, "r")) == NULL) { fwrite( "Cannot open file.", 17, 1, stdout ); exit( 3 ); } /* end if */ /* Get the extension to compare. */ p = strrchr( file_name, '.' ); p++; /* If it is ADR, call quickadr. If it is DRY, call quickdry. */ if (strcmp(p,"ADR") == 0) { printing = quickadr( fp, argc, argv ); } else if (strcmp(p,"DRY") == 0) { printing = quickdry( fp, argc, argv ); } else { printing = SCREEN_SIZE; } /* endif */ fclose( fp ); /* Scroll the screen */ while ( printing < SCREEN_SIZE - 1 ) { fwrite( "\n", 1, 1, stdout ); printing++; } /* end while */ } else { exit( 4 ); } /* endif */ } /* main */ /*====================================================================*/ /* INTERNAL FUNCTIONS */ /*====================================================================*/ /* ** SETFILE determines the application associated with the file_name by looking ** at the file extension. It places the file_name in to proper slot in the ** PERMDATA.DAT file and then builds a batch file to run the internal ** application. */ /* ** Known information about the format of the C:\SYSTEM\PERMDATA.DAT file: ** ** Position (hex) Application Function ** -------------- ------------ -------------------------------- ** 0000 - 0007 ** 0008 - 0057 worksheet file name ** 0058 - 0061 ** 0062 - 00B1 diary file name ** 00B2 - 00B5 ** 00B6 - 0105 editor file name ** 0106 - 0109 editor cursor file position ** 010A - 010B editor line length ** 010C - 010C editor word wrap (0 = OFF, 1 = ON) ** 010D - 010F ** 0110 - 015F address book file name ** 0160 - 02D9 */ void setfile ( char file_name[], char batch_file[], int batch_offset ) { FILE *fp; int offset; char *extension, contents[PERM_DATA_LENGTH]; /* Open, read and close the system data file. */ if ((fp = fopen(PERM_DATA_FILE, "rb")) == NULL) { fwrite( "Cannot open system data file.", 29, 1, stdout ); exit( 5 ); } /* end if */ fread( contents, PERM_DATA_LENGTH, 1, fp ); fclose( fp ); /* Upper case the file_name. This is to avoid the "File exists" message */ /* when saving the file from one of the internal applications. */ for (offset=0; offset toupper(argv[v][i]) ) { compare = GREATER_THAN; } /* end if */ i++; j++; } /* end if */ } /* end while */ if ( compare == EQUAL ) { while (j < (int) strlen(line) && !isspace(line[j])) j++; while (j < (int) strlen(line) && isspace(line[j])) j++; v++; } /* end if */ } /* end while */ /* Read until the next record */ if (compare == LESS_THAN) { while ( fgets(line, LINE_LENGTH, fp) != NULL && line[0] != '\n' ); } /* endif */ } /* end while */ /* Read each line in the address. If this name is a match, then display */ /* the address. */ do { if (compare == GREATER_THAN || compare == EQUAL) { printing++; /* For the first line, separate the name and telephone number on to */ /* separate lines. LINE points to the name and P points to the */ /* telephone number. */ if (printing == 1) { p = line; found = FALSE; while (!found) { p = strpbrk( p, "(0123456789" ); if (p == NULL || isdigit(*(p+1))) { found = TRUE; } else { p++; } /* end if */ } /* end while */ if (p != NULL) { *(p-1) = '\0'; if (strlen(line) > SCREEN_WIDTH) { line[SCREEN_WIDTH] = '\0'; } /* end if */ fwrite( line, strlen(line), 1, stdout ); fwrite( "\n", 1, 1, stdout ); p[SCREEN_WIDTH] = p[strlen(p)-1] = '\0'; fwrite( p, strlen(p), 1, stdout ); printing++; } else { line[SCREEN_WIDTH] = line[strlen(line)-1] = '\0'; fwrite( line, strlen(line), 1, stdout ); } /* end if */ fwrite( "\n", 1, 1, stdout ); } else { line[strlen(line)-1] = line[SCREEN_WIDTH] = '\0'; fwrite( line, strlen(line), 1, stdout ); if (printing < SCREEN_SIZE) fwrite( "\n", 1, 1, stdout ); } /* end if */ } /* end if */ } while ( (compare == GREATER_THAN || compare == EQUAL) && printing < SCREEN_SIZE && fgets(line, LINE_LENGTH, fp) != NULL && line[0] != '\n' ); return printing; } /* quickadr */ /************************************************************************/ /* ** QUICKDRY expects the following argument list to come from argc/argv: ** ** QUICK Q file_spec offset [day [month [year]]] ** ** The file pointer, fp, already points to the file specified by file_spec. ** The argc/argv parameters are used only to get at the offset and day, month, ** year values. ** ** QUICKDRY finds the entries in the diary that start with the current day ** (or the date passed in). It then displays a screen-full of the diary. ** It returns the number of lines that were displayed on the screen. */ int quickdry ( FILE *fp, int argc, char *argv[] ) { int display_offset; int printing = 0; int weekday; struct time temp_time = { '\0', '\0', '\0', '\0' }; struct date today, diary_date; char line[LINE_LENGTH]; char *arrow; char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; char *days[] = { "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue" }; display_offset = atoi( argv[3] ); /* Get today's date. */ getdate(&today); today.da_year -= 1900; /* if the user has specified any overrides to the start date, use them. */ if (argc > 4) { today.da_day = (char) atoi( argv[4] ); } /* end if */ if (argc > 5) { today.da_mon = (char) atoi( argv[5] ); } /* end if */ if (argc > 6) { today.da_year = atoi( argv[6] ); } /* end if */ /* Start looking for lines in the diary to display on the screen. */ while (printing < SCREEN_SIZE && fgets(line, LINE_LENGTH, fp) != NULL) { if (line[5] == '/') { line[5] = line[8] = line[11] = '\0'; diary_date.da_year = atoi( &line[9] ); diary_date.da_mon = (char) atoi( &line[6] ); diary_date.da_day = (char) atoi( &line[3] ); if ( diary_date.da_year > today.da_year || ( diary_date.da_year == today.da_year && ( diary_date.da_mon > today.da_mon || ( diary_date.da_mon == today.da_mon && diary_date.da_day >= today.da_day ) ) ) ) { /* Select the proper arrow to use. */ arrow = ( diary_date.da_day == today.da_day && diary_date.da_mon == today.da_mon && diary_date.da_year == today.da_year ) ? TODAY_MARKER : OTHER_MARKER; /* Make sure the line does not exceed the screen width. */ line[strlen(&line[12])+11] = line[SCREEN_WIDTH - DATE_WIDTH + 12] = '\0'; weekday = (int) (dostounix( &diary_date, &temp_time ) / 86400L) % 7; printing++; fwrite( arrow, 4, 1, stdout ); fwrite( " ", 1, 1, stdout ); fwrite( days[weekday], 3, 1, stdout ); fwrite( " ", 1, 1, stdout ); fwrite( &line[3], strlen(&line[3]), 1, stdout ); fwrite( " ", 1, 1, stdout ); fwrite( months[diary_date.da_mon-1], 3, 1, stdout ); fwrite( " ", 1, 1, stdout ); fwrite( &line[9], 2, 1, stdout ); fwrite( " ", 1, 1, stdout ); fwrite( &line[12], strlen(&line[12]), 1, stdout ); if (printing < SCREEN_SIZE) { fwrite( "\n", 1, 1, stdout ); } /* end if */ } /* end if */ } else if (printing > 0) { line[strlen(line)-1] = '\0'; /* Make sure the line does not exceed the screen width. */ line[SCREEN_WIDTH + display_offset] = '\0'; printing++; fwrite( &line[display_offset], strlen(&line[display_offset]), 1, stdout ); if (printing < SCREEN_SIZE) { fwrite( "\n", 1, 1, stdout ); } /* end if */ } /* end if */ } /* end while */ return printing; } /* quickdry */