static char *SccsId = "@(#)dmopproj.c 3.29 (TU-Delft) 04/28/93";
/**********************************************************

Name/Version      : The Design Data Management Project

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

Author(s)         : S. de Graaf
                    T.G.R. van Leuken
                    N. van der Meijs
		    P. van der Wolf
Creation date     : 04-Dec-1986
Modified by       : S. de Graaf
Modification date : 08-Jan-1988


        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) 1985-1988 , All rights reserved
**********************************************************/
#include "dmstd.h"

#define MAXPATHLEN 1024

#define HOSTLEN 128
char    dmnethost[MAXPATHLEN + 2] = "/";
int     dmhostnameprefix = 0;
static int  hostlen = 0;

#ifdef hpux
#define rindex strrchr
#endif

/* The file .dmrc contains, among other things, a software release number. */
/* This number is set by mkpr. dmOpenProject now has to verify whether   */
/* the tool operates on a valid (i.e. compatible) database.		   */
#define	RELEASE_NUM	3	/* number of software release; see also
				   mkpr */
extern int  dmInit_flag;
extern char *dmToolname;

DM_PROJECT * dmOpenProject (projectname, mode)
char   *projectname;
int mode;
{
    DM_PROJECT * dmproject;
    char   *dmfile;
    FILE * fp;
    char    dmpath[MAXPATHLEN];
    char    path[MAXPATHLEN];
    int     this_rel;
    int     view_entry;
    char   *rindex ();
    static char *cwd;
    static char wdpath[MAXPATHLEN];
    char   *getcwd ();
    char   *getenv ();
    char   *o_mode;
    register char  *cp;
    int     i;

    if (dmInit_flag == 0) {
	dmerrno = DME_NOINIT;
	dmError ("dmOpenProject");
	return (NULL);
    }
    strcpy (dmpath, projectname);
#ifdef MSDOS
    for (i = 0; dmpath[i] != '\0'; i++) {
	if (dmpath[i] == '\\')
	    dmpath[i] = '/';
    }
#endif

    if (hostlen == 0) {
#ifdef MSDOS
	getdevname (dmnethost);
#else
	gethostname (&dmnethost[strlen (dmnethost)], HOSTLEN);
#endif
	hostlen = strlen (dmnethost);
    }

    if (!cwd) {
	if (!(cwd = getenv ("CWD"))) {
	    if (!(cwd = getcwd (wdpath, MAXPATHLEN)))
		goto fail_sys;
	}
    }
    strcpy (wdpath, cwd);
#ifdef MSDOS
    for (i = 0; wdpath[i] != '\0'; i++) {
	if (wdpath[i] == '\\')
	    wdpath[i] = '/';
    }
#endif

#ifndef MSDOS
    CheckPrefix (wdpath, dmnethost);
    CheckPrefix (dmpath, dmnethost);
#endif

    if (*dmpath == '.') {	/* relative path */
	_dmSprintf (path, "%s/%s", wdpath, dmpath);
	strcpy (dmpath, path);
    }

    if (_dmcorrect_path (dmpath))
	goto fail_badpr;

    if ((dmproject = _dmCh_proj (dmpath)) != NULL) {
	dmerrno = DME_PRLOCK;
	return (dmproject);
    }
    else
	dmerrno = 0;

    if ((dmproject = _dmMk_projectkey ()) == NULL)
	return (NULL);

    if (mode == PROJ_WRITE)
	o_mode = "r+";
    else
	o_mode = "r";

    dmproject -> netpath = cp = _dmStrSave (dmpath);
#ifdef MSDOS
    _dmSprintf (path, "%s/dmrc.dot", cp);
#else
    _dmSprintf (path, "%s/.dmrc", cp);
#endif

    if (dmhostnameprefix && strncmp (path, dmnethost, hostlen) == 0) {
	dmproject -> dmpath = cp + hostlen;
	dmfile = path + hostlen;
    }
    else {
	dmproject -> dmpath = cp;
	dmfile = path;
    }
    if (!(fp = fopen (dmfile, o_mode))) {
	dmerrno = DME_NODMRC;	/* cannot open file .dmrc */
	goto fail;
    }

    cp = rindex (dmproject -> dmpath, '/');
    if (cp == NULL)
	dmproject -> projectid = dmproject -> dmpath;
    else
	dmproject -> projectid = cp + 1;
    dmproject -> mode = mode;

    for (view_entry = 0; view_entry < DM_NOVIEWS; view_entry++) {
	dmproject -> celllist[view_entry] = NULL;
	dmproject -> impcelllist[view_entry] = NULL;
    }
    dmproject -> maskdata = NULL;
 /* store toolname in project key. In the future this */
 /* might already have been put in an Init-Key (PvdW) */
    dmproject -> toolname = dmToolname;

    if (fscanf (fp, "%d", &this_rel) != 1
#ifdef PACK
	    || fgetc (fp) != '\n'
#else				/* UnPACKed */
	    || fgetc (fp) != 'U'
#endif				/* PACK */
	    || fscanf (fp, "%d", &dmproject -> procid) != 1
	    || fscanf (fp, "%lf", &dmproject -> lambda) != 1
	    || fscanf (fp, "%d", &dmproject -> n_samples) != 1) {

	fclose (fp);
	dmerrno = DME_FMT;
	dmError (dmfile);
	goto fail2;
    }

    fclose (fp);

 /* now check the release number */
    if (this_rel != RELEASE_NUM) {
	dmerrno = DME_BADREL;
	dmError (dmfile);
	goto fail2;
    }

#ifdef PRLOCK
 /* directory is a valid project; if mode is write lock it */
    if (mode == PROJ_WRITE && _dmLockProject (dmproject -> dmpath)) {
	goto fail2;
    }
#endif				/* PRLOCK */

    return (dmproject);

fail: 
    dmError (dmproject -> dmpath);
fail2: 
    _dmRm_projectkey (dmproject);
    return (NULL);
fail_sys: 
    dmerrno = DME_SYS;
    dmError ("dmOpenProject");
    return (NULL);
fail_badpr: 
    dmerrno = DME_BADPR;
    dmError (dmpath);
    return (NULL);
}

/*
** _dmcorrect_path() corrects its argument by removing
** the parts "//" and "/./" and "/../" from it
** and the trailing parts "/" and "/." and "/.." from it.
**
** examples:   /a///b   ->  /a/b
**             /a/./b   ->  /a/b
**             /a/../b  ->  /b
**             /a///    ->  /a
**             /a/.     ->  /a
**             /a/..    ->  /
*/
_dmcorrect_path (dmpath)
char   *dmpath;
{
    char    scratch_str[MAXPATHLEN];
    register char  *read_p;
    register char  *write_p;

#ifdef MSDOS
/* dmpath starts with D:/dir */
    read_p = dmpath;
    write_p = scratch_str;
    if (dmpath[1] == ':') {
	scratch_str[0] = dmpath[0];
	scratch_str[1] = dmpath[1];
	read_p += 2;
	write_p += 2;
    }
    *write_p = '/';
#else
    if (*dmpath != '/')		/* absolute path required */
	return (-1);

    read_p = dmpath;
    write_p = scratch_str;
    *write_p = '/';
#endif

    if (strncmp (read_p, "//", 2) == 0) {
	read_p += 1;
	write_p += 1;
	*write_p = '/';
    }

    while (1) {
	if (strncmp (read_p, "//", 2) == 0)
	    read_p += 1;
	else
	    if (strncmp (read_p, "/./", 3) == 0)
		read_p += 2;
	    else
		if (strncmp (read_p, "/../", 4) == 0) {
		    if (write_p == scratch_str)/* illegal path */
			return (-1);
		    while (*(--write_p) != '/');
		    read_p += 3;
		}
		else {
		    do {
			read_p++;
			write_p++;
			*write_p = *read_p;
			if (*read_p == '\0') {
			    if (strncmp (read_p - 1, "/", 1) == 0) {
				write_p -= 1;
				if (write_p != scratch_str)
				    *write_p = '\0';
			    }
			    else
				if (strncmp (read_p - 2, "/.", 2) == 0) {
				    write_p -= 2;
				    if (write_p == scratch_str)
					++write_p;
				    *write_p = '\0';
				}
				else
				    if (strncmp (read_p - 3, "/..", 3) == 0) {
					write_p -= 3;
					if (write_p == scratch_str)
				/* illegal path */
					    return (-1);
					while (*(--write_p) != '/');
					if (write_p == scratch_str)
					    ++write_p;
					*write_p = '\0';
				    }

			    strcpy (dmpath, scratch_str);
			    return (0);
			}
		    } while (*read_p != '/');
		}
    }
}

CheckPrefix (path, host)
char   *path,
       *host;
{
    char    prefix[MAXPATHLEN];
    int     i = 0;
    int     j = 0;

    if (path[0] != '/')
	return (0);
    while (path[j] == '/') {
	j++;
    }
    while (path[i] != '\0') {
	if ((prefix[i] = path[i + j]) == '/')
	    break;
	i++;
    }
    prefix[i] = '\0';
    if (IsHostname (prefix))
	return (1);		/* legal hostname */
    if (dmhostnameprefix) {
	sprintf (prefix, "%s%s", host, path);
	strcpy (path, prefix);
    }
    return (1);
}

IsHostname (s)
char   *s;
{
    FILE * fp;
    char    buf[MAXPATHLEN];
    char    name[MAXPATHLEN];
    int     i;
    fp = fopen ("/etc/hosts", "r");
    if (fp == 0)
	return (0);
    while (fgets (buf, MAXPATHLEN, fp) != 0) {
	if (buf[0] == '#')
	    continue;
	sscanf (buf, "%*s%s", name);
	if (strcmp (name, s) == 0) {
	    fclose (fp);
	    return (1);
	}
    }
    fclose (fp);
    return (0);
}

#ifdef MSDOS
getdevname (dmnethost)
char   *dmnethost;
{
    char   *wd;
    char   *getcwd ();
    char    path[MAXPATHLEN];

    wd = getcwd (path, MAXPATHLEN);
    strcpy (path, wd);
    strncpy (dmnethost, path, 2);
}
#endif
