/*
 * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 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.
 *
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 *
 * http://www.sgi.com
 *
 * For further information regarding this notice, see:
 *
 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
 */
/*
 * This module contains code for logging writes to files, and for
 * perusing the resultant logfile.  The main intent of all this is
 * to provide a 'write history' of a file which can be examined to
 * judge the state of a file (ie. whether it is corrupted or not) based
 * on the write activity.
 *
 * The main abstractions available to the user are the wlog_file, and
 * the wlog_rec.  A wlog_file is a handle encapsulating a write logfile.
 * It is initialized with the wlog_open() function.  This handle is
 * then passed to the various wlog_xxx() functions to provide transparent
 * access to the write logfile.
 *
 * The wlog_rec datatype is a structure which contains all the information
 * about a file write.  Examples include the file name, offset, length,
 * pattern, etc.  In addition there is a bit which is cleared/set based
 * on whether or not the write has been confirmed as complete.  This
 * allows the write logfile to contain information on writes which have
 * been initiated, but not yet completed (as in async io).
 *
 * There is also a function to scan a write logfile in reverse order.
 *
 * NOTE:	For target file analysis based on a write logfile, the
 * 		assumption is made that the file being written to is
 * 		locked from simultaneous access, so that the order of
 * 		write completion is predictable.  This is an issue when
 * 		more than 1 process is trying to write data to the same
 *		target file simultaneously.
 *
 * The history file created is a collection of variable length records
 * described by scruct wlog_rec_disk in write_log.h.  See that module for
 * the layout of the data on disk.
 */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "write_log.h"

#ifndef BSIZE
#ifdef DEV_BSIZE
#define BSIZE DEV_BSIZE
#else
#define BSIZE BBSIZE
#endif
#endif

#ifndef PATH_MAX
#define PATH_MAX          255
/*#define PATH_MAX pathconf("/", _PC_PATH_MAX)*/
#endif

char	Wlog_Error_String[256];

#if __STDC__
static int	wlog_rec_pack(struct wlog_rec *wrec, char *buf, int flag);
static int	wlog_rec_unpack(struct wlog_rec *wrec, char *buf);
#else
static int	wlog_rec_pack();
static int	wlog_rec_unpack();
#endif

/*
 * Initialize a write logfile.  wfile is a wlog_file structure that has
 * the w_file field filled in.  The rest of the information in the
 * structure is initialized by the routine.
 *
 * The trunc flag is used to indicate whether or not the logfile should
 * be truncated if it currently exists.  If it is non-zero, the file will
 * be truncated, otherwise it will be appended to.
 *
 * The mode argument is the [absolute] mode which the file will be
 * given if it does not exist.  This mode is not affected by your process
 * umask.
 */

int
wlog_open(wfile, trunc, mode)
struct wlog_file	*wfile;
int			trunc;
int			mode;
{
	int	omask, oflags;

	if (trunc)
		trunc = O_TRUNC;

	omask = umask(0);

	/*
	 * Open 1 file descriptor as O_APPEND
	 */

	oflags = O_WRONLY | O_APPEND | O_CREAT | trunc;
	wfile->w_afd =
		open(wfile->w_file, oflags, mode);
	umask(omask);

	if (wfile->w_afd == -1) {
		sprintf(Wlog_Error_String,
			"Could not open write_log - open(%s, %#o, %#o) failed:  %s\n",
			wfile->w_file, oflags, mode, strerror(errno));
		return -1;
	}

	/*
	 * Open the next fd as a random access descriptor
	 */

	oflags = O_RDWR;
	if ((wfile->w_rfd = open(wfile->w_file, oflags)) == -1) {
		sprintf(Wlog_Error_String,
			"Could not open write log - open(%s, %#o) failed:  %s\n",
			wfile->w_file, oflags, strerror(errno));
		close(wfile->w_afd);
		wfile->w_afd = -1;
		return -1;
	}

	return 0;
}

/*
 * Release all resources associated with a wlog_file structure allocated
 * with the wlog_open() call.
 */

int
wlog_close(wfile)
struct wlog_file	*wfile;
{
	close(wfile->w_afd);
	close(wfile->w_rfd);
	return 0;
}

/*
 * Write a wlog_rec structure to a write logfile.  Offset is used to
 * control where the record will be written.  If offset is < 0, the
 * record will be appended to the end of the logfile.  Otherwise, the
 * record which exists at the indicated offset will be overlayed.  This
 * is so that we can record writes which are outstanding (with the w_done
 * bit in wrec cleared), but not completed, and then later update the
 * logfile when the write request completes (as with async io).  When
 * offset is >= 0, only the fixed length portion of the record is
 * rewritten.  See text in write_log.h for details on the format of an
 * on-disk record.
 *
 * The return value of the function is the byte offset in the logfile
 * where the record begins.
 *
 * Note:  It is the callers responsibility to make sure that the offset
 * parameter 'points' to a valid record location when a record is to be
 * overlayed.  This is guarenteed by saving the return value of a previous
 * call to wlog_record_write() which wrote the record to be overlayed.
 *
 * Note2:  The on-disk version of the wlog_rec is MUCH different than
 * the user version.  Don't expect to od the logfile and see data formatted
 * as it is in the wlog_rec structure.  Considerable data packing takes
 * place before the record is written.
 */

int
wlog_record_write(wfile, wrec, offset)
struct wlog_file	*wfile;
struct wlog_rec		*wrec;
long			offset;
{
    int		reclen;
    char	wbuf[WLOG_REC_MAX_SIZE + 2];

    /*
     * If offset is -1, we append the record at the end of file
     *
     * Otherwise, we overlay wrec at the file offset indicated and assume
     * that the caller passed us the correct offset.  We do not record the
     * fname in this case.
     */

    reclen = wlog_rec_pack(wrec, wbuf, (offset < 0));

    if (offset < 0) {
	/*
	 * Since we're writing a complete new record, we must also tack
	 * its length onto the end so that wlog_scan_backward() will work.
	 * Length is asumed to fit into 2 bytes.
	 */

	    wbuf[reclen] = reclen / 256;
	    wbuf[reclen+1] = reclen % 256;
	    reclen += 2;

            if ( write(wfile->w_afd, wbuf, reclen) == -1 ) {
                  sprintf(Wlog_Error_String,
                          "Could not write log - write(%s, %s, %d) failed:  %s\n",
                           wfile->w_file, wbuf, reclen, strerror(errno));
                  return -1;
            } else {
                 offset = lseek(wfile->w_afd, 0, SEEK_CUR) - reclen;
                 if ( offset == -1 ) {
                       sprintf(Wlog_Error_String,
                               "Could not reposition file pointer - lseek(%s, 0, SEEK_CUR) failed:  %s\n",
                                wfile->w_file, strerror(errno));
                       return -1;
                 }
            }
    } else {
            if ( (lseek(wfile->w_rfd, offset, SEEK_SET)) == -1 ) {
                  sprintf(Wlog_Error_String,
                          "Could not reposition file pointer - lseek(%s, %ld, SEEK_SET) failed:  %s\n",
                           wfile->w_file, offset, strerror(errno));
                  return -1;
            } else {
                  if ( (write(wfile->w_rfd, wbuf, reclen)) == -1 ) {
                        sprintf(Wlog_Error_String,
                                "Could not write log - write(%s, %s, %d) failed:  %s\n",
                                 wfile->w_file, wbuf, reclen, strerror(errno));
                        return -1;
                  }
            }
    }

    return offset;
}

/*
 * Function to scan a logfile in reverse order.  Wfile is a valid
 * wlog_file structure initialized by wlog_open().  nrecs is the number
 * of records to scan (all records are scanned if nrecs is 0).  func is
 * a user-supplied function to call for each record found.  The function
 * will be passed a single parameter - a wlog_rec structure .
 */

int
wlog_scan_backward(wfile, nrecs, func, data)
struct wlog_file	*wfile;
int 			nrecs;
int 			(*func)();
long			data;
{
	int		fd, leftover, nbytes, offset, recnum, reclen, rval;
	char   		buf[BSIZE*32], *bufend, *cp, *bufstart;
	char		albuf[WLOG_REC_MAX_SIZE];
	struct wlog_rec	wrec;

	fd = wfile->w_rfd;

	/*
	 * Move to EOF.  offset will always hold the current file offset
	 */

        if ( (lseek(fd, 0, SEEK_END)) == -1 ) {
              sprintf(Wlog_Error_String,
                      "Could not reposition file pointer - lseek(%s, 0, SEEK_END) failed:  %s\n",
                       wfile->w_file, strerror(errno));
              return -1;
        }
	offset = lseek(fd, 0, SEEK_CUR);
        if ( (offset == -1) ) {
              sprintf(Wlog_Error_String,
                      "Could not reposition file pointer - lseek(%s, 0, SEEK_CUR) failed:  %s\n",
                       wfile->w_file, strerror(errno));
              return -1;
        }

	bufend = buf + sizeof(buf);
	bufstart = buf;

	recnum = 0;
	leftover = 0;
	while ((!nrecs || recnum < nrecs) && offset > 0) {
		/*
		 * Check for beginning of file - if there aren't enough bytes
		 * remaining to fill buf, adjust bufstart.
		 */

		if ((unsigned int)offset + leftover < sizeof(buf)) {
			bufstart = bufend - (offset + leftover);
			offset = 0;
		} else {
			offset -= sizeof(buf) - leftover;
		}

		/*
		 * Move to the proper file offset, and read into buf
		 */
                if ( (lseek(fd, offset, SEEK_SET)) ==-1  ) {
                      sprintf(Wlog_Error_String,
                              "Could not reposition file pointer - lseek(%s, %d, SEEK_SET) failed:  %s\n",
                               wfile->w_file, offset, strerror(errno));
                       return -1;
                }

		nbytes = read(fd, bufstart, bufend - bufstart - leftover);

		if (nbytes == -1) {
			sprintf(Wlog_Error_String,
				"Could not read history file at offset %d - read(%d, %p, %d) failed:  %s\n",
				offset, fd, bufstart,
				(int)(bufend - bufstart - leftover), strerror(errno));
			return -1;
		}

		cp = bufend;
		leftover = 0;

		while (cp >= bufstart) {

			/*
			 * If cp-bufstart is not large enough to hold a piece
			 * of record length information, copy remainder to end
			 * of buf and continue reading the file.
			 */

			if (cp - bufstart < 2) {
				leftover = cp - bufstart;
				memcpy(bufend - leftover, bufstart, leftover);
				break;
			}

			/*
			 * Extract the record length.  We must do it this way
			 * instead of casting cp to an int because cp might
			 * not be word aligned.
			 */

			reclen = (*(cp-2) * 256) + *(cp -1);

			/*
			 * If cp-bufstart isn't large enough to hold a
			 * complete record, plus the length information, copy
			 * the leftover bytes to the end of buf and continue
			 * reading.
			 */

			if (cp - bufstart < reclen + 2) {
				leftover = cp - bufstart;
				memcpy(bufend - leftover, bufstart, leftover);
				break;
			}

			/*
			 * Adjust cp to point at the start of the record.
			 * Copy the record into wbuf so that it is word
			 * aligned and pass the record to the user supplied
			 * function.
			 */

			cp -= reclen + 2;
			memcpy(albuf, cp, reclen);

			wlog_rec_unpack(&wrec, albuf);

			/*
			 * Call the user supplied function -
			 * stop if instructed to.
			 */

			if ((rval = (*func)(&wrec, data)) == WLOG_STOP_SCAN) {
				break;
			}

			recnum++;

			if (nrecs && recnum >= nrecs)
				break;
		}
	}

	return 0;
}

/*
 * The following 2 routines are used to pack and unpack the user
 * visible wlog_rec structure to/from a character buffer which is
 * stored or read from the write logfile.  Any changes to either of
 * these routines must be reflected in the other.
 */

static int
wlog_rec_pack(wrec, buf, flag)
struct wlog_rec	*wrec;
char		*buf;
int             flag;
{
	char			*file, *host, *pattern;
	struct wlog_rec_disk	*wrecd;

	wrecd = (struct wlog_rec_disk *)buf;

	wrecd->w_pid = (uint)wrec->w_pid;
	wrecd->w_offset = (uint)wrec->w_offset;
	wrecd->w_nbytes = (uint)wrec->w_nbytes;
	wrecd->w_oflags = (uint)wrec->w_oflags;
	wrecd->w_done = (uint)wrec->w_done;
	wrecd->w_async = (uint)wrec->w_async;

	wrecd->w_pathlen = (wrec->w_pathlen > 0) ? (uint)wrec->w_pathlen : 0;
	wrecd->w_hostlen = (wrec->w_hostlen > 0) ? (uint)wrec->w_hostlen : 0;
	wrecd->w_patternlen = (wrec->w_patternlen > 0) ? (uint)wrec->w_patternlen : 0;

	/*
	 * If flag is true, we should also pack the variable length parts
	 * of the wlog_rec.  By default, we only pack the fixed length
	 * parts.
	 */

	if (flag) {
		file = buf + sizeof(struct wlog_rec_disk);
		host = file + wrecd->w_pathlen;
		pattern = host + wrecd->w_hostlen;

		if (wrecd->w_pathlen > 0)
			memcpy(file, wrec->w_path, wrecd->w_pathlen);

		if (wrecd->w_hostlen > 0)
			memcpy(host, wrec->w_host, wrecd->w_hostlen);

		if (wrecd->w_patternlen > 0)
			memcpy(pattern, wrec->w_pattern, wrecd->w_patternlen);

		return (sizeof(struct wlog_rec_disk) +
			wrecd->w_pathlen + wrecd->w_hostlen + wrecd->w_patternlen);
	} else {
		return sizeof(struct wlog_rec_disk);
	}
}

static int
wlog_rec_unpack(wrec, buf)
struct wlog_rec	*wrec;
char		*buf;
{
	char			*file, *host, *pattern;
	struct wlog_rec_disk	*wrecd;

	memset((char *)wrec, 0x00, sizeof(struct wlog_rec));
	wrecd = (struct wlog_rec_disk *)buf;

	wrec->w_pid = wrecd->w_pid;
	wrec->w_offset = wrecd->w_offset;
	wrec->w_nbytes = wrecd->w_nbytes;
	wrec->w_oflags = wrecd->w_oflags;
	wrec->w_hostlen = wrecd->w_hostlen;
	wrec->w_pathlen = wrecd->w_pathlen;
	wrec->w_patternlen = wrecd->w_patternlen;
	wrec->w_done = wrecd->w_done;
	wrec->w_async = wrecd->w_async;

	if (wrec->w_pathlen > 0) {
		file = buf + sizeof(struct wlog_rec_disk);
		memcpy(wrec->w_path, file, wrec->w_pathlen);
	}

	if (wrec->w_hostlen > 0) {
		host = buf + sizeof(struct wlog_rec_disk) + wrec->w_pathlen;
		memcpy(wrec->w_host, host, wrec->w_hostlen);
	}

	if (wrec->w_patternlen > 0) {
		pattern = buf + sizeof(struct wlog_rec_disk) +
			wrec->w_pathlen + wrec->w_hostlen;
		memcpy(wrec->w_pattern, pattern, wrec->w_patternlen);
	}

	return 0;
}
