Ejemplo n.º 1
0
static STATUS
gcn_nq_fopen( char *name, char *mode, FILE **file )
{
    LOCATION	loc;
    STATUS	status;

#ifndef hp9_mpe
    if ( ( status = NMloc( ADMIN, PATH, (char *)NULL, &loc ) ) != OK )
        goto error;

    LOfaddpath( &loc, "name", &loc );
    LOfstfile( name, &loc );
#else
    if ( (status = NMloc( FILES, FILENAME, name, &loc )) != OK )
        goto error;
#endif

    if ( ! STcompare( mode, "r" )  &&  (status = LOexist( &loc )) != OK )
        goto error;

#ifdef VMS
    status = SIfopen( &loc, mode, SI_RACC, sizeof(GCN_DB_RECORD), file );

    if (status == E_CL1904_SI_CANT_OPEN && ( LOexist( &loc ) == OK ) )
        status = SIfopen( &loc, mode, GCN_RACC_FILE, sizeof (GCN_DB_RECORD),
                          file );
#else
    status = SIfopen( &loc, mode, SI_RACC, sizeof (GCN_DB_RECORD), file );
#endif

error:

    if ( status != OK )  *file = NULL;
    return( status );
}
Ejemplo n.º 2
0
/******************************************************************************
** Name: MEsmdestroy()	- Destroy a shared memory segment
**
** Description:
**	Remove the shared memory segment specified by shared memory identifier
**	"key" from the system and destroy any system data structure associated
**	with it.
**
**	Note: The shared memory pages are not necessarily removed from
**	processes which have the segment mapped.  It is up to the clients to
**	detach the segment via MEfree_pages prior to destroying it.
**
**	Protection Note: The caller of this routine must have protection to
**	destroy the shared memory segment.  Protections are enforced by the
**	underlying Operating System.  In general, this routine can only be
**	guaranteed to work when executed by a user running with the same
**	effective privledges as the user who created the shared memory segment.
**
** Inputs:
**	user_key			identifier which was previosly
**				      used in a successful MEget_pages() call
**				      (not necessarily a call in this process)
**
** Outputs:
**	err_code 		System specific error information.
**
**	Returns:
**	    OK
**	    ME_NO_PERM		    No permission to destroy shared memory
**				            segment.
**	    ME_NO_SUCH_SEGMENT	indicated shared memory segment does not
**				            exist.
**	    ME_NO_SHARED	    No shared memory in this CL.
**	    ME_BAD_ADVICE	    call was made during ME_USER_ALLOC
**
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
******************************************************************************/
STATUS
MEsmdestroy(char        *user_key,
            CL_ERR_DESC *err_code)
{
	LOCATION        location;
	LOCATION        temp_loc;
	char            loc_buf[MAX_LOC + 1];
	STATUS          ret_val = OK;

	CLEAR_ERR(err_code);

	/*
	 * Get location of ME files for shared memory segments.
	 */

# ifdef MCT
	gen_Psem(&NM_loc_sem);
# endif /* MCT */
	ret_val = NMloc(FILES,
	                PATH,
	                (char *) NULL,
	                &temp_loc);
	if (!ret_val)
	{
		LOcopy(&temp_loc,
		       loc_buf,
		       &location);
		LOfaddpath(&location,
		           ME_SHMEM_DIR,
		           &location);
		LOfstfile(user_key,
		          &location);

		if (LOexist(&location) != OK)
			ret_val = FAIL;
		else {
			ret_val = LOdelete(&location);
			switch (ret_val) {
			case OK:
			case ME_NO_PERM:
				break;;

			default:
				ret_val = ME_NO_SUCH_SEGMENT;
				break;;
			}
		}
	}
# ifdef MCT
	gen_Vsem(&NM_loc_sem);
# endif /* MCT */
	return (ret_val);
}
Ejemplo n.º 3
0
/*
** Name: gipImportInstXML()
**
** Description:
**
**	Import generated XML doc containing save set and instance info.
**
** History:
**	05-Sep-2007 (hanje04)
**	    Created.
**	
*/
STATUS
gipImportPkgInfo( LOCATION *xmlfileloc, UGMODE *state, i4 *count )
{
    char	*xmlfilestr = NULL;
    xmlDocPtr	doc;
    xmlNodePtr	cur;

    /* sanity check */
    if ( LOexist( xmlfileloc ) != OK )
	return( FAIL );

    /* get location string */
    LOtos( xmlfileloc, &xmlfilestr );

    /* load instance/saveset document */
    doc = xmlParseFile( xmlfilestr );
    if ( doc == NULL )
	return( FAIL );

    /* load first element */
    cur = xmlDocGetRootElement( doc );

    /* basic validation */
    /* FIX ME, NEED DTD!!! */
    if ( cur == NULL ||
	    xmlStrcmp( cur->name, (const xmlChar *) "IngresPackageInfo" ) )
    {
	xmlFreeDoc( doc );
	return( FAIL );
    }

    /* walk the tree */
    cur = cur->xmlChildrenNode;
    while ( cur != NULL )
    {
	if ( ! xmlStrcmp( cur->name, (const xmlChar *)"saveset" ) )
	    gipParseSaveSet( doc, cur );
	else if ( ! xmlStrcmp( cur->name, (const xmlChar *)"instances" ) )
	    gipParseInstances( doc, cur, state, count );

	cur = cur->next;
    }

    xmlFreeDoc( doc );
    return( OK );
}
Ejemplo n.º 4
0
STATUS
xfsetdirs(char *dir, char *frompath, char *intopath)
{
    auto i2	dirflag;
    auto char 	*s;
    char	*locbuf;
    STATUS	status;

    locbuf = XF_REQMEM(MAX_LOC + 1, FALSE);

    if (dir == NULL || *dir == EOS)	
    {
	/* Default to current directory. */
	status = LOgt(locbuf, &Xf_dir);
        if(status != OK)
        {
#ifdef UNIX                 
            status = LOfakepwd(locbuf, &Xf_dir);
#endif
            if(status != OK)
            {
                IIUGerr(E_XF0061_Can_Not_Determine_Dir, UG_ERR_ERROR, 0);
                return(FAIL);
            }
        }
	dir = NULL;
    }
    else
    {
	STlcopy(dir, locbuf, MAX_LOC);
	if (LOfroms(PATH, locbuf, &Xf_dir) != OK)
	{
	    IIUGerr(E_XF0006_Invalid_directory_pat, UG_ERR_ERROR, 1, dir);
	    return (FAIL);
	}

	if (!LOisfull(&Xf_dir))
	{
	    auto LOCATION	xloc;
	    char		xbuf[MAX_LOC + 1];

	    /* 
	    ** path spec. is a relative specification -- we must expand it 
	    ** to a full pathname. 
	    */
	    LOcopy(&Xf_dir, xbuf, &xloc);
	    status = LOgt(locbuf, &Xf_dir);
            if(status != OK)
            {
                IIUGerr(E_XF0061_Can_Not_Determine_Dir, UG_ERR_ERROR, 0);
                return(FAIL);
            }
	    LOaddpath(&Xf_dir, &xloc, &Xf_dir);
	}

	/* LOisdir and LOexist are archaic and should be replaced by LOinfo. */
	LOisdir(&Xf_dir, &dirflag);
	if (dirflag != ISDIR || LOexist(&Xf_dir) != OK)
	{
	    IIUGerr(E_XF0006_Invalid_directory_pat, UG_ERR_ERROR, 1, dir);
	    return (FAIL);
	}
    }
    LOtos(&Xf_dir, &s);

    /* the COPY FROM path doesn't have to exist. */
    if (frompath != NULL && *frompath != EOS)
	Xf_from_path = saveloc(frompath);

    /* the COPY INTO path doesn't have to exist. */
    if (intopath != NULL && *intopath != EOS)
	Xf_into_path = saveloc(intopath);

    IIUGmsg(ERget(S_XF0064_Unload_Directory_is), FALSE, 1, 
		(PTR)(Xf_into_path == NULL ? s : Xf_into_path));
    IIUGmsg(ERget(S_XF0065_Reload_Directory_is), FALSE, 1, 
		(PTR)(Xf_from_path == NULL ? s : Xf_from_path));

    return (OK);
}
Ejemplo n.º 5
0
/*
** pp_open() -- open a file for reading.  The use of the include path list
**      is used to resolve files that may not be in the current default
**      location.  
*/
static STATUS
pp_open( FILE **input, char *filepath, bool def_dir )
{
	LOCATION loc;
	LOCATION loctest;
	char buf[ MAX_LOC + 1 ];
	char bufdev[ MAX_LOC + 1 ];
	char bufpath[ MAX_LOC + 1 ];
	char bufsave[ MAX_LOC + 1 ];
	char buftest[ MAX_LOC + 1 ];
	STATUS sts;
	IPATH *ipath;
	bool found = FALSE;
	bool file_has_path, dir_has_path;

	/* 
	** Check to see if we should first look in the default directory,
	** this directory will be the first entry in the Include list.
	*/
	if (def_dir == TRUE) 
		ipath = &ihead;
	else
		ipath = ihead.next;

	/* Convert the filename to open to a LOCATION */
	STcopy(filepath, bufsave);
	if (OK != (sts = LOfroms( PATH & FILENAME, bufsave, &loc )) )
		return (sts);

	/*
	** Search for the file in each directory in the include list.
	** No expansion possible if there are no include directories.
	*/
	while (ipath != NULL && found == FALSE) 
	{
		/* Initialize loctest so LOaddpath will work */
		LOcopy(&loc, buftest, &loctest);
			
		/* Is there a device (VMS) and/or a path for the directory? */
		STcopy(ERx(""), bufdev);
		STcopy(ERx(""), bufpath);
		sts = LOdetail(ipath->pathloc, bufdev, bufpath, buf, buf, buf);
		if (sts != OK)
			break;
		if (STlength(bufdev) + STlength(bufpath) > 0 )
			dir_has_path = TRUE;
		else
			dir_has_path = FALSE;

		/* Don't mess with the filename if it was an absolute path */
		/* or if this include directory path is empty */
		if (LOisfull(&loctest) == FALSE && dir_has_path == TRUE )
		{
			/* Is there a path for the file? */
			sts = LOdetail(&loctest, 
				buf, bufpath, buf, buf, buf);
			if (sts != OK)
				break;
			file_has_path = (STlength(bufpath) > 0 ? TRUE : FALSE);

			/*
			** If there's no path component then copy in the 
			** next prefix, else append it.
			** If LOaddpath succeeds, the result will also have 
			** the original filename.  If it fails then drop out.
			** LOaddpath can fail if loctest is an absolute path,
			** but we already checked for that.
			*/
			if ( file_has_path )
			{
				sts =LOaddpath(ipath->pathloc, &loc, &loctest);
			}
			else
			{
				LOcopy(ipath->pathloc, buftest, &loctest);

				/*
				** If we can't set the filename from loc, 
				** then something is wrong, and will continue 
				** to be wrong.  Get out of the loop.
				*/
				sts = LOstfile(&loc, &loctest);
			}
		}

		/*
		** If all of the filename manipulations have succeeded
		** then check for the file's existance.  
		*/
		if (sts == OK && LOexist(&loctest) == OK) {
			found = TRUE;
			LOcopy(&loctest, buf, &loc);
		}

		/* Prepare for the next path in the include list */
		ipath = ipath->next;
	}

	/* 
	** If the file existed then return back the result from the open,
	** otherwise all of our efforts were a bust, return back a failure.
	*/ 
	if (found)
		return ( SIfopen(&loc, ERx("r"), SI_TXT, MAX_LINE, input) );
	else
		return (FAIL);
}
Ejemplo n.º 6
0
/*{
** Name: NMwritesyms - write the symbol table list to file.
**
** Description:
**    Write the symbol table list back out to the file.
**
**    This duplicates the function in ingunset.c, but shouldn't be in 
**    compatlib because no one else has any business writing the file.
**
** Inputs:
**	none.
**
** Output:
**	none.
**
**      Returns:
**          OK                         	    Function completed normally. 
**          FAIL                            Function completed abnormally.
**
** History:
**      20-jul-87 (mmm)
**          Updated to meet jupiter standards.
**	14-apr-89 (arana)
**	    When LOlast was added to update symbol table mod time,
**	    return value was saved off but not returned.
**	15-jul-93 (ed)
**	    adding <gl.h> after <compat.h>
**      29-sep-94 (cwaldman)
**          Changed check of NMopensyms return value to compare against
**          (FILE *)NULL (was NULL).
**          Changed write routine to write into a temporary file first,
**          check whether this file has been written OK, and rename
**          temporary file to symbol.tbl if it is alright. This is part
**          of the fix for bug 44445 (symbol.tbl disappears). There is
**          still a slight chance of something going wrong during the
**          rename, but in that case variables are at least preserved
**          in symbol.tmp.
**      19-oct-94 (abowler)
**          Minor correction to change above. Cal to SIopen should be
**          passed address of location structure. (Didn't show up as
**          a bug on su4_u42 !)
**      28-feb-95 (cwaldman)
**          Amendment to change on 29 Sep. Part of the check whether
**          the temporary symbol table had been written OK was to check
**          the file size. The check would return the file size if
**          check was OK and 0 otherwise. If a 0 was returned, the old
**          symbol.tbl would not be replaced. This made it impossible
**          to 'ingunset' the last variable in a symbol.tbl. Changed
**          'OK-check' to use -1 as error indicator.
**	02-jul-1996 (sweeney)
**	    Apply umask fix (bug #71890) from ingres63p
**	07-apr-2004 (somsa01)
**	    Added backup of symbol.tbl logic.
*/
STATUS
NMwritesyms()
{
    register SYM	*sp;
    FILE		*fp, *tfp = NULL;
    register i4 	status = OK;
    register i4 	closestat;
    char		buf[ MAXLINE + NULL_NL_NULL ];
    char		tbuf[ MAXLINE + NULL_NL_NULL ];
    i4			flagword, size, symcount = 0, bksymcount;
    STATUS		retval;
    LOCATION		t_loc;
    LOINFORMATION	loinfo;
    bool		perform_backup = TRUE;
    OFFSET_TYPE		bk_size;

    /*
    ** ensure sensible umask for symbol.tmp, as it will become symbol.tbl
    */
    PEsave();
    PEumask("rw-r--");
 
    if ((FILE *)NULL == (fp = NMopensyms( "r" )))
    {
	PEreset();
	return (NM_STOPN);
    }
    SIclose(fp);
 
    LOcopy(&NMSymloc, tbuf, &t_loc);
    if ( OK != LOfstfile("symbol.tmp", &t_loc) ||
         OK != SIopen(&t_loc, "w", &tfp))
    {
	return (NM_STOPN);
    }

    for ( sp = s_list; sp != NULL; sp = sp->s_next )
    {
	(VOID) STpolycat( 3, sp->s_sym, "\t", sp->s_val, buf );
	STmove( buf, ' ', MAXLINE, buf );

	buf[ MAXLINE - 1 ] = '\n';
	buf[ MAXLINE ] = '\0';
 
	if ( OK != (status = SIputrec(buf, tfp)))
	    break;

	symcount++;
    }
 
    /* Very interested in close status of file being written */
 
    closestat = SIclose( tfp );
    flagword = (LO_I_SIZE);
    size = (OK == LOinfo(&t_loc,&flagword,&loinfo) ? loinfo.li_size : -1);
 
    retval=(status != OK || closestat != OK || size == -1 ? NM_STAPP : OK);

    /* if file written ok update modification time */
    if(retval == OK)
    {
	LOrename(&t_loc, &NMSymloc);
	LOlast(&NMSymloc, &NMtime);
 
#if defined(su4_cmw)
	/* Now reset the old MAC label if any */
	if (NM_got_label)
	{
	    (void)setcmwlabel(NM_path, &NM_saved_label, SETCL_ALL);
	    NM_got_label=0;
	}
#endif

	/*
	** If we have no backup to check against, just do it. Otherwise,
	** make sure our new symbol table differs from the backup by at most
	** one symbol before performing a backup.
	*/
	if (LOexist(&NMBakSymloc) == OK)
	{
	    LOsize(&NMBakSymloc, &bk_size);
	    bksymcount = (i4)(bk_size / (MAXLINE + 1));
	    if (bksymcount != symcount && bksymcount != symcount - 1 &&
		bksymcount != symcount + 1)
	    {
		perform_backup = FALSE;
	    }
	}

	if (perform_backup)
	{
	    if (SIopen(&NMBakSymloc, "w", &tfp) == OK)
	    {
		for (sp = s_list; sp != NULL; sp = sp->s_next)
		{
		    STpolycat(3, sp->s_sym, "\t", sp->s_val, buf);
		    STmove(buf, ' ', MAXLINE, buf);

		    buf[MAXLINE - 1] = '\n';
		    buf[MAXLINE] = '\0';
 
               	    if ((status = SIputrec(buf, tfp)) != OK)
			break;
		}
 
		SIclose(tfp);
	    }
	} 
    }

    PEreset();
    return (retval);
}
Ejemplo n.º 7
0
/*
** Writes or erases a transaction log and displays a completion thermometer.
**
** 'context' must not be NULL, and defaults for element 0 & 1 of context
** must have been set.
*/
i4
write_transaction_log(bool create, PM_CONTEXT *context,
	char *log_dir[], char *log_file[],
	void (*message)(char *), void (*init_graph)(bool, i4), 
	i4 graph_size, void (*update_graph)())
{

# define LG_PAGE_SIZE		2048L
# define LG_NUMBER_OF_PAGES	32L	/* Number of pages to write at a time */

    DI_IO 		dio[LG_MAX_FILE];
    char 		buf[LG_PAGE_SIZE * LG_NUMBER_OF_PAGES];
    char		nodename[GL_MAXNAME];
    i4  		i, j, marker, count, num_logs;
    i4 		num_pages, page, part_size, remainder, loop;
    CL_ERR_DESC 	err;
    char		*string;
    LOCATION 		loc[LG_MAX_FILE];
    char 		locbuf[MAX_LOC + 1];
    char 		*path[LG_MAX_FILE];
    i4  		LOinfo_flag;
    LOINFORMATION 	loc_info;
    i8 		size;
    CS_SCB 		scb;
    bool		size_in_kbytes = FALSE;

    MEfill( sizeof( scb ), 0, ( PTR ) &scb ); 
    
    ++graph_size;

    /* Prepare transaction for log LOCATION(s) */
    for (num_logs = 0; num_logs < LG_MAX_FILE; num_logs++)
    {
	if (log_dir[num_logs] == 0)
	    break;
	STcopy( log_dir[num_logs], locbuf );
	LOfroms( PATH, locbuf, &loc[num_logs] );
	LOfstfile( log_file[num_logs], &loc[num_logs] );
	LOtos( &loc[num_logs], &path[num_logs] );
    }

    /* get size (in bytes) of log file to be created or erased */
    if( create )
    {
	STATUS status;
	char *value;
	bool havevalue = FALSE;

	status = PMmGet( context, ERx( "$.$.rcp.file.kbytes" ), &value );
	if ( status == OK )
	{
	    havevalue = TRUE;
	    size_in_kbytes = TRUE;
	}

	if ( havevalue == FALSE )
	{
	    status = PMmGet( context, ERx( "$.$.rcp.file.size" ), &value );
	    if ( status == OK )
		havevalue = TRUE;
	}

	if ( havevalue == FALSE )
	{
	    if ( message != NULL )
	    {
		char msg[ BIG_ENOUGH ];
		STprintf( msg, ERx( "%s %s" ),
			PMmExpandRequest( context,
			ERx( "$.$.rcp.file.kbytes" ) ),
			"not found." );
		message( msg );
	    }
	    return( 0 );	
	}
	CVal8( value, &size );
    }
    else
    {
	LOinfo_flag = LO_I_SIZE;
	size = 0;

	for (i = 0; i < num_logs; i++)
	{
	    if ( LOinfo( &loc[i], &LOinfo_flag, &loc_info ) != OK )
	    {
		if ( message != NULL )
		{
		    char msg[ BIG_ENOUGH ];

		    STprintf( msg,
			    "Unable to get size of transaction log:\n\n\t%s",
			    path[i] );	
		    (*message)( msg );
		}
		return( 0 );	
	    }
	    else
		size += loc_info.li_size;
	    if ((LOinfo_flag & LO_I_SIZE) == 0)
		break;
	}

	if ( (LOinfo_flag & LO_I_SIZE) == 0 || size == 0L)
	{
	    STATUS status;
	    char *value;
	    bool havevalue = FALSE;

	    status = PMmGet( context, ERx( "$.$.rcp.file.kbytes" ), &value );
	    if ( status == OK )
	    {
		havevalue = TRUE;
		size_in_kbytes = TRUE;
	    }

	    if ( havevalue == FALSE )
	    {
		status = PMmGet( context, ERx( "$.$.rcp.file.size" ), &value );
		if ( status == OK )
		    havevalue = TRUE;
	    }

	    if ( havevalue == FALSE  )
	    {
		if ( message != NULL )
		{
		    char msg[ BIG_ENOUGH ];

		    STprintf( msg, ERx( "%s %s." ),
			    PMmExpandRequest( context,
			    ERx( "$.$.rcp.file.kbytes" ) ),
			    "not found." );
		    message( msg );
		}
		return( 0 );	
	    }
	    CVal8( value, &size );
	}
    }

    for (i = 0; i < num_logs; i++)
    {
	if ( create && LOexist( &loc[i] ) == OK )
	{
		char msg[ BIG_ENOUGH ];

		if ( message != NULL )
		{
			STprintf( msg, "%s already exists.", path[i] ); 
			(*message)( msg ); 
			STprintf( msg, "To create a new transaction log, you must first delete all partitions of the old one." ); 
			(*message)( msg ); 
		}
		return( 0 );	
	}
    }

    if ( CSinitiate( (i4 *) NULL, (char ***) NULL, (CS_CB *) NULL )
	    != OK )
    {
	    if ( message != NULL )
		    message( "Unable to connect to shared memory" );
	    return( 0 );	
    }

    CSset_sid( &scb );

    /* create DI file */
    for (i = 0; i < num_logs; i++)
    {
	if ( create && DIcreate( &dio[i], 
		log_dir[i],  (u_i4)STlength(log_dir[i]), 
		log_file[i], (u_i4)STlength(log_file[i]),
		(i4)LG_PAGE_SIZE, &err) != OK )
	{
	    char msg[ BIG_ENOUGH ];

	    if ( message != NULL )
	    {
		STprintf( msg,
			"Unable to create transaction log:\n\n\t%s",
			path[i] );	
		(*message)( msg );
	    }
	    return( 0 );
	}

	/* open DI file */
	if ( DIopen( &dio[i],
		log_dir[i],  (u_i4)STlength(log_dir[i]), 
		log_file[i], (u_i4)STlength(log_file[i]),
		(i4)LG_PAGE_SIZE, DI_IO_WRITE, 0, &err) != OK )
	{
	    if ( message != NULL )
	    {
		char msg[ BIG_ENOUGH ];

		STprintf( msg,
			"Unable to open transaction log:\n\n\t%s",
			path[i] );	
		(*message)( msg );
	    }
	    return( 0 );
	}
    }

    if ( size_in_kbytes == FALSE )
	size = (size + 1023) / 1024;

    (*init_graph)( create, (i4) size );

    num_pages = size / (LG_PAGE_SIZE/1024);

    part_size = num_pages / num_logs;

    /* Readjust num_pages to be a multiple of num_logs */
    num_pages = part_size * num_logs;

    loop = part_size / LG_NUMBER_OF_PAGES;
    remainder = part_size % LG_NUMBER_OF_PAGES;

    marker = loop / graph_size;

    /* Fill buffer with zeroes */
    MEfill( sizeof( buf ), 0 , buf);

    for (i = 0; i < num_logs; i++)
    {
	if ( create &&
		DIalloc( &dio[i], part_size, &page, &err ) != OK )
	{
	    DIdelete( &dio[i], log_dir[i], (u_i4)STlength( log_dir[i] ),
		    log_file[i], (u_i4)STlength( log_file[i] ), &err );
	    if ( message != NULL )
		    (*message)( "Unable to allocate space in transaction log file." );
	    return( 0 );
	}
    }

    count = 0;
    for( j = 0; j < loop; j++ )
    {
	i4	n = LG_NUMBER_OF_PAGES;
	i4	page_no = j * n;

	for (i = 0; i < num_logs; i++)
	{
	    if ( DIwrite( &dio[i], &n, page_no, 
			buf, &err ) != OK )
	    {
		DIdelete( &dio[i], 
		    log_dir[i], (u_i4)STlength(log_dir[i]),
		    log_file[i], (u_i4)STlength(log_file[i]),
		    &err );
		if ( message != NULL )
			(*message)( "Unable to continue writing transaction log." );
		return( 0 );
	    }
	}

	if ( j >= marker && j % marker == 0 &&
		(f4) ((f4) j / (f4) loop) >= ((f4) count + 1) /
		graph_size )
	{
	    ++count;
	    (*update_graph)();
	    SIflush( stdout );
	}
    }

    if (remainder)
    {
	i4	page_no = loop * LG_NUMBER_OF_PAGES;

	for (i = 0; i < num_logs; i++)
	{
	    if ( DIwrite( &dio[i], &remainder, page_no,
			buf, &err ) != OK )
	    {
		DIdelete( &dio[i], 
		    log_dir[i], (u_i4)STlength(log_dir[i]),
		    log_file[i], (u_i4)STlength(log_file[i]),
		    &err );
		if ( message != NULL )
			(*message)( "Unable to continue writing transaction log." );
		return( 0 );
	    }
	}
    }

    for (i = 0; i < num_logs; i++)
    {
	if ( DIforce( &dio[i], &err ) != OK )
	{
	    DIdelete( &dio[i], log_dir[i], (u_i4)STlength(log_dir[i]),
		    log_file[i], (u_i4)STlength(log_file[i]), &err );
	    if ( message != NULL )
		(*message)( "Unable to force changes to transaction log." );
	    return( 0 );
	}

	if ( create && DIflush( &dio[i], &err ) != OK )
	{
	    DIdelete( &dio[i], log_dir[i], (u_i4)STlength(log_dir[i]),
		    log_file[i], (u_i4)STlength(log_file[i]), &err );
	    if ( message != NULL )
		(*message)( "Unable to flush transaction log to disk." );
	    return( 0 );
	}

	if( DIclose( &dio[i], &err ) != OK)
	{
	    DIdelete( &dio[i], log_dir[i], (u_i4)STlength(log_dir[i]),
		    log_file[i], (u_i4)STlength(log_file[i]), &err );
	    if ( message != NULL )
		(*message)( "Unable to finish writing transaction log." );
	    return( 0 );
	}
    }

    return( (i4) size );
}
Ejemplo n.º 8
0
ADF_CB *
FEadfcb ()
{
    if (!done)
    {
	char		*cp;
	DB_STATUS	rval;
	PTR		srv_cb_ptr;
	SIZE_TYPE	srv_size;
	SIZE_TYPE	dbinfo_size;
	PTR		dbinfoptr;
        STATUS          tmtz_status;
        STATUS          date_status;
	char		date_type_alias[100];
        char            col[] = "udefault";
    	STATUS          status = OK;
    	CL_ERR_DESC     sys_err;
	ADUUCETAB	*ucode_ctbl; /* unicode collation information */
        PTR         	ucode_cvtbl;


	
    	done = TRUE;

	/* first, get the size of the ADF's server control block */
	srv_size = adg_srv_size();

	/* allocate enough memory for it */
	if ((srv_cb_ptr = MEreqmem(0, srv_size, FALSE, (STATUS *)NULL)) == NULL)
	{
    	    EXsignal(EXFEBUG, 1, ERx("FEadfcb(alloc)"));
	}

	/*
	**  Fix up code so that "now" works properly for frontends.
	**  Only allocating enough for one (1) dbmsinfo() request.
	*/
	dbinfo_size = sizeof(ADF_TAB_DBMSINFO);
	if ((dbinfoptr = MEreqmem(0, dbinfo_size, TRUE, (STATUS*)NULL)) == NULL)
	{
		IIUGbmaBadMemoryAllocation(ERx("FEadfcb"));
	}

	dbinfo = (ADF_TAB_DBMSINFO *) dbinfoptr;

	dbinfo->tdbi_next = NULL;
	dbinfo->tdbi_prev = NULL;
	dbinfo->tdbi_length = dbinfo_size;
	dbinfo->tdbi_type = ADTDBI_TYPE;
	dbinfo->tdbi_s_reserved = -1;
	dbinfo->tdbi_l_reserved = (PTR)-1;
	dbinfo->tdbi_owner = (PTR)-1;
	dbinfo->tdbi_ascii_id = ADTDBI_ASCII_ID;
	dbinfo->tdbi_numreqs = 1;

	/*
	**  Now define request.
	*/
	dbinfo->tdbi_reqs[0].dbi_func = IIUGnfNowFunc;
	dbinfo->tdbi_reqs[0].dbi_num_inputs = 0;
	dbinfo->tdbi_reqs[0].dbi_lenspec.adi_lncompute = ADI_FIXED;
	STcopy("_BINTIM", dbinfo->tdbi_reqs[0].dbi_reqname);
	dbinfo->tdbi_reqs[0].dbi_reqcode = 1;
	dbinfo->tdbi_reqs[0].dbi_lenspec.adi_fixedsize = 4;
	dbinfo->tdbi_reqs[0].dbi_dtr = DB_INT_TYPE;

	/*
	** set timezone in ADF cb  - Any errors must be reported
        ** after adg_init() called.
	*/

	if ( (tmtz_status = TMtz_init(&cb.adf_tzcb)) == OK)
        {
	   tmtz_status = TMtz_year_cutoff(&cb.adf_year_cutoff);
        }

	/* Always use INGRESDATE by default, and check 
	** 'ii.<node>.config.date_alias' (kibro01) b118702
	*/
	cb.adf_date_type_alias = AD_DATE_TYPE_ALIAS_INGRES;
	STprintf(date_type_alias,ERx("ii.%s.config.date_alias"),PMhost());
	date_status = PMget(date_type_alias, &cp);
	if (date_status == OK && cp != NULL && STlength(cp))
	{
	    if (STbcompare(cp, 0, ERx("ansidate"), 0, 1) == 0)
		cb.adf_date_type_alias = AD_DATE_TYPE_ALIAS_ANSI;
	    else if (STbcompare(cp, 0, ERx("ingresdate"), 0, 1) == 0)
		cb.adf_date_type_alias = AD_DATE_TYPE_ALIAS_INGRES;
	    else
		cb.adf_date_type_alias = AD_DATE_TYPE_ALIAS_NONE;
	}

	/* set timezone table to NULL in ADF cb, adg_init() will fill it */
	/* cb.adf_tz_table = NULL; - not needed, done in declaration above */

	/* Start up ADF */
    	rval = adg_startup(srv_cb_ptr, srv_size, dbinfo, 0);
	if (DB_FAILURE_MACRO(rval))
	{
	    /*
	    ** Before bailing out, try to be helpful. Since the environment
	    ** is likely not set up correctly, write hard coded messages
	    ** since error message fetch will likely fail in this situation.
	    */
	    char	*tempchar;
	    i4		dummy;
	    LOCATION	temploc;
	    NMgtAt("II_SYSTEM", &tempchar);
	    if (tempchar && *tempchar)
	    {
		LOfroms(PATH, tempchar, &temploc);
		if (LOexist(&temploc))
		{
		    tempchar = ERx("FEadfcb: II_SYSTEM DOES NOT EXIST\n");
		    SIwrite(STlength(tempchar), tempchar, &dummy, stderr);
		}
		else
		{
		    NMloc(ADMIN, FILENAME, ERx("config.dat"), &temploc);
		    if (LOexist(&temploc))
		    {
			tempchar = ERx("FEadfcb: II_SYSTEM IS NOT SET CORRECTLY\n");
			SIwrite(STlength(tempchar), tempchar, &dummy, stderr);
		    }
		}
	    }
	    else
	    {
		tempchar = ERx("FEadfcb: II_SYSTEM IS NOT SET\n");
		SIwrite(STlength(tempchar), tempchar, &dummy, stderr);
	    }
    	    EXsignal(EXFEBUG, 1, ERx("FEadfcb(start)"));
	}

	/* put the pointer to ADF's server control block in the ADF_CB */
	cb.adf_srv_cb = srv_cb_ptr;

	/* set up the error message buffer */
    	cb.adf_errcb.ad_ebuflen = DB_ERR_SIZE;
    	cb.adf_errcb.ad_errmsgp = ebuffer;

	/* initialize the ADF_CB */
    	rval = adg_init(&cb);
	if (DB_FAILURE_MACRO(rval))
	{
    	    EXsignal(EXFEBUG, 1, ERx("FEadfcb(init)"));
	}

	/* find out which natural language we should speak */
	cb.adf_slang = iiuglcd_langcode();

	/* Always QUEL; for SQL explictly change this with 'IIAFdsDmlSet()'. */
	cb.adf_qlang = DB_QUEL;

	/* lets get the multinational info */

	/* 
	** Defaults for all of these are initially set statically, above.
	*/
	NMgtAt(ERx("II_DATE_FORMAT"), &cp);
    	if ( cp != NULL && *cp != EOS )
    	{
	    FEapply_date_format(&cb,cp);
    	}

	NMgtAt(ERx("II_MONEY_FORMAT"), &cp);
    	if ( cp != NULL && *cp != EOS )
    	{
	    FEapply_money_format(&cb,cp);
    	}

	NMgtAt(ERx("II_MONEY_PREC"), &cp);
    	if ( cp != NULL && *cp != EOS )
    	{
	    FEapply_money_prec(&cb,cp);
    	}

	NMgtAt(ERx("II_DECIMAL"), &cp);
    	if ( cp != NULL && *cp != EOS )
    	{
	    FEapply_decimal(&cb,cp);
    	}

	NMgtAt(ERx("II_UNICODE_SUBS"), &cp);
	if ( !cp )
	{
	    cb.adf_unisub_status = AD_UNISUB_OFF;
	}
	else
	{
	    /* As with SET unicode_substitution take the first char */
	    cb.adf_unisub_status = AD_UNISUB_ON;
	    *cb.adf_unisub_char = cp[0];
	}

	NMgtAt(ERx("II_NULL_STRING"), &cp);
	if ( cp != NULL && *cp != EOS )
	{
	    FEapply_null(&cb,cp);
	}

	/* If there was a Timezone error other than the expected ingbuild
	** error TM_PMFILE_OPNERR, then lets report it now. */

        if (tmtz_status && (tmtz_status != TM_PMFILE_OPNERR))
        {
	    LOCATION    loc_root;
	    STATUS status = OK;
	    status = NMloc(FILES, PATH, ERx("zoneinfo"), &loc_root);
#if defined(conf_BUILD_ARCH_32_64) && defined(BUILD_ARCH64)
            status = LOfaddpath(&loc_root, ERx("lp64"), &loc_root);
#endif
#if defined(conf_BUILD_ARCH_64_32) && defined(BUILD_ARCH32)
    {
        /*
        ** Reverse hybrid support must be available in ALL
        ** 32bit binaries
        */
        char    *rhbsup;
        NMgtAt("II_LP32_ENABLED", &rhbsup);
        if ( (rhbsup && *rhbsup) &&
       ( !(STbcompare(rhbsup, 0, "ON", 0, TRUE)) ||
         !(STbcompare(rhbsup, 0, "TRUE", 0, TRUE))))
            status = LOfaddpath(&loc_root, "lp32", &loc_root);
    }
#endif /* ! LP64 */

            if ( status == OK )
            {
		status = LOexist(&loc_root);
            }
            if ( status == OK )
	    {
                   IIUGerr(tmtz_status, 0, 0);

                   /* As this may disappear from the screen quickly,
                   ** let's pause to allow the users to reflect on the
                   ** fact that the timezone info is (probably) wrong.
                   */
                   if (!IIugefa_err_function) PCsleep(5000);
	    }
        }

	/* Initialize unicode collation for UTF8 installations */
	if (CMischarset_utf8())
	{
          if (status = aduucolinit(col, MEreqmem, 
			&ucode_ctbl, &ucode_cvtbl, &sys_err))
          {
    	    EXsignal(EXFEBUG, 1, ERx("FEadfcb(alloc)"));
          }

          cb.adf_ucollation = (PTR) ucode_ctbl;

	  /* Set unicode normalization to NFC just in case 
	  ** Front end will need it.
	  */
          if ((status = adg_setnfc(&cb)) != E_DB_OK)
    	    EXsignal(EXFEBUG, 1, ERx("FEadfcb(alloc)"));
	}
	/* lets not do this again! */
    }

    return &cb;
}
Ejemplo n.º 9
0
main(int argc, char **argv)
{
    STATUS status = OK;
    VMS_STATUS vStatus;
    char srcbuf[NAME_FILE_SIZE];
    char dstbuf[NAME_FILE_SIZE];
    char delFile[NAME_FILE_SIZE];
    struct dsc$descriptor_s filename_d = 
        { sizeof (delFile) - 1,
            DSC$K_DTYPE_T,
            DSC$K_CLASS_S,
            delFile
        };
    FILE *srcFile = NULL;
    FILE *dstFile = NULL;
    FILE *nameFile = NULL;
    LOCATION loc;
    bool clusterArg = FALSE;
    bool unclusterArg = FALSE;
    bool writeOutput = FALSE;
    bool validSyntax;
    bool clustered = FALSE;
    bool v1DecryptErr = FALSE;
    bool rewrite = FALSE;
    bool isLogin = FALSE;
    i4   total_recs = 0;
    char local_host[MAX_LOC+CM_MAXATTRNAME];
    char config_host[MAX_LOC+CM_MAXATTRNAME];
    i2 i,j;
    i4 active_rec;
    i4 offset;
    char *onOff = NULL;
    bool srcOpened=FALSE;
    bool dstOpened=FALSE;
    bool printable = TRUE;
    GCN_QUEUE *gcn_q;
    GCN_QUEUE *merge_q;
    i4 rec_len = 0;
    QUEUE *q;
    u_i1  local_mask[ 8 ];        /* Must be 8 bytes */
    char name[MAX_LOC+CM_MAXATTRNAME];
    i4 count;
    char *p = NULL;
    i4 dcryptFail = 0;
    i2 pc;
    char *pv[ 3 ];
    GCN_DB_REC0 tmp_rec;
    SYSTIME timestamp;

    MEadvise(ME_INGRES_ALLOC);
    SIeqinit();
    GChostname( local_host, sizeof(local_host));
    STcopy (PMhost(), config_host);
    if (argc == 1)
       validSyntax = TRUE;
    /*
    ** Parse input arguments.
    */    
    for (i = 1; i < argc; i++)
    {
        validSyntax = FALSE;
        for (j = 0; j < argLen; j++)
        {
            if (!STncasecmp(arg[j],argv[i], STlength(argv[i])))
            {
                switch(j)
                {
                    case HELP1:
                    case HELP2:
                    case HELP3:
                    case HELP4:
                       usage();
                       break;

                    case VERBOSE:
                       validSyntax = TRUE;
                       verboseArg = TRUE;
                       break;

                    case CLUSTER:
                       validSyntax = TRUE;
                       clusterArg = TRUE;
                       writeOutput = TRUE;
                       break;

                    case UNCLUSTER:
                       validSyntax = TRUE;
                       unclusterArg = TRUE;
                       writeOutput = TRUE;
                       break;
                }
            } /* if (!STncasecmp(arg[j],argv[i], STlength(argv[i]))) */
            if (validSyntax)
                break;
        } /* for (j = 0; j < argLen; j++) */
        if (!validSyntax)
            break;
    } /* for (i = 1; i < argc; i++) */

    if (!validSyntax)
    {
        usage();
        PCexit(1);
    }

    if (clusterArg && unclusterArg)
    {
        SIprintf("Cannot specify both -c and -u\n\n");
            usage();
        PCexit(1);
    }

    if (verboseArg)
        SIprintf("Local host is %s\n", local_host);

    /*
    ** Generate key seeds for encoding and decoding.
    */
    STpolycat( 2, GCN_LOGIN_PREFIX, local_host, name );
    gcn_init_mask( name, sizeof( local_mask ), local_mask );

    QUinit(&gcn_qhead);
    QUinit(&merge_qhead);
    PMinit();

    /*
    ** See if this is a clustered installation.  If it is, 
    ** the node, login, and attribute files have no file extension.
    */
    if ( PMload( (LOCATION *)NULL, (PM_ERR_FUNC *)NULL ) != OK )
    {
        SIprintf("Error reading config.dat, exiting\n");
        goto cvt_exit;      
    }

    PMsetDefault( 0, SystemCfgPrefix );
    PMsetDefault( 1, config_host );
    PMsetDefault( 2, ERx("gcn") );

    status = PMget( ERx("!.cluster_mode"), &onOff);
    if (onOff && *onOff)
        ;
    else
        onOff = "OFF";

    if (verboseArg)
        SIprintf("Cluster mode is %s\n", onOff);

    if (!clusterArg && !unclusterArg)
        clustered = !STncasecmp(onOff, "ON", STlength(onOff));

    /*
    ** Rewrite the named GCN files.  For clustered installations, the
    ** node, login and attribute files have no hostname extension.
    */
    for ( i = 0; i < NBR_NAMED_FILES; i++ )
    {  
        /*
        ** Ticket files are simply deleted.
        */
        if (i == IILTICKET || i == IIRTICKET)
        {
            STprintf(delFile, "II_SYSTEM:[INGRES.FILES.NAME]II%s*;*", 
                named_file[i].file);
            if (verboseArg)
                SIprintf("Deleting %s\n", delFile);
            filename_d.dsc$w_length = STlength(delFile);
            vStatus = lib$delete_file(&filename_d,0,0,0,0,0,0,0,0,0);
            if (!vStatus & STS$M_SUCCESS)
                SIprintf("delete of %s failed, status is 0x%d\n", delFile,
                    vStatus);
            continue;
        }    
 
        rewrite = FALSE;
        if (!clusterArg && !unclusterArg)
            writeOutput = FALSE;
        if ( ( status = NMloc( FILES, PATH & FILENAME, 
            (char *)NULL, &loc ) ) != OK )
        {
            SIprintf("iicvtgcn: Could not find II_SYSTEM:[ingres.files]\n");
            goto cvt_exit;
        }
     
        LOfaddpath( &loc, "name", &loc );

        if (clustered || unclusterArg)
        {
            if (named_file[i].add_cluster_node)
                STprintf( srcbuf, "II%s_%s", named_file[i].file,config_host);
            else
                STprintf(srcbuf, "II%s", named_file[i].file);
        }
        else 
            STprintf( srcbuf, "II%s_%s", named_file[i].file,config_host);

        if (verboseArg)
            SIprintf("Opening %s for input\n", srcbuf);

        LOfstfile( srcbuf, &loc );

        /*
        ** Ignore non-existent files.
        */
        if ( LOexist( &loc ) != OK )
        {
            if (verboseArg)
                SIprintf("%s does not exist\n", srcbuf);
            continue;
        }
        /*
        ** Open the existing file as "regular" RACC.
        */
        status = SIfopen( &loc, "r", (i4)SI_RACC, sizeof( GCN_DB_REC0 ), 
            &srcFile );
        /*
        ** If the file exists but can't be opened, it's already optimized.
        */
        if (status == E_CL1904_SI_CANT_OPEN && ( LOexist( &loc ) == OK ) )
        {
            /*
            ** Open the existing file as "optimized" RACC.
            */
            status = SIfopen( &loc, "r", (i4)GCN_RACC_FILE, 
                sizeof( GCN_DB_REC0 ), &srcFile );
            if (status != OK)
            {
                SIprintf( "iicvtgcn: Error opening %s, status is %x\n",
                    srcbuf, status );
                continue;
            }
            if (verboseArg)
                SIprintf("%s is already optimized\n", srcbuf);
        }
        else if (status != OK)
        {
            SIprintf( "iicvtgcn: Error opening %s, status is %x\n",
                srcbuf, status );
            continue;
        }

        /*
        ** A successful open as SI_RACC means the file is not optimized.
        ** This file needs a rewrite.
        */
        else
        {
            if (verboseArg)
                SIprintf("Rewriting %s as optimized\n", srcbuf);
            writeOutput = TRUE;    
        }

        srcOpened = TRUE;

        while ( status == OK )
        {
            /*
            ** Read the source data and store in a queue for analysis.
            */
            status = SIread( srcFile, sizeof( GCN_DB_REC0 ),
                &count, (PTR)&tmp_rec );
            if ( status == ENDFILE )
                break;

            if ( status != OK )
            {
                SIprintf("iicvtgcn: Error reading %s, status is %x\n",
                    srcbuf, status);
                goto cvt_exit;
            }
            else if (tmp_rec.gcn_invalid && tmp_rec.gcn_tup_id != -1)
                continue;
            else
            {
                gcn_q = (GCN_QUEUE *)MEreqmem(0, sizeof(GCN_QUEUE),0,NULL);
                if (!gcn_q)
                {
                    SIprintf("iicvtgcn: Cannot allocate memory, exiting\n");
                    goto cvt_exit;
                }
                MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), (PTR)&gcn_q->buf);
                QUinsert(&gcn_q->q, &gcn_qhead);
                /*
                ** EOF record found.
                */
                if (gcn_q->buf.gcn_tup_id == -1)
                {
                    gcn_q->buf.gcn_l_uid = 0;
                    gcn_q->buf.gcn_uid[0] = '\0';
                    gcn_q->buf.gcn_l_obj = 0;
                    gcn_q->buf.gcn_obj[0] = '\0';
                    gcn_q->buf.gcn_l_val = 0;
                    gcn_q->buf.gcn_val[0] = '\0';
                    gcn_q->buf.gcn_invalid = TRUE;
                    break;
                }
            }
        } /* while ( status == OK ) */

        /*
        ** Decrypt passwords for IILOGIN files.  If any V1 records are found, 
        ** the IILOGIN file will need to be rewritten.
        */
        isLogin = FALSE;
        for (q = gcn_qhead.q_prev; q != &gcn_qhead; q = q->q_prev)
        {
            gcn_q = (GCN_QUEUE *)q;

            /*
            ** EOF record found.
            */
            if (gcn_q->buf.gcn_tup_id == -1)
            {
                gcn_q->buf.gcn_invalid = TRUE;
                break;
            }

            if (i == IILOGIN)
            {
                isLogin = TRUE;
                MEcopy((PTR)&gcn_q->buf, sizeof(GCN_DB_REC0), (PTR)&tmp_rec);
                if (verboseArg)
                     SIprintf("\tEncoding vnode %s\n", gcn_q->buf.gcn_obj);

                if (unclusterArg)
                    status = gcn_recrypt( FALSE, local_mask, 
                        gcn_q->buf.gcn_val, &v1DecryptErr, &writeOutput);
                else if (clusterArg)
                    status = gcn_recrypt( TRUE, local_mask, 
                    gcn_q->buf.gcn_val, &v1DecryptErr, &writeOutput);
                else
                    status = gcn_recrypt( clustered, local_mask, 
                    gcn_q->buf.gcn_val, &v1DecryptErr, &writeOutput);

                if (status != OK)
                {
                    if (verboseArg)
                        SIprintf("Cannot decrypt password from " \
                            "vnode %s status %x\n", gcn_q->buf.gcn_obj,
                            status);
                    dcryptFail++;
                    MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), 
                        (PTR)&gcn_q->buf);
                    continue;                
                }
                if (v1DecryptErr)
                {
                    if (verboseArg)
                        SIprintf("Cannot decrypt password from " \
                            "vnode %s\n", gcn_q->buf.gcn_obj);
                    dcryptFail++;
                    MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), 
                        (PTR)&gcn_q->buf);
                    continue;
                }
            }  /* if (LOGIN) */

        } /* for (q = gcn_qhead.q_prev; q != &gcn_qhead; q = q->q_prev) */
        
        if (dcryptFail && verboseArg && isLogin)
        {
            if (clustered || unclusterArg )
                SIprintf("\n%d vnode(s) could not be decrypted.\n" \
                    "Probably some login entries were created on " \
                    "another node.\nTry executing iicvtgcn on another " \
                    "node to merge the other node's entries.\n\n", dcryptFail);
            else
                SIprintf("\n%d vnode(s) could not be decrypted.\n" \
                    "Probably the login file was created on " \
                    "another host.\nTry executing iicvtgcn on " \
                    "a different host.\n\n", dcryptFail);
        }

        if (!writeOutput)
        {
            if (srcOpened)
                SIclose(srcFile);
            srcOpened = FALSE;
            cleanup_queues();
            continue;
        }
   
        /*
        ** Open the destination file with special GCN_RACC_FILE flag, for 
        ** optimized writes.
        */
        if (clustered || clusterArg) 
        {
            if (named_file[i].add_cluster_node)
                STprintf( dstbuf, "II%s_%s", named_file[i].file, local_host);
            else
                STprintf(dstbuf, "II%s", named_file[i].file);
        }
        else
            STprintf( dstbuf, "II%s_%s", named_file[i].file, local_host);

        if (clusterArg && !named_file[i].add_cluster_node)
            rewrite = TRUE;

        LOfstfile( dstbuf, &loc );

        if (rewrite)
        {
            status = SIfopen( &loc, "rw", (i4)GCN_RACC_FILE, 
                sizeof( GCN_DB_REC0 ), &dstFile );
            if ( status != OK )
            {
                status = SIfopen( &loc, "w", (i4)GCN_RACC_FILE, 
                    sizeof( GCN_DB_REC0 ), &dstFile );
                if (status == OK)
                {
                    SIclose( dstFile);
                    status = SIfopen( &loc, "rw", (i4)GCN_RACC_FILE, 
                        sizeof( GCN_DB_REC0 ), &dstFile );
                }
            }
        }
        else
            status = SIfopen( &loc, "w", (i4)GCN_RACC_FILE, 
                sizeof( GCN_DB_REC0 ), &dstFile );

        if ( status != OK )
        {
            SIprintf( "iicvtgcn: Error opening %s, status is %x\n",dstbuf,
                status );
            goto cvt_exit;
        }

        dstOpened = TRUE;

        if (verboseArg)
            SIprintf("%s %s\n", rewrite ? "Rewriting " : "Writing ", dstbuf);

        /*
        ** If this is a merge operation (-c), login, attribute or
        ** node files may change the location of EOF, since the
        ** file to be merged may have different records than
        ** the destination file. 
        ** Before merging, the output file is read and fed into a queue.
        ** Then each merge record is compared to each output record.
        ** If the entire records match, nothing is done. 
        ** If a global login record matches only the vnode name
        ** global or private records will be added if not present;
        ** otherwise, nothing is done.
        ** Node or attribute records may be added if only one field
        ** fails to match.
        */
        status = SIfseek(dstFile, (i4)0, SI_P_START);
        if (rewrite)
        {
            while ( status == OK )
            {
                /*
                ** Read the source data and store in a queue for analysis.
                */
                status = SIread( dstFile, sizeof( GCN_DB_REC0 ),
                    &count, (PTR)&tmp_rec );
                if ( status == ENDFILE )
                    break;

                if ( status != OK )
                {
                    SIprintf("iicvtgcn: Error reading %s, status is %x\n",
                        dstbuf, status);
                    goto cvt_exit;
                }
                else if (tmp_rec.gcn_invalid && tmp_rec.gcn_tup_id != -1)
                    continue;
                else
                {
                    merge_q = (GCN_QUEUE *)MEreqmem(0, sizeof(GCN_QUEUE),0,NULL);
                    if (!merge_q)
                    {
                        SIprintf("iicvtgcn: Cannot allocate memory, exiting\n");
                        goto cvt_exit;
                    }
                    MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), 
                        (PTR)&merge_q->buf);
                    QUinsert(&merge_q->q, &merge_qhead);
    
                    /*
                    ** EOF record found.
                    */
                    if (merge_q->buf.gcn_tup_id == -1)
                        break;
                }
                if ( status == ENDFILE )
                    break;

            } /* while ( status == OK ) */

            /*
            ** Go through the input queue.  Compare each record with
            ** the output (merge) queue.  If the record is invalid
            ** or doesn't match, it's ignored.
            */
            dcryptFail = 0;
            total_recs = 0;
            for (q = gcn_qhead.q_prev; q != &gcn_qhead; q = q->q_prev)
            {
                SYSTIME     timestamp;

                gcn_q = (GCN_QUEUE *)q;
                if (gcn_q->buf.gcn_tup_id == -1)
                    break;
                if ( !gcn_merge_rec( gcn_q, isLogin ) )
                    continue;
                if (isLogin)
                {
                    /*
                    ** Login passwords get encrypted as V0 in a cluster
                    ** environment.
                    */
                    MEcopy((PTR)&gcn_q->buf, sizeof(GCN_DB_REC0), 
                        (PTR)&tmp_rec);
                    status = gcn_recrypt( TRUE, local_mask, 
                        gcn_q->buf.gcn_val, &v1DecryptErr, &writeOutput);

                    if (status != OK)
                    {
                        if (verboseArg)
                            SIprintf("Cannot decrypt password from " \
                                "vnode %s status %x\n", gcn_q->buf.gcn_obj,
                                status);
                        dcryptFail++;
                        MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), 
                            (PTR)&gcn_q->buf);
                        continue;                
                    }
                    if (v1DecryptErr)
                    {
                        if (verboseArg)
                            SIprintf("Cannot decrypt password from " \
                                "vnode %s\n", gcn_q->buf.gcn_obj);
                        dcryptFail++;
                        MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), 
                            (PTR)&gcn_q->buf);
                        continue;
                    }
                }
                merge_q = (GCN_QUEUE *)MEreqmem(0, sizeof(GCN_QUEUE),0,NULL);
                if (!merge_q)
                {
                    SIprintf("iicvtgcn: Cannot allocate memory, exiting\n");
                    goto cvt_exit;
                }

                MEcopy((PTR)&gcn_q->buf, sizeof(GCN_DB_REC0), 
                    (PTR)&merge_q->buf);
                total_recs++;
              
                QUinsert(&merge_q->q, &merge_qhead);
            }

            if (dcryptFail && verboseArg && isLogin)
            {
                if (clustered || unclusterArg )
                    SIprintf("\n%d vnode(s) could not be decrypted.\n" \
                        "Probably some login entries were created on " \
                        "another node.\nTry executing iicvtgcn on another " \
                        "node to merge the other node's entries.\n\n", 
                        dcryptFail);
                    else
                        SIprintf("\n%d vnode(s) could not be decrypted.\n" \
                            "Probably the login file was created on " \
                            "another host.\nTry executing iicvtgcn on " \
                            "a different host.\n\n", dcryptFail);
            }
            if (verboseArg)
                SIprintf("Total records merged: %d\n", total_recs);

            /*
            ** If no records to merge, clean up and continue.
            */
            if (!total_recs)
            {
                cleanup_queues();
                continue;
            }

            status = SIfseek(dstFile, (i4)0, SI_P_START);
            active_rec = 0;
            for (q = merge_qhead.q_prev; q != &merge_qhead; q = q->q_prev)
            {
                merge_q = (GCN_QUEUE *)q;
                if (verboseArg)
                   SIprintf("Rewriting %s record vnode %s val %s\n", 
                       !STcasecmp("*", merge_q->buf.gcn_uid) ? "global" : 
                       "private", merge_q->buf.gcn_obj, merge_q->buf.gcn_val);
                if (merge_q->buf.gcn_tup_id == -1)
                    continue;
                status = SIwrite(sizeof( GCN_DB_REC0 ), 
                    (char *)&merge_q->buf, &count, dstFile );
                if ( status != OK)
                {
                    SIprintf( "iicvtgcn: Failed to write file %s, " \
                        "status is %x\n", srcbuf, status );
                    goto cvt_exit;
                }
                active_rec++;
            }
            /*
            ** Write new EOF record.
            */
            tmp_rec.gcn_tup_id = -1;
            tmp_rec.gcn_l_uid = 0;
            tmp_rec.gcn_uid[0] = '\0';
            tmp_rec.gcn_l_obj = 0;
            tmp_rec.gcn_obj[0] = '\0';
            tmp_rec.gcn_l_val = 0;
            tmp_rec.gcn_val[0] = '\0';
            tmp_rec.gcn_invalid = TRUE;
            offset = active_rec * sizeof(GCN_DB_REC0);
            status = SIfseek(dstFile, (i4)offset, SI_P_START);
            status = SIwrite(sizeof( GCN_DB_REC0 ), (PTR)&tmp_rec, 
                &count, dstFile );
        }
        else
        {
            for (q = gcn_qhead.q_prev; q != &gcn_qhead; q = q->q_prev)
            {
                gcn_q = (GCN_QUEUE *)q;
                gcn_q->buf.gcn_l_val = STlength(gcn_q->buf.gcn_val);
                if (verboseArg)
                   SIprintf("Writing %s record vnode %s val %s\n", 
                       !STcasecmp("*", gcn_q->buf.gcn_uid) ? "global" : 
                       "private", gcn_q->buf.gcn_obj, gcn_q->buf.gcn_val);
                status = SIwrite(sizeof( GCN_DB_REC0 ), (char *)&gcn_q->buf, 
                    &count, dstFile );
                if ( status != OK)
                {
                    SIprintf( "iicvtgcn: Failed to write file %s, " \
                        "status is %x\n", srcbuf, status );
                    goto cvt_exit;
                }
            }
        }  /* if (rewrite) */


        cleanup_queues();

        SIclose( srcFile );
        srcOpened = FALSE;
        SIclose( dstFile );
        dstOpened = FALSE;

    } /* for (i = 0; i < NBR_NAMED_FILES; i++ ) */

cvt_exit:

    cleanup_queues();

    if (srcOpened)
        SIclose(srcFile);
    if (dstOpened)
        SIclose(dstFile);
    PCexit( OK );
}