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

Name/Version      : The Design Data Management Project

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

Author(s)         : S. de Graaf
                    A. van der Hoeven
                    T.G.R. van Leuken
                    N. van der Meijs
		    T. Vogel
		    P. van der Wolf
Creation date     : 04-Dec-1986
Modified by       : S. de Graaf
Modification date : 21-Jan-1988
Modification date : 08-Apr-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"

/*
** This function opens the file and returns a file pointer
** to the file, as indicated in the key argument.
** NULL is returned when the request can not be granted.
*/
DM_STREAM * dmOpenStream (key, stream, mode)
DM_CELL * key;
char   *stream,
       *mode;
{
    char    path[MAXLINE];
    char   *view;
    int     is_info2;
    int     is_info3;
    char   *file;
    DM_STREAM * dmfile;

#ifdef DM_DEBUG
    IFDEBUG
	fprintf (stderr, "keyno: %d, stream: %s, mode: %s\n",
	    key -> keyno, stream, mode);
#endif /* DM_DEBUG */

    if (_dmCh_key (key) != 0) {
	dmError2 ("dmOpenStream: stream", stream);
	return (NULL);
    }

    is_info2 = 0;
    is_info3 = 0;
    if (strcmp (stream, "info2") == 0) {
	++is_info2;
	file = "info";
    }
    else if (strcmp (stream, "info3") == 0) {
	++is_info3;
	file = "info";
    }
    else {
	file = stream;	/* direct mapping of stream to file */
    }

    view = key -> view;

    if (mode[0] == 'w' || mode[0] == 'a' || mode[1] == '+') {
	if (is_info2 || is_info3) {
	    mode =  "r+";
	}
	if (key -> mode == READONLY) {
	    dmerrno = DME_MODE;		/* invalid mode for key */
	    dmError2 ("dmOpenStream", mode);
	    return (NULL);
	}
    }

    _dmSprintf (path, "%s/%s/%s/%s", key -> dmproject -> dmpath,
		    view, key -> cell, file);

    dmfile = _dmMk_streamkey ();
    dmfile -> dmfp = fopen (path, mode);
    dmfile -> dmkey = key;
    dmfile -> stream = _dmStrSave (stream);
    dmfile -> mode = _dmStrSave (mode);

#ifdef DM_DEBUG
    IFDEBUG
	fprintf (stderr, "path: %s, fildes: %d\n",
	    path, (dmfile -> dmfp ? fileno (dmfile -> dmfp) : -1));
#endif /* DM_DEBUG */

    /* the stream has not been opened properly. Inform desman of failure;
     * It might recover this failure so that we can try again. 
     */
    if (dmfile -> dmfp == NULL) {
	if (_dmFailOSToDesMan (dmfile) == 0) {
	    /* desman successful :  try again */
	    dmfile -> dmfp = fopen (path, mode);
	}
    }
    if (dmfile -> dmfp == NULL) {
	dmerrno = DME_FOPEN;
	dmError2 ("dmOpenStream", stream);
	goto fail;
    }
    else if (is_info3) {
	fseek (dmfile -> dmfp, 195L, 0);/* 3 x (4 x 16 + 1) */
    }
    else if (is_info2) {
	fseek (dmfile -> dmfp, 276L, 0);
	/* 3 x (4 x 16 + 1) + 5 x 16 + 1 */
    }

    /* inform the design manager of the successful openstream action */
    if (_dmOSToDesMan (dmfile) < 0) {
	/* It does not agree. */
	dmError2 ("dmOpenStream", stream);
	goto fail;
    }

    return (dmfile);
fail:
    _dmRm_streamkey (dmfile);
    return (NULL);
}
