1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
/************************************************************************
* LOG.C - Creates a ASCII file with time and date stamps for logging *
* hours. *
* *
* usage: LOG [IN][OUT][CALC] *
* IN - Creates an opening entry from which a "time spent" *
* is calculated. *
* OUT - Creates a closing entry and calculates *
* "time spent" for that entry. *
* CALC - Calculates total overall "time spent" for the *
* entire log. *
* *
* NOTES: I used seconds to do all the calculations. The other *
* time/date entries are for human readability. Some *
* enhancments can be done to this program. *
* i.e. Wage/Pay calculation, closing the log after a CALC *
* to insure log is not reused, tracking hours for individual *
* people, tracking hours for individual projects, etc. *
* *
* Public domain by Robert Sprawls. *
************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <time.h>
/* Define time file constants */
#define HOUR 3600 /* Number of seconds in an hour. */
#define MINS 60 /* Number of seconds in a minute */
#define IN_ENTRY 40 /* Size of an IN entry */
#define SEC_OFF 4 /* Offset of seconds in an IN entry */
#define HOUR_OFF 64 /* Offset of seconds in an "time spent" */
/* calculated entry. */
/* Define values returned to DOS */
#define OK 0 /* Executed normally, nothing will be eched */
#define OPENLOG 1 /* Attempted to log in while open entry in log */
#define CLOSEDLOG 2 /* Attempted to log out while closed entry in log */
#define FILE_ERROR 3 /* File access error. Just in case. */
#define SEEK_ERROR 4 /* File positioning error */
#define NOPARMS 5 /* No parameters supplied to program */
#define INVALID 6 /* Invalid parameters */
void usage( void );
long get_in_entry( FILE * );
void fastforw( FILE * ); /* Oppisite of rewind(); */
void quit( int );
char strbuf[ IN_ENTRY + 1 ];
FILE *wrklog;
int main( int argc, char *argv[] )
{
char outline[ IN_ENTRY * 2 + 1 ];
long in_entry_time = 0, total_seconds = 0;
double hours, pay;
time_t current_time;
div_t hdiv, mdiv;
if( argc < 2 )
{
usage();
quit( NOPARMS );
}
/* Open log. Can be any directory. */
if(( wrklog = fopen( "WORK.LOG", "a+" )) == NULL )
quit( FILE_ERROR );
strupr( argv[ 1 ] );
time( ¤t_time );
/* Create an opening IN entry. */
if( strcmp( "IN", argv[ 1 ] ) == 0 )
{
/* Make sure there isn't a open entry already. */
if( get_in_entry( wrklog ) )
quit( OPENLOG );
/* Stamp it. */
fprintf( wrklog, "%3s %ld %s", argv[ 1 ], current_time,
ctime( ¤t_time ));
}
/* Create a closinf OUT entry. */
else if( strcmp( "OUT", argv[ 1 ] ) == 0 )
{
/* Make sure there is a previous IN entry. */
if( ( in_entry_time = get_in_entry( wrklog )) == 0 )
quit( CLOSEDLOG );
total_seconds = current_time - in_entry_time;
sprintf( outline, "%3s %ld %s", argv[ 1 ], current_time,
ctime( ¤t_time ));
/* Cut off the newline character that's normally put on. */
outline[ strlen( outline ) - 1 ] = '\0';
hdiv = div( total_seconds, HOUR );
mdiv = div( hdiv.rem, MINS );
sprintf( strbuf, " Time Spent: %02d:%02d:%02d/%ld\n\n",
hdiv.quot, mdiv.quot, mdiv.rem, total_seconds );
strcat( outline, strbuf );
fprintf( wrklog, outline );
}
/* Calculate the overall "time spent" */
else if( strcmp( "CALC", argv[ 1 ] ) == 0 )
{
rewind( wrklog );
while( !feof( wrklog ) )
{
/* This is to eliminate garbage or residual entries. */
outline[ 0 ] = '\0';
fgets( outline, 80, wrklog );
if( strstr( outline, "OUT" ) != NULL )
{
total_seconds += atol( &outline[ HOUR_OFF ] );
}
}
/* goto to end of file and stamp total hours */
fastforw( wrklog );
if( total_seconds )
{
hdiv = div( total_seconds, HOUR );
mdiv = div( hdiv.rem, MINS );
fprintf( wrklog, "\t\t\t\t\t\t\t\t\t\t "
"Total Hours: %02d:%02d:%02d/%ld\n",
hdiv.quot, mdiv.quot, mdiv.rem, total_seconds );
}
}
else
{
usage();
quit( INVALID );
}
quit( OK );
}
void usage( void )
{
printf( "\nusage: LOG [IN][OUT][CALC]\n");
}
/****************************************************************
* get_in_entry - gets a previous IN entry. *
* *
* Params: FILES *fp - file pointer. *
* Returns: The entry's seconds if successful, else 0 *
* *
* NOTES: If fseek fails for any reason, function does not *
* return. Instead, quit is call with the error code. *
****************************************************************/
long get_in_entry( FILE *fp )
{
if( fseek( fp, -IN_ENTRY, SEEK_END ) != 0 )
quit( SEEK_ERROR );
fread( strbuf, 1, IN_ENTRY, fp );
fastforw( fp );
if( strstr( strbuf, "IN" ) == NULL )
return( 0 );
else
{
return( atol( &strbuf[ SEC_OFF ]));
}
}
/****************************************************************
* quit() - Program exit function. Reports of any outstanding *
* errors. *
* *
* Params: errcode - Error code as defined in beginning. *
* Returns: nothing. *
****************************************************************/
void quit( int errcode )
{
char *errmsg[] =
{
"",
"Log has an open entry.",
"No corresponding IN entry.",
"File open error.",
"Seek error",
"No parameters specified.",
"Invalid Parameters."
};
printf( "\n%s\n", errmsg[ errcode ] );
fclose( wrklog );
exit( errcode );
}
/****************************************************************
* fastforw() - Puts file pointer to end of file. *
* *
* Params: fp - File pointer. *
* Returns: nothing. *
****************************************************************/
void fastforw( FILE *fp )
{
fseek( fp, 0, SEEK_END );
}
|