static char *SccsId = "@(#)main.c 3.13 (TU-Delft) 03/26/91";
/**********************************************************

Name/Version      : rmpr/3.13

Language          : C
Operating system  : UNIX SYSTEM V
Host machine      : HP9000

Author(s)         : P. van der Wolf
Creation date     : 04-Sep-1986
Modified by       : S. de Graaf
Modification date : 09-Feb-1987


        Delft University of Technology
        Department of Electrical Engineering
        Network Theory Section
        Mekelweg 4 - P.O.Box 5031
        2600 GA DELFT
        The Netherlands

        Phone : 015 - 786234

        COPYRIGHT (C) 1987 , All rights reserved
**********************************************************/
/* The rmpr (remove project) command should be used by the designer to
** remove an empty project (i.e. a project that contains no cells).
** It shows much resemblance with the UNIX rmdir command.
** If the directory is a project directory, as verified by dmOpenProject(),
** rmpr checks whether it contains no cells. If so, it removes
** the files .dmrc and projlist.
** It also removes the view directories with the files celllist and
** impcelllist.
** If this causes the UNIX directory to become empty, rmpr will
** also remove the project directory.
*/

#include "dmstd.h"
#include "signal.h"
#ifdef ESE
#include "eseOption.h"
#include "tversion.h"
#endif
/* the global definitions are included via dmInit.c */

#ifdef SYSV
#define rindex strrchr
#define index  strchr
#endif

#ifdef ESE
OptionSpec optionSpecs[] = {
    { "", NO, eseHelp, (void *) optionSpecs,
            "usage:     rmpr [options] project\nOptions (may be abbreviated) are:"},
    { "release", NO, esePrintString, (void *) TOOLVERSION,
            "    -release:              print the release number of this tool"},
    { "help", NO, eseHelp, (void *) optionSpecs,
            "    -help:                 print this list" },
    { "%help", NO, eseHelpAll, (void *) optionSpecs,
            "    -%help:                print this list" },
    { "%etext", NO, eseText, (void *) NULL,
            "    -%etext:               print the '(int) & etext' number" },
    { NULL, NULL, NULL, NULL, NULL, },
};
#endif


struct  stat st_buf;

#ifndef ESE
char *argv0 = "rmpr";	/* program name */
char *use_msg =		/* command line */
"\nUsage: %s project\n\n";
#else
char *argv0 = "rmpr";	/* program name */
char *use_msg =		/* command line */
"\nUsage: %s [options] project\n\n";
#endif

main (argc, argv)
int   argc;
char *argv[];
{
    DM_PROJECT * proj_key;
    char   *rindex ();
    char   *dir_path = NULL;
    char    proj_file[MAXLINE + 20];
    char    cmd[MAXLINE];
    int	    i;
    static char *view_str[] = {
	LAYOUT,
	CIRCUIT,
#ifndef ESE
	FLOORPLAN
#endif
    };

#ifdef ESE
    if (eseOptionHandler (argc, argv, optionSpecs, 1, & dir_path) > 0) {
        fprintf (stderr, use_msg, argv0); 
        exit (1);
    }

    if (!dir_path) {
        fprintf (stderr, use_msg, argv0);
        exit (1);
    }
    if (strlen (dir_path) >= MAXLINE) {
        fprintf (stderr, "%s: path name too long\n", argv0);
        exit (1);
    }
#else

    if (argc != 2) {
	fprintf (stderr, use_msg, argv0);
	exit (1);
    }

    if (strlen (argv[1]) >= MAXLINE) {
	fprintf (stderr, "%s: path name too long\n", argv0);
	die (1);
    }

    dir_path = argv[1];
#endif

    /* before dmOpenProject() first check if dir_path exists */
    /* and is a directory. We also check whether dir_path is   */
    /* writable (for locking/unlinking).		       */

    if (stat (dir_path, &st_buf) != 0) {
	fprintf (stderr, "%s: cannot access %s\n", argv0, dir_path);
	die (1);
    }

#ifdef DM_DEBUG
    IFDEBUG
	fprintf (stderr, "st_buf.st_mode = '%o'\n", st_buf.st_mode);
#endif /* DM_DEBUG */

    if (!(st_buf.st_mode & S_IFDIR)) {
	fprintf (stderr, "%s: %s is not a project directory\n",
						    argv0, dir_path);
	die (1);
    }
    if (!(st_buf.st_mode & S_IWRITE)) {
	fprintf (stderr, "%s: %s is not writable\n", argv0, dir_path);
	die (1);
    }

    /* Ignore signals. */
#ifndef MSDOS
    signal (SIGHUP, SIG_IGN);
    signal (SIGQUIT, SIG_IGN);
    signal (SIGTERM, SIG_IGN);
#endif
    signal (SIGINT, SIG_IGN);

    /* now initialize and open project: .dmrc will be read
    ** and a lock will be set
    */
    dmInit (argv0);
    proj_key = dmOpenProject (dir_path, PROJ_WRITE);

    /* dmOpenProject succeeded, so the directory is a project.
    ** See if the different celllists are empty.
    */
    for (i = 0; i < sizeof (view_str)/sizeof (char *); i++) {
	_dmSprintf (proj_file, "%s/%s/celllist", dir_path, view_str[i]);

	if (stat (proj_file, &st_buf) != 0) {
	    fprintf (stderr, "%s: cannot access %s\n", argv0, proj_file);
	    die (1);
	}
	if (st_buf.st_size != 0) {
	    fprintf (stderr,
		"%s: celllist of view %s of project %s is not empty\n",
						argv0, view_str[i], dir_path);
	    fprintf (stderr, "%s can only remove empty projects\n", argv0);
	    die (1);
	}
    }

    /* The celllists are empty. Now remove .dmrc and projlist,
    ** thereby turning the project directory into an ordinary directory.
    ** Then try to remove the celllists, impcelllists
    ** and the view directories.
    */
    /* .dmrc was already found by dmOpenProject() */
#ifdef MSDOS
    _dmSprintf (proj_file, "%s/dmrc.dot", dir_path);
#else
    _dmSprintf (proj_file, "%s/.dmrc", dir_path);
#endif
    if (unlink (proj_file) == -1) {
	fprintf (stderr, "%s: cannot unlink %s\n", argv0, proj_file);
	die (1);
    }
    _dmSprintf (proj_file, "%s/projlist", dir_path);
    if (unlink (proj_file) == -1) {
	fprintf (stderr, "%s: cannot unlink %s\n", argv0, proj_file);
	die (1);
    }

    for (i = 0; i < sizeof (view_str)/sizeof (char *); i++) {
	_dmSprintf (proj_file, "%s/%s/celllist", dir_path, view_str[i]);

	if (unlink (proj_file) == -1) {
	    fprintf (stderr, "%s: cannot unlink %s\n", argv0, proj_file);
	    die (1);
	}
#ifdef MSDOS
	_dmSprintf (proj_file, "%s/%s/impclist", dir_path, view_str[i]);
#else
	_dmSprintf (proj_file, "%s/%s/impcelllist", dir_path, view_str[i]);
#endif
	if (unlink (proj_file) == -1) {
	    fprintf (stderr, "%s: cannot unlink %s\n", argv0, proj_file);
	    die (1);
	}

	_dmSprintf (proj_file, "%s/%s", dir_path, view_str[i]);
	if (rmdir (proj_file) == -1) {
	    fprintf (stderr,
		"%s: cannot remove directory %s, contains non-project files\n",
		argv0, proj_file);
	    die (1);
	}
    }

    /* Now the project directory might be empty. Try to remove it
    ** by an rmdir. If this not succeeds the directory is probably
    ** not empty (we already know dir_path is a legal directory).
    ** No further actions have to be taken in this case.
    */

    dmCloseProject (proj_key, QUIT);		/* first remove lock */

/*
    _dmSprintf (cmd, "rmdir %s 2> /dev/null", dir_path);
#ifdef DM_DEBUG
    IFDEBUG
	fprintf (stderr, "system command: %s\n", cmd);
#endif DM_DEBUG
    system (cmd);
*/

    if (rmdir (dir_path) == -1) {
	fprintf (stderr,
	    "%s: directory %s not removed, contains non-project files\n",
	    argv0, dir_path);
    }

    die (0);
}

dmError (s)
char *s;
{
    fprintf (stderr, "%s: ", argv0);
    dmPerror (s);
    fprintf (stderr,
	"%s: error in ddm interface function\n", argv0);
    die (1);
}

die (status)
int  status;
{
    if (status)
	fprintf (stderr, "%s: -- program aborted --\n", argv0);
#ifndef ESE
    else
	fprintf (stderr, "%s: -- program finished --\n", argv0);
#endif /* ESE */
    dmQuit ();
    exit (status);
}
