Example #1
0
File: test2.c Project: wtj/formosa
int main(int argc, char **argv){


	int fd;
 	int total_titles;
 	int filesize;
 	int i;

	fd = open(".DIR", O_RDONLY); 
 	
	total_titles = get_num_records_byfd( fd, FH_SIZE )*FH_SIZE;

	if( (fileHDRs = (FILEHEADER **)malloc( filesize )) == NULL ){
		printf("memory alloc error\n");
		exit(0);
	}

	if( read( fd, fileHDRs, filesize ) != filesize ){
		printf("read error\n");
		exit(0);
	} 

	for( i=0; i<total_titles; i++)
		printf("%20s %30s\n", fileHDRs[i]->owner, fileHDRs[i]->title );

	close(fd);
 	free(fileHDRs);
}
Example #2
0
/*
 * update the .THREADHEAD .THREADPOST files accordingly
 *
 * thrheadpos - index pos. in .THREADHEAD file (count from beginning of file)
 * thrpostidx - index pos. of current post (count from the pos. of its
 *											thread head in .THREADPOST
 */
#ifdef	USE_THREADING	/* syhu */
int update_threadinfo(FILEHEADER *fhdr, char *path, int thrheadpos, int thrpostidx )		/* syhu */
{

	THRHEADHEADER thrhead;
	THRPOSTHEADER thrpost, thrpost_tmp;
	char dotdir[PATHLEN];					/* full-pathname for .xxxx file */
 	int fd_thrhead;							/* file descriptor for headfile */
	int fd_thrpost;							/* file descriptor for postfile */
 	int fd_thrpost2;						/* 2nd fd, used for copying */
 	int i;									/* general counter */
 	int index;								/* temp. index */
 	char *buff;								/* general char pointer */
 	BOOL overflow = FALSE;					/* if thread-unit is used up */


	/* file opening & locking stuff */
	sprintf( dotdir, "%s/%s", path, THREAD_HEAD_REC );
	if( (fd_thrhead = open( dotdir, O_RDWR | O_CREAT, 0644 )) <= 0)
 		return (-1);
 	sprintf( dotdir, "%s/%s", path, THREAD_REC );
	if( (fd_thrpost = open( dotdir, O_RDWR | O_CREAT, 0644 )) <= 0 )
 	{
		close( fd_thrhead );
		return (-1);
	}
	if (myflock(fd_thrhead, LOCK_EX) || myflock(fd_thrpost, LOCK_EX)) {
		close(fd_thrhead);
		close(fd_thrpost);
		return -1;
	}


	/* load up default template 'thrhead' and 'thrpost' for later use */
 	/* 'thrhead' */
 	if( thrheadpos == (-1) )		/* if it's a original post, not followup */
 	{
        memcpy( &thrhead, fhdr, FH_SIZE );
        thrhead.numfollow = 0;
 		thrhead.thrpostidx = 0;

 		if( (index=get_num_records_byfd( fd_thrhead, THRHEADHDR_SIZE )) == -1 )
 			goto end;
 		thrhead.thrheadpos = index;

 		if( (index=get_num_records_byfd( fd_thrpost, THRPOSTHDR_SIZE )) == -1 )
 			goto end;
        thrhead.thrpostpos = index;
 	}
	else
	{
 		/* load this entry from .THREADHEAD file */
        if( lseek( fd_thrhead, thrheadpos*THRHEADHDR_SIZE, SEEK_SET ) == -1 ||
            read( fd_thrhead, &thrhead, THRHEADHDR_SIZE) != THRHEADHDR_SIZE )
			goto end;
 		thrhead.numfollow++;				/* update the # of follow-ups */
	}

	/* 'thrpost' */
    memcpy( &thrpost, fhdr, FH_SIZE );
 	thrpost.lastfollowidx = 0;
 	thrpost.nextfollowidx = 0;
	thrpost.nextpostidx = 0;
    thrpost.thrheadpos = thrheadpos;
    thrpost.thrpostidx = thrhead.numfollow;


	/* check if the thread-space in .THREADPOST overflows,
	   if so then move all the entries in this thread to EOF */
	if( thrheadpos != (-1) ) 				 /* if it's a follow-up */
	{
		/* first check if this thread needs to be moved to EOF in .THREADPOST
  		   note that numfollow has been +1 for follow-up posts,
		   NOTE: some optimization can be done here for already-last entry */
		if( (thrhead.numfollow % THREADUNIT_SIZE) == 0 )
 		{
 			/* update the threadhead link position to .THREADPOST's EOF */
 			if( (index=get_num_records_byfd(fd_thrpost,THRPOSTHDR_SIZE)) == -1 )
 				goto end;

			/* move all headers for this thread to EOF, alloc buffer for it */
 			if( (fd_thrpost2 = open( dotdir, O_RDONLY )) > 0 &&
				lseek( fd_thrpost2, thrhead.thrpostpos*THRPOSTHDR_SIZE,
					   SEEK_SET ) != -1 &&
				lseek( fd_thrpost, 0, SEEK_END ) != -1 )
 			{
 				i = thrhead.numfollow*THRPOSTHDR_SIZE;
 				if( (buff=(char *)malloc( i )) != NULL  &&
					read( fd_thrpost2, buff, i ) == i )
 				{
					write( fd_thrpost, (void *)buff, i );
 					free( buff );
	 				close( fd_thrpost2 );
 					thrhead.thrpostpos = index;
					overflow = TRUE;
 				}
			}
		} /* end checking if space isn't enough */
	}

 	/* update linkage info in .THREADPOST */
 	/* first update the 'lastfollowidx' of the post being followed */
 	i = (thrhead.thrpostpos + thrpostidx)*THRPOSTHDR_SIZE;
	if( lseek( fd_thrpost, i, SEEK_SET ) == -1 ||
		read( fd_thrpost, &thrpost_tmp, THRPOSTHDR_SIZE ) != THRPOSTHDR_SIZE )
		goto end;

	i = thrpost_tmp.lastfollowidx;
	thrpost_tmp.lastfollowidx = thrpost.thrpostidx;
 	if( thrpostidx == 0 )				/* if this is the first follow-up */
		thrpost_tmp.nextfollowidx = thrpost.thrpostidx;

	if( lseek( fd_thrpost, -(THRPOSTHDR_SIZE), SEEK_CUR ) == -1  ||
		write( fd_thrpost,&thrpost_tmp,THRPOSTHDR_SIZE ) != THRPOSTHDR_SIZE )
 		goto end;

 	/* then update the 'nextpostidx' in the last followup hdr, IF it's not the
		same as the first. Since for the first there's only 'nextfollowidx'
 		note that since this would be the last of all follow-ups,
		its nextpostidx should be 0 */
 	if( thrpostidx != 0 )
	{
 		i = (thrhead.thrpostpos + i) * THRPOSTHDR_SIZE;
 		if( lseek( fd_thrpost, i, SEEK_SET ) == -1  ||
			read( fd_thrpost, &thrpost_tmp, THRPOSTHDR_SIZE ) !=
				  THRPOSTHDR_SIZE )
			goto end;

 		thrpost_tmp.nextpostidx = thrpost.thrpostidx;

 		if( lseek( fd_thrpost, -(THRPOSTHDR_SIZE), SEEK_CUR ) == -1 ||
			write( fd_thrpost, &thrpost_tmp, THRPOSTHDR_SIZE ) !=
			 	   THRPOSTHDR_SIZE )
 			goto end;
 	}

    /* move fd_thrpost & fd_thrhead to correct position for final write */
    i = (thrhead.thrpostpos + thrpost.thrpostidx)*THRPOSTHDR_SIZE;
    if( lseek( fd_thrpost, i, SEEK_SET ) == -1 )
    	goto end;
	if( thrheadpos == -1 && lseek( fd_thrhead, 0, SEEK_END ) == -1)
		goto end;
 	else if( lseek( fd_thrhead, thrheadpos*THRHEADHDR_SIZE, SEEK_SET ) == -1)
		goto end;

	/* save .THREADPOST & .THREADHEAD entry */
	if( write(fd_thrpost, &thrpost, THRPOSTHDR_SIZE) != THRPOSTHDR_SIZE ||
		write(fd_thrhead, &thrhead, THRHEADHDR_SIZE) != THRHEADHDR_SIZE )
		goto end;

	/* write space-filling blocks in .THREADPOST, calculate how many dummy
	   entries are needed first. this is only necessary when a new
	   thread unit is open, such as original post or unit overflow.
	   note that what's written is space-filling only, it's rather random */
 	if( thrheadpos == (-1) || overflow )
 	{
 		i = THREADUNIT_SIZE - thrhead.numfollow%THREADUNIT_SIZE - 1;
		write( fd_thrpost, (void *)0, i*THRPOSTHDR_SIZE );
	}

	/* adjust file header accordingly */
	fhdr->thrheadpos = thrpost.thrheadpos;
	fhdr->thrpostidx = thrpost.thrpostidx;


	/* closing stuff */
end:
	flock( fd_thrpost, LOCK_UN );
	flock( fd_thrhead, LOCK_UN );
	close( fd_thrpost );
	close( fd_thrhead );

	return 0;

} /* end of update_threadinfo() */
Example #3
0
/*
 * postno is for readrc mechanism
 * It reads the last postno information from INFO_REC
 * If failed, scan all .DIR file to find the last postno.
 * and write it back to INFO_REC.
 */
int get_last_info(const char *dotdir, int fd, INFOHEADER *info, int force)
{
	char finfo[PATHLEN];

	setdotfile(finfo, dotdir, INFO_REC);
	if (force || (get_record(finfo, info, IH_SIZE, 1) != 0)) {
		int i, nr, myfd;
		FILEHEADER lastf, fhtmp;
		time_t lastmtime = 0, mtime;

		if (!dotdir && !fd)
			return -1;

		if (!fd) {
			myfd = open(dotdir, O_RDWR | O_CREAT, 0644);
			if (myfd == -1)
				return -1;
			if (myflock(myfd, LOCK_EX)) {
				close(myfd);
				return -1;
			}
		} else {
			myfd = fd;
		}

		nr = get_num_records_byfd(myfd, FH_SIZE);
		for (i = 1; i <= nr; ++i) {
			if (get_record_byfd(myfd, &fhtmp, FH_SIZE, i) == 0) {
				if (fhtmp.accessed & FILE_DELE)
					continue;

				if (fhtmp.mtime)
					mtime = fhtmp.mtime;
				else if (fhtmp.filename[0] == 'M')
					mtime = strtol(fhtmp.filename + 2, NULL, 10);
				else
					mtime = 0;

				if (mtime > lastmtime) {
					memcpy(&lastf, &fhtmp, FH_SIZE);
					lastmtime = mtime;
				}
			} else {
				break;
			}
		}

		if (!fd) {
			flock(myfd, LOCK_UN);
			close(myfd);
		}

		if (i <= nr)
			return -1;

		memset(info, 0, IH_SIZE);
		if (lastmtime) {
			info->last_postno = lastf.postno;
			info->last_mtime  = lastf.mtime;
			strcpy(info->last_filename, lastf.filename);
		} else {
			/* There is no article yet. */
			info->last_postno = 0;
			info->last_mtime = 0;
			strcpy(info->last_filename, "M.000000000.A");
		}
		if (substitute_record(finfo, info, IH_SIZE, 1) == -1)
			return -1;
	}

	return 0;
}