#!/usr/local/bin/icmake -qi

#define HUNGRY          1
#define ONEDEV		1

#define FINDARGS        "-printf \"%p CT:%c MT:%t IN:%i SZ:%k LN:%l\\n\""
#define VER             "1.01"
#define RM              "rm -f"

string maketemp (string mat)
{
    return ("/tmp/" + mat + "." + (string) getpid ());
}    

string makegrep (string file)
{
    string
        line,
	ret;
    list
        input,
	stripped;
     int
        i;
	
    while (input = fgets (file, (int) element (1, input)))
    {
        stripped = strtok (element (0, input), "#\n");
        line = element (0, stripped);
        if (line && element (0, line) != "#")
	{
	    if (ret)
	        ret += "|";
	    ret += "^" + line;
	}
    }
    
    return (ret);
}    

void main (int argc, list argv)
{
    string
        startdir,
	startdirfile,
	excludefile,
	listfile,
	oldlistfile,
	stampfile,
	grepcmd,
	allfiles;
    list
        finfo;
    string
	onedev;
	
    echo (0);

    if (argc != 4 && argc != 6)
    {
        printf ("\n"
	        "ICCE Backup Filelist Builder V" VER "\n"
		"Copyright (c) ICCE 1994. All rights reserved.\n"
		"\n"
		"buildlist by Karel Kubat.\n"
		"\n"
                "Usage: buildlist startdirfile excludefile listfile "
		                               "[stampfile oldlistfile]\n"
		"where:\n"
		"       startdirfile : file holding directory to start scanning\n"
		"       excludefile  : file holding directories to exclude\n"
		"       listfile     : file to receive listing of these files\n"
		"       stampfile    : (optional) stamp of last run\n"
		"       oldlistfile  : (optional) list of last full run\n"
		"\n"
                "A list of files to backup is built, the files are at and "
		                                "under the\n"
                "directory whose name is contained in the startdirfile.\n"
                "The output is sent to listfile. Only the directories which "
		                                "do not appear\n"
                "in the excludefile are scanned.\n"
                "If oldlistfile and stampfile are present, only files"
		                                " younger than the stamp\n"
		"or not in oldlist are taken.\n"
                "\n");
        exit (1);
    }
    
    startdirfile = element (1, argv);
    finfo = fgets (startdirfile, 0);
    startdir = element (0, strtok (element (0, finfo), " \t\n"));
    
    if (! startdir)
    {
        printf ("buildlist: no startdir to be found in the file ", 
	        startdirfile, "\n");
        exit (1);		
    }
    
    excludefile = element (2, argv);
    listfile = element (3, argv);
    if (argc == 6)
    {
        stampfile   = element (4, argv);
	oldlistfile = element (5, argv);
    }
	       
    grepcmd = makegrep (excludefile);
     
    printf ("Building list of files.. have patience..\n");

    if (ONEDEV)
	onedev = "-xdev";

    if (stampfile)
    {
        if (HUNGRY)
	{
	    printf ("    (list of all files on disk)\n");
	    allfiles = maketemp ("allfiles");
            exec ("find", startdir, FINDARGS, onedev,
                  "| egrep -v", "'" + grepcmd + "'", 
	          "|", "sort",
	          ">", allfiles);
		  
	    printf ("    (files not on full backup)\n");
	    exec ("diff", allfiles, oldlistfile, 
	          "|", "egrep", "'< '",
		  "|", "sed", "'s/< //g'",
		  "|", "sort",
		  ">", listfile);
		  
	    exec (RM, allfiles);
	}
	else
	{
            exec ("find", startdir, "-newer", stampfile, FINDARGS, onedev,
              "| egrep -v", "'" + grepcmd + "'", 
	      "|", "sort",
	      ">", listfile);
	}
    }
    else
    {
        exec ("find", startdir, FINDARGS, onedev,
              "| egrep -v", "'" + grepcmd + "'", 
	      "|", "sort", 
	      ">", listfile);
    }
    
    printf ("List of files built.\n");    	      

    exit (0);
}
