/*
 *	C4 -- CVS like front end to the Perforce p4 SCM tool.
 *
 * Copyright (c) 1998 - 2000, Neil Russell.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Neil Russell.
 * 4. The name Neil Russell may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY NEIL RUSSELL ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL NEIL RUSSELL BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *	Global declarations and definitions.
 */

#include	<stdio.h>
#include	<unistd.h>
#include	<fcntl.h>
#include	<stdlib.h>
#include	<stdarg.h>
#include	<string.h>
#include	<stdio.h>
#include	<dirent.h>
#include	<sys/param.h>
#include	<sys/types.h>
#include	<sys/stat.h>

/**************************************************/

#define C4TAG		".c4"
#define C4IGNORE	".c4ignore"

/**************************************************/

typedef struct Ignore	Ignore;
struct Ignore
{
	char *		spec;
	Ignore *	next;
};

typedef struct File	File;
struct File
{
	int		flag;		/* File flags */
	char *		name;		/* File name component */

	long		modtime;	/* Depot mod time */
#if 0
	long		change;		/* Change number */
#endif

	Ignore *	ignore;		/* Ignore list for directory */

	File *		children;	/* Directory contents */
	File *		next;		/* Next in this directory */
};

/* Depot flags */
#define F_DEPOT		0x000001	/* Depot has a copy */
#define F_HAVE		0x000002	/* Client (should) have a copy */
#define F_GET		0x000004	/* Client needs a p4 get */
#define F_SYMLINK	0x000008	/* Entry is a symbolic link */
#define F_OPEN		0x000010	/* File is open in this client */
#define F_DELETE	0x000020	/* File is opened for delete */

/* File scan flags */
#define F_SDIR		0x000040	/* Scanned as a directory */
#define F_DIFF0		0x000080	/* Do a diff on a closed file */
#define F_DIFF1		0x000100	/* Do a diff on an open file */
#define F_EXISTS	0x000200	/* File exists in client */
#define F_ERROR		0x000400	/* Error on this file */

/* Diff flags */
#define F_MODIFIED	0x000800	/* File and depot are different */

/* what to do about it */
#define F_EDIT		0x001000	/* Do a "p4 edit" on this file */
#define F_REVERT	0x002000	/* Do a "p4 revert" on this file */
#define F_REFRESH	0x004000	/* Do a "p4 refresh" on this file */
#define F_ADD		0x008000	/* Do a "p4 add" on this file */
#define F_REMOVE	0x010000	/* Do a "p4 delete" on this file */
#define F_ADDMAYBE	0x020000	/* Reported as an add condidate */

/* Miscelaneous */
#define F_IGNORELIST	0x040000	/* Ignore list read for directory */

/**************************************************/

/******** command.c ********/
extern int	CmdArgs;		/* Number of args seen */
extern int	CmdExec;		/* '-n' command line option */
extern char *	CmdP4;			/* Name of the real p4 command */
extern void	Command(char *, void (*)(char *), int clobber);
extern void	CommandDone(void);
extern void	CommandArg(char *);

/******** commit.c ********/
extern void	Commit(char ** argv);

/******** findroot.c ********/
extern void	FindRoot(void);

/******** fstat.c ********/
extern void	DoFstat(void);

/******** glob.c ********/
extern int	Glob(char * spec, char * name);

/******** ignore.c ********/
extern void	IgnoreSpec(Ignore ** list, char * spec);
extern int	IsIgnored(char * dir, File * dp, char * name);

/******** info.c ********/
extern char	ClientPath[];
extern int	ClientPathLen;
extern char	CurDir[];
extern int	CurDirLen;
extern int	UseDiffSC;
extern void	GetClientPath(void);

/******** lookup.c ********/
extern File *	Lookup(char * name, int create);
extern void	PrintTree(char * msg);

/******** main.c ********/
extern void	Error(int, char *, ...);
extern void *	Alloc(unsigned);
extern void *	ReAlloc(void *, unsigned);

/******** mkws.c ********/
extern void	MakeWorkspace(char ** argv);

/******** scan.c ********/
extern int	CmdVerbose;		/* '-v' command line option */
extern int	SupressIgnore;
extern int	Debug;
extern void	Scan(char ** argv);
