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 ); }
/****************************************************************************** ** 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); }
/* ** 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 ); }
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); }
/* ** 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); }
/*{ ** 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); }
/* ** 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 ); }
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; }
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 ); }