/* highscore-lib-centralized.c -- Hiscore Library for centralized systems. Created on: 2008/11/28 11:45:58 ~yas/dsys/highscore/centralized/highscore-lib-centralized.c */ #include /* open() */ #include /* fstat() */ #include /* fstat() */ #include /* memcpy(), memset() */ #include /* snprintf(), perror() */ #include /* getenv() */ #include #include "highscore.h" static int insert_score( score_record_t records[], int len, int nelement, int score, char *user ); static int find_posision( score_record_t records[], int len, int nelement, int score ); int get_highscore(score_record_t records[], int len) { int fd; struct stat stat; ssize_t bytes; char *filename; if( (filename=getenv(HIGHSCORE_FILE_ENV)) == NULL ) { fprintf(stdout,"No environment: %s\n",HIGHSCORE_FILE_ENV ); return( 0 ); } if( (fd = open(filename,O_RDONLY)) < 0 ) { perror( filename ); return( 0 ); } if( flock(fd,LOCK_SH) < 0 ) { perror("flock"); goto error0; } if( fstat(fd,&stat) < 0 ) { perror("fstat"); goto error1; } bytes = (stat.st_size <= len*sizeof(score_record_t)) ? stat.st_size : len*sizeof(score_record_t) ; if( read(fd, records, bytes)!=bytes ) { perror("read"); goto error1; } if( flock(fd,LOCK_UN) < 0 ) { perror("flock"); goto error0; } close( fd ); return( bytes/sizeof(score_record_t) ); error1: flock( fd,LOCK_UN ); error0: close( fd ); return( 0 ); } int put_score(int score, char *user) { int fd, n; struct stat stat; ssize_t bytes; off_t offset ; score_record_t records[HIGHSCORE_MAX_RECORDS]; char *filename; if( (filename=getenv(HIGHSCORE_FILE_ENV)) == NULL ) { fprintf(stdout,"No environment: %s\n",HIGHSCORE_FILE_ENV ); return( 0 ); } if( (fd = open( filename,O_RDWR|O_CREAT, 0666)) < 0 ) { perror( filename ); return( 0 ); } if( flock(fd,LOCK_EX) < 0 ) { perror("flock"); goto error0; } if( fstat(fd,&stat) < 0 ) { perror("fstat"); goto error1; } bytes = (stat.st_size <= HIGHSCORE_MAX_RECORDS*sizeof(score_record_t))? stat.st_size : HIGHSCORE_MAX_RECORDS*sizeof(score_record_t) ; if( read(fd, records, bytes)!=bytes ) { perror("read"); goto error1; } n = insert_score( records,HIGHSCORE_MAX_RECORDS,bytes/sizeof(score_record_t), score, user ); if( n > 0 ) { offset = 0L; if( lseek( fd, offset, SEEK_SET )< 0 ) { perror("lseek"); goto error1; } bytes = n * sizeof(score_record_t); if( write(fd, records, bytes)!=bytes ) { perror("write"); goto error1; } } if( flock(fd,LOCK_UN) < 0 ) { perror("flock"); goto error1; } close( fd ); return( 1 ); error1: flock( fd,LOCK_UN ); error0: close( fd ); return( 0 ); } static int insert_score( score_record_t records[], int len, int nelement, int score, char *user ) { int pos, copy_records; pos = find_posision( records, len, nelement, score ); if( pos < 0 ) return( -1 ); if( nelement == len ) copy_records = nelement - pos - 1; else copy_records = nelement - pos ; memcpy( &records[pos+1], &records[pos], copy_records*sizeof(score_record_t) ); memset( &records[pos], 0, sizeof(score_record_t) ); records[pos].score = score ; snprintf( records[pos].name, HIGHSCORE_NAME_LEN, "%s", user ); return( nelement == len ? nelement : nelement+1 ); } static int find_posision( score_record_t records[], int len, int nelement, int score ) { score_record_t *pos; int i; for( i=0; i