/*
 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <xfs/xfs.h>
#include <xfs/jdm.h>

#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include "types.h"
#include "mlog.h"
#include "inv_priv.h"


/*----------------------------------------------------------------------*/
/*  init_idb                                                            */
/*                                                                      */
/*  Returns -1 if we are done with initialization, the fd if not.	*/
/*  The idb_token indicates whether there was an error or not, if the 	*/
/*  return value is -1.                                                 */
/*----------------------------------------------------------------------*/

int
init_idb( void *pred, inv_predicate_t bywhat, inv_oflag_t forwhat,
	  inv_idbtoken_t *tok )
{
	char fname[ INV_STRLEN ];
	char uuname[ INV_STRLEN ];
	int fd;

	*tok = INV_TOKEN_NULL;
	/* make sure INV_DIRPATH exists, and is writable */
	if ( make_invdirectory( forwhat ) < 0 )
		return I_DONE;

	/* come up with the unique file suffix that refers to this
	   filesystem */
	if ( fstab_get_fname( pred, uuname, bywhat, forwhat ) < 0 ) {
		return I_DONE;
	}

	( void )strcpy( fname, uuname );
	strcat ( fname, INV_INVINDEX_PREFIX );

	/* first check if the inv_index file exists: if not create it */
	if ( ( fd = open( fname, INV_OFLAG(forwhat) ) ) == -1 ) {
		if (errno != ENOENT) {
			INV_PERROR ( fname );
		} else if (forwhat == INV_SEARCH_N_MOD) {
			*tok = idx_create( fname, forwhat ); 
		} else {
			/* this happens when the inv is empty and the user
			   wants to do a search. this is legal - not an error */
			return I_EMPTYINV;
		}
		return I_DONE; /* we are done whether token's NULL or not */
	}
	
	/* we've got to do more housekeeping stuff. so signal that */
	return fd;
}





inv_idbtoken_t
get_token( int invfd, int stobjfd  )
{
	invt_desc_entry_t *desc;

	desc = (invt_desc_entry_t *) malloc
		( sizeof( invt_desc_entry_t ) );
	
	desc->d_invindex_fd = invfd;
	desc->d_stobj_fd  = stobjfd;
	desc->d_update_flag = 0;
	desc->d_invindex_off = -1;

	return (inv_idbtoken_t) desc; /* yukky, but ok for the time being */
}






void
destroy_token( inv_idbtoken_t tok )
{
	free ( (invt_desc_entry_t *) tok );
}



inv_sestoken_t
get_sesstoken( inv_idbtoken_t tok )
{
	inv_sestoken_t stok;

	stok = (inv_sestoken_t) malloc( sizeof( invt_sesdesc_entry_t ) );
	stok->sd_invtok = tok;
	stok->sd_session_off = stok->sd_sesshdr_off = -1;
	stok->sd_sesstime = (time32_t) 0;
	return stok;
}






/*---------------------------------------------------------------------------*/
/*                                                                           */
/*                                                                           */
/*                                                                           */
/*---------------------------------------------------------------------------*/
bool_t
invmgr_query_all_sessions (
	void *inarg,
	void **outarg,
	search_callback_t func)
{
	invt_counter_t *cnt;
	invt_fstab_t *arr;
	int numfs, i, fd, invfd;
	char fname[INV_STRLEN];
	int result;
	inv_oflag_t forwhat = INV_SEARCH_ONLY;
	void *objectfound;

	/* if on return, this is still null, the search failed */
	*outarg = NULL; 
	ASSERT(inarg);

	fd = fstab_getall( &arr, &cnt, &numfs, forwhat );
	/* special case missing file: ok, outarg says zero */
	if ( fd < 0 && errno == ENOENT ) {
		return BOOL_TRUE;
	}
	if ( fd < 0 || numfs <= 0 ) {
		mlog( MLOG_NORMAL | MLOG_INV, _("INV: Error in fstab\n") );
		return BOOL_FALSE;
	}
	
	close( fd );

	for ( i = 0; i < numfs; i++) {
		if ( fstab_get_fname( &arr[i].ft_uuid, fname, 
				     (inv_predicate_t)INV_BY_UUID,
				     forwhat) < 0 ) {
			mlog( MLOG_NORMAL | MLOG_INV, _(
			     "INV: Cant get inv-name for uuid\n")
			     );
			return BOOL_FALSE;
		}
		strcat( fname, INV_INVINDEX_PREFIX );
		invfd = open( fname, INV_OFLAG(forwhat) );
		if ( invfd < 0 ) {
			mlog( MLOG_NORMAL | MLOG_INV, _(
			     "INV: Open failed on %s\n"),
			     fname
			     );
			return BOOL_FALSE;
		}
		result = search_invt( invfd, inarg, &objectfound, func );
		close(invfd);		

		/* if error return BOOL_FALSE */
		if (result < 0) {
			return BOOL_FALSE;
		} else if ((result == 1) && *outarg) {
			/* multiple entries found,  more info needed */
			*outarg = NULL;
			return BOOL_TRUE;
		} else if (result == 1) {
			*outarg = objectfound;
		}
	}
	
	/* return val indicates if there was an error or not. *buf
	   says whether the search was successful */
	return BOOL_TRUE;
}




/*----------------------------------------------------------------------*/
/* search_invt                                                          */
/*                                                                      */
/* Used by the toplevel (inv layer ) to do common searches on the inven-*/
/* tory. Caller supplies a callback routine that performs the real      */
/* comparison/check.                                                    */
/*----------------------------------------------------------------------*/

intgen_t
search_invt( 
	int 			invfd,
	void 			*arg, 
	void 			**buf,
	search_callback_t 	do_chkcriteria )
{

	int 		fd, i;
	invt_entry_t	*iarr = NULL;
	invt_counter_t	*icnt = NULL;
	int	     	nindices;
	

	if (invfd == I_EMPTYINV)
		return -1;

	/* set the caller's buffer pointer to NULL initially.
	 * if no session found, the caller will expect to see
	 * NULL.
	 */
	*( char ** )buf = NULL;

	if ( ( nindices = GET_ALLHDRS_N_CNTS( invfd, (void **)&iarr, 
					      (void **)&icnt, 
					      sizeof( invt_entry_t ),
					      sizeof( invt_counter_t )) 
	      ) <= 0 ) {
		return -1;
	}

	free( icnt );

	/* we need to get all the invindex headers and seshdrs in reverse
	   order */
	for (i = nindices - 1; i >= 0; i--) {
		int 			nsess;
		invt_sescounter_t 	*scnt = NULL;
		invt_seshdr_t		*harr = NULL;
		bool_t                  found;

		fd = open (iarr[i].ie_filename, O_RDONLY );
		if (fd < 0) {
			INV_PERROR( iarr[i].ie_filename );
			continue;
		}
		INVLOCK( fd, LOCK_SH );

		/* Now see if we can find the session we're looking for */
		if (( nsess = GET_ALLHDRS_N_CNTS_NOLOCK( fd, (void **)&harr, 
						  (void **)&scnt, 
						  sizeof( invt_seshdr_t ),
						 sizeof( invt_sescounter_t ))
		     ) < 0 ) {
			INV_PERROR( iarr[i].ie_filename );
			INVLOCK( fd, LOCK_UN );
			close( fd );
			continue;
		}
		free ( scnt );

		while ( nsess ) {
			/* fd is kept locked until we return from the 
			   callback routine */

			/* Check to see if this session has been pruned 
			 * by xfsinvutil before checking it. 
			 */
			if ( harr[nsess - 1].sh_pruned ) {
				--nsess;
				continue;
			}
			found = (* do_chkcriteria ) ( fd, &harr[ --nsess ],
						      arg, buf );
			if (! found ) continue;
			
			/* we found what we need; just return */
			INVLOCK( fd, LOCK_UN );
			close( fd );
			free( harr );

			return found; /* == -1 or 1 */
		}
		
		INVLOCK( fd, LOCK_UN );
		close( fd );
	}
	
	return 0;
}



/*---------------------------------------------------------------------------*/
/*                                                                           */
/*                                                                           */
/*                                                                           */
/*---------------------------------------------------------------------------*/


intgen_t
invmgr_inv_print(
	int 		invfd, 
	invt_pr_ctx_t 	*prctx)
{

	int 		fd, i;
	invt_entry_t	*iarr = NULL;
	invt_counter_t	*icnt = NULL;
	int	     	nindices;
	u_int           ref = 0;

	if (invfd == I_EMPTYINV)
		return 0;
	
		
	if ( ( nindices = GET_ALLHDRS_N_CNTS( invfd, (void **)&iarr, 
					      (void **)&icnt, 
					      sizeof( invt_entry_t ),
					      sizeof( invt_counter_t )) 
	      ) <= 0 ) {
		return -1;
	}
	
	free( icnt );

	if (prctx->invidx) {
		idx_DEBUG_printinvindices( iarr, (u_int) nindices );
		free(iarr);
		return (0);
	}



	for ( i = 0; i < nindices; i++ ) {
		int 			nsess;
		invt_sescounter_t 	*scnt = NULL;
		invt_seshdr_t		*harr = NULL;
		int                     s;

		fd = open (iarr[i].ie_filename, O_RDONLY );
		if (fd < 0) {
			INV_PERROR( iarr[i].ie_filename );
			continue;
		}
		INVLOCK( fd, LOCK_SH );

		/* Now see if we can find the session we're looking for */
		if (( nsess = GET_ALLHDRS_N_CNTS_NOLOCK( fd, (void **)&harr, 
						  (void **)&scnt, 
						  sizeof( invt_seshdr_t ),
						 sizeof( invt_sescounter_t ))
		     ) < 0 ) {
			INV_PERROR( iarr[i].ie_filename );
			INVLOCK( fd, LOCK_UN );
			close( fd );
			continue;
		}
		free ( scnt );
		for( s = 0; s < nsess; s++ ) {
			/* fd is kept locked until we return from the 
			   callback routine */

			/* Check to see if this session has been pruned 
			 * by xfsinvutil before returning it. 
			 */
			if ( harr[s].sh_pruned ) {
				continue;
			}

			(void)DEBUG_displayallsessions( fd, &harr[ s ],
						        ref++, prctx);
		}
			
		INVLOCK( fd, LOCK_UN );
		close( fd );
	}
	
	free (iarr);
	return 0;
}



/*---------------------------------------------------------------------------*/
/*                                                                           */
/*                                                                           */
/*                                                                           */
/*---------------------------------------------------------------------------*/


intgen_t
invmgr_inv_check(
	int invfd)
{

	int 		fd, i;
	invt_entry_t	*iarr = NULL;
	invt_counter_t	*icnt = NULL;
	int	     	nindices;

	if (invfd == I_EMPTYINV)
		return 0;
	
	if ( ( nindices = GET_ALLHDRS_N_CNTS( invfd, (void **)&iarr, 
					      (void **)&icnt, 
					      sizeof( invt_entry_t ),
					      sizeof( invt_counter_t )) 
	      ) <= 0 ) {
		return -1;
	}

	free( icnt );


	for ( i = 0; i < nindices; i++ ) {
		int 			nsess;
		invt_sescounter_t 	*scnt = NULL;
		invt_seshdr_t		*harr = NULL;
		int                     s;

		fd = open (iarr[i].ie_filename, O_RDONLY );
		if (fd < 0) {
			INV_PERROR( iarr[i].ie_filename );
			continue;
		}
		INVLOCK( fd, LOCK_SH );

		/* Now see if we can find the session we're looking for */
		if (( nsess = GET_ALLHDRS_N_CNTS_NOLOCK( fd, (void **)&harr, 
						  (void **)&scnt, 
						  sizeof( invt_seshdr_t ),
						 sizeof( invt_sescounter_t ))
		     ) < 0 ) {
			INV_PERROR( iarr[i].ie_filename );
			INVLOCK( fd, LOCK_UN );
			close( fd );
			continue;
		}
		free ( scnt );
		
		if ((iarr[i].ie_timeperiod.tp_start != harr[0].sh_time) ||
		    (iarr[i].ie_timeperiod.tp_end != harr[nsess-1].sh_time)) {
			printf(_("INV: Check %d failed.\n"), i+1);
			printf(_("invidx (%d)\t%d - %d\n"),
			       i+1,
			       iarr[i].ie_timeperiod.tp_start,
			       iarr[i].ie_timeperiod.tp_end);
			for( s = 0; s < nsess; s++ ) {
				printf(_("tm (%d)\t%d\n"), s, harr[s].sh_time);
			}
		}
		else {
			printf(_("INV: Check %d out of %d succeeded\n"),
			       i+1, nindices);
		}
		INVLOCK( fd, LOCK_UN );
		close( fd );
	}
	
	return 0;
}


/*----------------------------------------------------------------------*/
/*                                                                      */
/*                                                                      */
/*                                                                      */
/*----------------------------------------------------------------------*/

/* ARGSUSED */
bool_t
tm_level_lessthan( int fd, invt_seshdr_t *hdr, void *arg,
		   void **tm )
{
	u_char level = *(u_char *)arg;
	*tm = NULL;
	if ( IS_PARTIAL_SESSION( hdr ) )
		return 0;
	if (hdr->sh_level < level ) {
#ifdef INVT_DEBUG
		mlog( MLOG_DEBUG | MLOG_INV, "$ found level %d < %d\n", hdr->sh_level, 
		     level );
#endif
		*tm = calloc( 1, sizeof( time32_t ) );
		memcpy( *tm, &hdr->sh_time, sizeof( time32_t ) );
		return 1;
	}
	return 0;
}




/*----------------------------------------------------------------------*/
/*                                                                      */
/*                                                                      */
/*                                                                      */
/*----------------------------------------------------------------------*/

bool_t
lastsess_level_lessthan( int fd, invt_seshdr_t *hdr, void *arg,
			 void **buf )
{
	u_char level = *(u_char *)arg;
	*buf = NULL;
	if ( IS_PARTIAL_SESSION( hdr ) )
		return 0;
	if (hdr->sh_level < level ) {
#ifdef INVT_DEBUG
		mlog( MLOG_DEBUG | MLOG_INV, "$ found (ses) level %d < %d \n",
		     hdr->sh_level, level );
#endif
		return stobj_make_invsess( fd, (inv_session_t **) buf, hdr );
	}
	return 0;

}



/*----------------------------------------------------------------------*/
/*                                                                      */
/*                                                                      */
/*                                                                      */
/*----------------------------------------------------------------------*/

bool_t
lastsess_level_equalto( int fd, invt_seshdr_t *hdr,
		       void *arg, void **buf )
{
	u_char level = *(u_char *)arg;
	*buf = NULL;
	if ( IS_PARTIAL_SESSION( hdr ) )
		return 0;
	if (hdr->sh_level == level ) {
#ifdef INVT_DEBUG
	mlog( MLOG_DEBUG | MLOG_INV, "$ found (ses) level %d == %d \n", hdr->sh_level,
	     level );
#endif
		return stobj_make_invsess( fd, (inv_session_t **) buf, hdr );
	}
	return 0;


}






/*----------------------------------------------------------------------*/
/* insert_session                                                       */
/*                                                                      */
/* insert a session that may or may not be already in the inventory.    */
/* this is used in reconstructing the database.                         */
/*----------------------------------------------------------------------*/
bool_t
insert_session( invt_sessinfo_t *s)
{	
	inv_idbtoken_t tok = INV_TOKEN_NULL;
	int invfd, stobjfd = -1;
	invt_idxinfo_t	  idx;
	bool_t		  ret = BOOL_FALSE;
	inv_oflag_t       forwhat = INV_SEARCH_N_MOD;

	/* initialize the inventory */
	if ( ( invfd = init_idb ( (void *) s->ses->s_fsid, 
				  (inv_predicate_t) INV_BY_UUID,
 				  forwhat,
				  &tok ) ) < 0 ) {
		if ( tok == INV_TOKEN_NULL ) {
#ifdef INVT_DEBUG
			mlog( MLOG_DEBUG | MLOG_INV, "INV: insert_session: init_db "
			      "failed\n" );
#endif
			return BOOL_FALSE;
		}
		
		invfd = tok->d_invindex_fd;
		close( tok->d_stobj_fd );
		destroy_token( tok );
	}
	
	/* at this point we know that invindex has at least one entry
	
	   First we need to find out if this session is in the inventory
	   already. To find the storage object that can possibly
	   contain this session, it suffices to sequentially search the
	   inventory indices of this filesystem for the particular invt-entry
	 */
	INVLOCK( invfd, LOCK_EX );
	idx.invfd = invfd;
	stobjfd = idx_find_stobj( &idx, s->seshdr->sh_time );
	if (stobjfd < 0) {
		INVLOCK( invfd, LOCK_UN );
		free( idx.icnt );
		free( idx.iarr );
		return BOOL_FALSE;
	}

	/* Now put the session in the storage-object */
	INVLOCK( stobjfd, LOCK_EX );
	if ( ( stobj_insert_session( &idx, stobjfd, s ) < 0 ) ||
		( idx_recons_time ( s->seshdr->sh_time, &idx ) < 0 ) )
			ret = BOOL_TRUE;
		
	INVLOCK( stobjfd, LOCK_UN );
	INVLOCK( invfd, LOCK_UN );

	free( idx.icnt );
	free( idx.iarr );

	if (ret) return BOOL_FALSE;

	/* make sure the fstab is uptodate too */
	if ( fstab_put_entry( &s->ses->s_fsid, s->ses->s_mountpt, s->ses->s_devpath,
			      forwhat ) < 0 )
		return BOOL_FALSE;

	/* and we are done */
	return BOOL_TRUE;
	
}



/*----------------------------------------------------------------------*/
/*                                                                      */
/*                                                                      */
/*                                                                      */
/*----------------------------------------------------------------------*/

intgen_t
make_invdirectory( inv_oflag_t forwhat )
{
	struct stat64 st;
	char path[PATH_MAX];
	char *p;

	p = strcpy( path, INV_DIRPATH );

	if ( stat64( path, &st ) == 0 )
		return 1;

	if ( forwhat == INV_SEARCH_ONLY || errno != ENOENT )
		return -1;

	do {
		p++;
		if ( *p == '/' ) {
			*p = '\0';
			if ( mkdir( path, (mode_t)0755 ) < 0 ) {
				if ( errno != EEXIST ) {
					INV_PERROR( path );
					return -1;
				}
			}
			*p = '/';
		}
	} while ( *p );

	if ( mkdir( path, (mode_t)0755 ) < 0 ) {
		if ( errno != EEXIST ) {
			INV_PERROR( path );
			return -1;
		}
	}

	mlog( MLOG_VERBOSE | MLOG_INV, _("%s created\n"), path );
	return 1;
}

#ifdef NOTDEF

bool_t
invmgr_lockinit( void )
{
	if ( invlock_fd == -1 ) {
		if (( invlock_fd = open( INV_LOCKFILE, 
					O_RDONLY | O_CREAT, S_IRUSR|S_IWUSR )) < 0 ) {
			INV_PERROR( INV_LOCKFILE );
			return BOOL_FALSE;
		}
		fchmod ( invlock_fd, INV_PERMS );
	}
	return BOOL_TRUE;
}
	
	
bool_t
invmgr_trylock( invt_mode_t mode )
{
	int md;
	ASSERT( invlock_fd >= 0 );
	
	md = (mode == INVT_RECONSTRUCT) ? LOCK_EX: LOCK_SH;

	if (INVLOCK( invlock_fd, md | LOCK_NB ) < 0)
		return BOOL_FALSE;

	return BOOL_TRUE;
}

void
invmgr_unlock( void )
{
	ASSERT( invlock_fd >= 0 );
	
	INVLOCK( invlock_fd, LOCK_UN );	

}

#endif

