home *** CD-ROM | disk | FTP | other *** search
- From: zeppelin@login.dknet.dk (Thomas B. Pedersen)
- Newsgroups: comp.sources.misc
- Subject: v44i058: typhoon - Typhoon Relational Database Management System, Part02/09
- Date: 17 Sep 1994 21:44:15 -0500
- Organization: Sterling Software
- Sender: kent@sparky.sterling.com
- Approved: kent@sparky.sterling.com
- Message-ID: <35g9hv$ofg@sparky.sterling.com>
- X-Md4-Signature: ae0f28b0c926f38174b9f245402b9fdc
-
- Submitted-by: zeppelin@login.dknet.dk (Thomas B. Pedersen)
- Posting-number: Volume 44, Issue 58
- Archive-name: typhoon/part02
- Environment: SCO UNIX, Tandem NonStop UNIX, Sun Solaris, AIX, Linux, OS/2
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: typhoon/src/os2.c typhoon/src/ty_open.c
- # typhoon/src/util/backup.c typhoon/src/util/import.c
- # typhoon/src/util/restore.c
- # Wrapped by kent@sparky on Sat Sep 17 21:38:15 1994
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 2 (of 9)."'
- if test -f 'typhoon/src/os2.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'typhoon/src/os2.c'\"
- else
- echo shar: Extracting \"'typhoon/src/os2.c'\" \(3660 characters\)
- sed "s/^X//" >'typhoon/src/os2.c' <<'END_OF_FILE'
- X/*----------------------------------------------------------------------------
- X * File : os2.c
- X * Library : typhoon
- X * OS : UNIX, OS/2, DOS
- X * Author : Thomas B. Pedersen
- X *
- X * Copyright (c) 1994 Thomas B. Pedersen. All rights reserved.
- X *
- X * Permission is hereby granted, without written agreement and without
- X * license or royalty fees, to use, copy, modify, and distribute this
- X * software and its documentation for any purpose, provided that the above
- X * copyright notice and the following two paragraphs appear (1) in all
- X * source copies of this software and (2) in accompanying documentation
- X * wherever the programatic interface of this software, or any derivative
- X * of it, is described.
- X *
- X * IN NO EVENT SHALL THOMAS B. PEDERSEN BE LIABLE TO ANY PARTY FOR DIRECT,
- X * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
- X * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF HE HAS BEEN
- X * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- X *
- X * THOMAS B. PEDERSEN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
- X * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- X * A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
- X * BASIS, AND THOMAS B. PEDERSEN HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
- X * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- X *
- X * Description:
- X * Contains functions specific to OS/2.
- X *
- X * Functions:
- X * ty_openlock - Create/open the locking resource.
- X * ty_closelock - Close the locking resource.
- X * ty_lock - Obtain the lock.
- X * ty_unlock - Release the lock.
- X *
- X * $Log: os2.c,v $
- X * Revision 1.1 1994/09/13 21:28:31 tbp
- X * Added to repository.
- X *
- X *
- X *--------------------------------------------------------------------------*/
- X
- Xstatic char rcsid[] = "$Id";
- X
- X#define INCL_NOPMAPI
- X#define INCL_DOSSEMAPHORES
- X#include <os2.h>
- X
- X#define TIMEOUT -1 /* Wait maximum 30 seconds for excl. access */
- X
- X/*---------------------------- Global variables ----------------------------*/
- Xstatic HMTX block_sem; /* Blocking semaphore used by d_block() */
- Xstatic HMTX ty_sem; /* API function semaphore */
- X
- X
- X#ifdef __BORLANDC__
- XULONG _dllmain(ULONG termflag, HMODULE modhandle)
- X#endif
- X#ifdef __IBMC__
- Xvoid _CRT_init(void);
- XULONG _System _DLL_InitTerm(ULONG modhandle, ULONG termflag)
- X#endif
- X{
- X static char fname[] = "\\SEM32\\TYPHOON";
- X
- X switch( termflag )
- X {
- X case 0:
- X#ifdef __IBMC__
- X _CRT_init();
- X#endif
- X if( DosOpenMutexSem(fname, &ty_sem) )
- X if( DosCreateMutexSem(fname, &ty_sem, 0, 0) )
- X return 0;
- X
- X if( DosCreateMutexSem(NULL, &block_sem, 0, 0) )
- X return 0;
- X break;
- X
- X case 1:
- X /* Never release the ty_sem semaphore */
- X DosCloseMutexSem(ty_sem);
- X DosCloseMutexSem(block_sem);
- X break;
- X }
- X
- X return 1;
- X}
- X
- X/*------------------------------ ty_openlock ------------------------------*\
- X *
- X * Purpose : This function ensures that only one instance of a Typhoon
- X * function is active at the time, at least in its critical
- X * section.
- X *
- X * Parameters: None.
- X *
- X * Returns : -1 - Semaphore could not be created.
- X * 0 - Successful.
- X *
- X */
- X
- Xty_openlock()
- X{
- X/*
- X static char fname[] = "\\SEM32\\TYPHOON";
- X
- X if( DosOpenMutexSem(fname, &ty_sem) )
- X if( DosCreateMutexSem(fname, &ty_sem, 0, 0) )
- X return -1;
- X
- X locked = 0;
- X*/
- X return 0;
- X}
- X
- X
- Xty_closelock()
- X{
- X/* DosCloseMutexSem(ty_sem);*/
- X return 0;
- X}
- X
- X
- Xty_lock()
- X{
- X if( DosRequestMutexSem(ty_sem, TIMEOUT) )
- X return -1;
- X
- X return 0;
- X}
- X
- X
- Xty_unlock()
- X{
- X DosReleaseMutexSem(ty_sem);
- X return 0;
- X}
- X
- X
- Xvoid os2_block()
- X{
- X DosRequestMutexSem(block_sem, -1L);
- X}
- X
- X
- Xvoid os2_unblock()
- X{
- X DosReleaseMutexSem(block_sem);
- X}
- X
- X/* end-of-file */
- END_OF_FILE
- if test 3660 -ne `wc -c <'typhoon/src/os2.c'`; then
- echo shar: \"'typhoon/src/os2.c'\" unpacked with wrong size!
- fi
- # end of 'typhoon/src/os2.c'
- fi
- if test -f 'typhoon/src/ty_open.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'typhoon/src/ty_open.c'\"
- else
- echo shar: Extracting \"'typhoon/src/ty_open.c'\" \(13441 characters\)
- sed "s/^X//" >'typhoon/src/ty_open.c' <<'END_OF_FILE'
- X/*----------------------------------------------------------------------------
- X * File : ty_open.c
- X * Library : typhoon
- X * OS : UNIX, OS/2, DOS
- X * Author : Thomas B. Pedersen
- X *
- X * Copyright (c) 1994 Thomas B. Pedersen. All rights reserved.
- X *
- X * Permission is hereby granted, without written agreement and without
- X * license or royalty fees, to use, copy, modify, and distribute this
- X * software and its documentation for any purpose, provided that the above
- X * copyright notice and the following two paragraphs appear (1) in all
- X * source copies of this software and (2) in accompanying documentation
- X * wherever the programatic interface of this software, or any derivative
- X * of it, is described.
- X *
- X * IN NO EVENT SHALL THOMAS B. PEDERSEN BE LIABLE TO ANY PARTY FOR DIRECT,
- X * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
- X * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF HE HAS BEEN
- X * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- X *
- X * THOMAS B. PEDERSEN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
- X * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- X * A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
- X * BASIS, AND THOMAS B. PEDERSEN HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
- X * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- X *
- X * Description:
- X *
- X * Functions:
- X * Contains functions for opening and closing the database.
- X *
- X * $Log: ty_open.c,v $
- X * Revision 1.2 1994/09/17 16:00:19 tbp
- X * typhoon.h and environ.h are now included from <>.
- X *
- X * Revision 1.1 1994/09/13 21:28:36 tbp
- X * Added to repository.
- X *
- X *
- X *--------------------------------------------------------------------------*/
- X
- Xstatic char rcsid[] = "$Id";
- X
- X#ifdef UNIX
- X# include <unistd.h>
- X# include <stdio.h>
- X# ifdef __STDC__
- X# include <stdlib.h>
- X# endif
- X# define DIR_SWITCH '/'
- X#else
- X# include <stdlib.h>
- X# include <io.h>
- X# define DIR_SWITCH '\\'
- X#endif
- X#include <fcntl.h>
- X#include <assert.h>
- X#include <string.h>
- X#include <stdio.h>
- X#include <typhoon.h>
- X#include "ty_dbd.h"
- X#include "ty_type.h"
- X#include "ty_glob.h"
- X#include "ty_prot.h"
- X
- X/*--------------------------- Function prototypes --------------------------*/
- Xstatic void fixpath PRM( (char *, char *); )
- X int read_dbdfile PRM( (Dbentry *, char *); )
- Xstatic int perform_rebuild PRM( (unsigned); )
- X
- X
- Xstatic void (*rebuildverbose_fn) PRM((char *, ulong, ulong);)
- X
- X
- Xstatic void fixpath(path, s)
- Xchar *path, *s;
- X{
- X int len = strlen(s);
- X
- X if( len > 0 )
- X {
- X strcpy(path, s);
- X
- X if( path[len-1] != DIR_SWITCH )
- X {
- X path[len++] = DIR_SWITCH;
- X path[len] = 0;
- X }
- X }
- X else
- X {
- X path[0] = '.';
- X path[1] = DIR_SWITCH;
- X path[2] = 0;
- X }
- X}
- X
- X
- X
- X/*-------------------------------- d_dbdpath -------------------------------*\
- X *
- X * Purpose : Set the path of the dbd-file. This function is called prior
- X * d_open().
- X *
- X * Parameters: path - The path of the dbd-file.
- X *
- X * Returns : S_OKAY - Successful.
- X *
- X */
- X
- X
- XFNCLASS d_dbdpath(path)
- Xchar *path;
- X{
- X fixpath(typhoon.dbdpath, path);
- X
- X return S_OKAY;
- X}
- X
- X
- X
- X/*-------------------------------- d_dbfpath -------------------------------*\
- X *
- X * Purpose : Set the path of the database files. This function is called
- X * prior to d_open().
- X *
- X * Parameters: path - The path of the database files.
- X *
- X * Returns : S_OKAY - Successful.
- X *
- X */
- X
- X
- XFNCLASS d_dbfpath(path)
- Xchar *path;
- X{
- X fixpath(typhoon.dbfpath, path);
- X
- X return S_OKAY;
- X}
- X
- X
- X
- X/*--------------------------------- d_dbget --------------------------------*\
- X *
- X * Purpose : Gets the current database ID.
- X *
- X * Parameters: id - Pointer to database ID.
- X *
- X * Returns : S_OKAY - The database ID is stored in <id>.
- X * S_NOCD - There is no current database.
- X *
- X */
- X
- XFNCLASS d_dbget(id)
- Xint *id;
- X{
- X if( CURR_DB == -1 )
- X RETURN S_NOCD;
- X
- X *id = CURR_DB;
- X
- X RETURN S_OKAY;
- X}
- X
- X
- X
- X/*--------------------------------- d_dbset --------------------------------*\
- X *
- X * Purpose : Sets the current database ID.
- X *
- X * Parameters: id - Database ID obtained by call to d_dbget().
- X *
- X * Returns : S_OKAY - The database ID is stored in <id>.
- X * S_INVDB - Invalid database ID.
- X *
- X */
- X
- XFNCLASS d_dbset(id)
- Xint id;
- X{
- X int i;
- X
- X /* Ensure that the id is valid */
- X if( id < 0 || id >= DB_MAX )
- X RETURN S_INVDB;
- X
- X /* Ensure that the database is actually open */
- X if( typhoon.dbtab[id].clients == 0 )
- X RETURN S_INVDB;
- X
- X DB->db_status = db_status;
- X
- X typhoon.curr_db = id;
- X typhoon.db = typhoon.dbtab + id;
- X
- X db_status = DB->db_status;
- X
- X RETURN S_OKAY;
- X}
- X
- X
- X/*------------------------------- d_setfiles -------------------------------*\
- X *
- X * Purpose : Set the maximum number of open files.
- X *
- X * Parameters: maxfiles - The maximum number of open files allowed.
- X *
- X * Returns : S_OKAY - Ok.
- X * S_INVPARM- The maximum is invalid.
- X *
- X */
- XFNCLASS d_setfiles(maxfiles)
- Xint maxfiles;
- X{
- X if( maxfiles < 2 )
- X RETURN S_INVPARM;
- X
- X if( maxfiles < typhoon.max_open )
- X {
- X /* maxfiles is less than max_open, so we need minimize the number
- X * of open files right away.
- X */
- X int diff = typhoon.max_open - maxfiles;
- X
- X while( typhoon.cur_open > maxfiles && diff-- )
- X ty_closeafile();
- X
- X /* If it was not possible to closed the required number of files
- X * anyway, an error code is returned
- X */
- X if( typhoon.cur_open > maxfiles )
- X RETURN S_INVPARM;
- X }
- X
- X typhoon.max_open = maxfiles;
- X
- X RETURN S_OKAY;
- X}
- X
- X
- X
- XFNCLASS d_keybuild(fn)
- Xvoid (*fn)PRM((char *, ulong, ulong);)
- X{
- X typhoon.do_rebuild = 1;
- X rebuildverbose_fn = fn;
- X}
- X
- X
- Xstatic perform_rebuild(biggest_rec)
- Xunsigned biggest_rec;
- X{
- X ulong recno;
- X ulong recid;
- X ulong datasize;
- X ulong records;
- X char *buf;
- X int fh, i;
- X Record *rec;
- X RECORD filehd;
- X char fname[128];
- X int preamble;
- X int foreign_keys;
- X
- X if( (buf = (void *)malloc(biggest_rec)) == NULL )
- X RETURN S_NOMEM;
- X
- X for( i=0, rec=DB->record; i<DB->header.records; i++, rec++ )
- X {
- X sprintf(fname, "%s%c%s_tmp", DB->dbfpath, DIR_SWITCH,
- X DB->file[rec->fileid].name);
- X
- X fh = os_open(fname, O_RDWR|O_BINARY, 0);
- X read(fh, &filehd.H, sizeof filehd.H);
- X
- X recno = (sizeof(filehd.H) + filehd.H.recsize - 1) / filehd.H.recsize;
- X recid = INTERN_TO_RECID(i);
- X records = lseek(fh, 0, SEEK_END) / filehd.H.recsize;
- X
- X rebuildverbose_fn(rec->name, records, 0);
- X
- X if( rec->first_foreign == -1 )
- X foreign_keys = 0;
- X else
- X foreign_keys = rec->keys - (rec->first_foreign - rec->first_key);
- X preamble= sizeof(long) * foreign_keys + offsetof(RECORDHEAD, data[0]);
- X datasize= filehd.H.recsize - preamble;
- X
- X for( ;; )
- X {
- X lseek(fh, filehd.H.recsize * recno + preamble, SEEK_SET);
- X if( read(fh, buf, datasize) != datasize )
- X break;
- X
- X if( d_fillnew(recid, buf) != S_OKAY )
- X printf("%s: d_fillnew failed\n", rec->name);
- X
- X recno++;
- X
- X rebuildverbose_fn(rec->name, records, recno);
- X }
- X
- X close(fh);
- X unlink(fname);
- X
- X rebuildverbose_fn(rec->name, records, records);
- X }
- X free(buf);
- X
- X RETURN S_OKAY;
- X}
- X
- X
- X
- X/*--------------------------------- d_open ---------------------------------*\
- X *
- X * Purpose : Opens a database of the name <dbname>. The dbd-file is
- X * expected to be in <dbdpath> and the data and index file are
- X * expected to be in (or will be created in) <dbfpath>, set by
- X * d_dbdpath() and d_dbfpath().
- X *
- X * If the database is opened in exclusive or one-user mode the
- X * first file is locked. This will make future calls to d_open()
- X * return S_UNAVAIL.
- X *
- X * Parameters: dbname - Database name.
- X * mode - [s]hared, e[x]clusive or [o]ne user mode.
- X *
- X * Returns : S_OKAY - Database successfully opened.
- X * S_NOTAVAIL - Database is currently not available.
- X * S_NOMEM - Not enough memory to open database.
- X * S_INVDB - Invalid database name.
- X * S_BADTYPE - The mode parmeter was invalid.
- X *
- X */
- X
- XFNCLASS d_open(dbname, mode)
- Xchar *dbname, *mode;
- X{
- X char fname[129];
- X Record *rec;
- X int i, n;
- X unsigned biggest_rec = 0;
- X Dbentry *_db;
- X
- X db_status = S_OKAY;
- X
- X /* Validate the mode parameter */
- X if( *mode != 's' && *mode != 'x' && *mode != 'o' )
- X RETURN_RAP(S_BADTYPE);
- X
- X /* Initialize locking resource */
- X if( ty_openlock() == -1 )
- X RETURN S_FATAL;
- X
- X ty_lock();
- X
- X /* Find an available database slot */
- X for( i=0, _db=typhoon.dbtab; i<DB_MAX; i++, _db++ )
- X if( !_db->clients )
- X break;
- X
- X if( i == DB_MAX )
- X {
- X ty_unlock();
- X RETURN S_NOTAVAIL;
- X }
- X
- X DB = _db;
- X DB->mode = *mode;
- X strcpy(DB->name, dbname);
- X strcpy(DB->dbfpath, typhoon.dbfpath);
- X
- X /* dbd-file is located in <dbdpath> */
- X sprintf(fname, "%s%s.dbd", typhoon.dbdpath, dbname);
- X if( read_dbdfile(DB, fname) != S_OKAY )
- X {
- X ty_unlock();
- X return db_status;
- X }
- X
- X /* Allocate 'current record' buffer (add room for record numbers of
- X * parent records (one per foreign key)
- X */
- X for( i=0, rec=DB->record; i<DB->header.records; i++, rec++ )
- X {
- X if( rec->first_foreign == -1 )
- X n = rec->size;
- X else
- X n = rec->size + (rec->keys - (rec->first_foreign - rec->first_key))
- X * sizeof(ulong);
- X
- X if( n > biggest_rec )
- X biggest_rec = n;
- X }
- X
- X if( (DB->real_recbuf = (char *)malloc(biggest_rec)) == NULL )
- X {
- X ty_unlock();
- X free(DB->dbd);
- X RETURN S_NOMEM;
- X }
- X
- X if( shm_alloc(DB) == -1 )
- X {
- X ty_unlock();
- X free(DB->dbd);
- X return S_NOMEM;
- X }
- X
- X /* The database cannot be opened during a restore (except for rebuild) */
- X if( DB->shm->restore_active && !typhoon.do_rebuild )
- X {
- X ty_unlock();
- X free(DB->dbd);
- X shm_free(DB);
- X RETURN S_NOTAVAIL;
- X }
- X
- X DB->recbuf = DB->real_recbuf;
- X DB->clients++;
- X
- X /* If the indices should be rebuilt we'll remove them first */
- X if( typhoon.do_rebuild )
- X {
- X char fname[256];
- X char new_fname[256];
- X
- X for( i=0; i<DB->header.files; i++ )
- X if( DB->file[i].type == 'k' )
- X {
- X sprintf(fname, "%s%c%s", typhoon.dbfpath, DIR_SWITCH, DB->file[i].name);
- X unlink(fname);
- X }
- X else
- X {
- X sprintf(fname, "%s%c%s", typhoon.dbfpath, DIR_SWITCH, DB->file[i].name);
- X sprintf(new_fname, "%s_tmp", fname);
- X unlink(new_fname);
- X rename(fname, new_fname);
- X }
- X }
- X
- X /* Before opening the database we mark all file handles are closed */
- X for( i=0; i<DB->header.files; i++ )
- X DB->fh[i].any = NULL;
- X
- X /* Open all the database files */
- X for( i=0; i<DB->header.files && db_status == S_OKAY; i++ )
- X ty_openfile(DB->file + i, DB->fh + i, *mode == 's');
- X
- X /* Roll back if a file could not be opened */
- X if( db_status != S_OKAY )
- X {
- X i--;
- X while( i-- )
- X ty_closefile(DB->fh + i);
- X
- X DB->clients--;
- X CURR_DB = -1;
- X shm_free(DB);
- X free(DB->real_recbuf);
- X free(DB->dbd);
- X ty_unlock();
- X RETURN db_status;
- X }
- X
- X CURR_DB = _db - typhoon.dbtab;
- X CURR_REC = 0;
- X CURR_RECID = 0;
- X CURR_BUFREC = 0;
- X CURR_BUFRECID = 0;
- X
- X if( typhoon.do_rebuild )
- X {
- X perform_rebuild(biggest_rec);
- X typhoon.do_rebuild = 0;
- X }
- X
- X typhoon.dbs_open++;
- X ty_unlock();
- X
- X /* Return the status of the last db_open command */
- X return db_status;
- X}
- X
- X
- X
- X/*--------------------------------- d_close --------------------------------*\
- X *
- X * Purpose : Close the current database.
- X *
- X * Parameters: None.
- X *
- X * Returns : S_NOCD - No current database.
- X * S_OKAY - Database successfully closed.
- X *
- X */
- X
- XFNCLASS d_close()
- X{
- X int i;
- X
- X if( CURR_DB == -1 )
- X RETURN_RAP(S_NOCD);
- X
- X DB->clients--;
- X
- X for( i=0; i<DB->header.files; i++ )
- X ty_closefile(DB->fh + i);
- X
- X /* If there is currently a transaction active the transaction counter
- X * in shared memory must be decremented.
- X */
- X d_abortwork();
- X
- X shm_free(DB);
- X FREE(DB->dbd);
- X FREE(DB->real_recbuf);
- X
- X CURR_DB = -1;
- X CURR_REC = 0;
- X
- X if( !--typhoon.dbs_open )
- X ty_closelock();
- X
- X RETURN S_OKAY;
- X}
- X
- X
- X
- X/*-------------------------------- d_destroy -------------------------------*\
- X *
- X * Purpose : Destroy a database.
- X *
- X * Parameters: dbname - Database name.
- X *
- X * Returns : S_NOMEM - Not enough memory to open database and destroy.
- X * S_INVDB - Invalid database name.
- X * S_OKAY - Database successfully closed.
- X * S_NOTAVAIL - The database is already opened in non-shared
- X * mode.
- X *
- X *
- X * INSERT LOCK CHECK HERE!!!!!
- X *
- X *
- X */
- X
- XFNCLASS d_destroy(dbname)
- Xchar *dbname;
- X{
- X int i, dbdfile;
- X char fname[80];
- X Header header;
- X File *file;
- X Dbentry *_db = typhoon.dbtab;
- X
- X ty_lock();
- X
- X for( i=0; i<DB_MAX; i++, _db++ ) /* Find database name in table */
- X if( !strcmp(_db->name, dbname) )
- X break;
- X
- X if( i == DB_MAX )
- X { /* Database currently not open */
- X sprintf(fname, "%s%s.dbd", typhoon.dbdpath, dbname);
- X
- X if( (dbdfile = open(fname, O_BINARY|O_RDONLY)) == -1 )
- X {
- X ty_unlock();
- X RETURN S_INVDB; /* Database name not found */
- X }
- X read(dbdfile, &header, sizeof header);
- X
- X if( !(file = (File *)malloc(sizeof(File) * header.files)) )
- X {
- X close(dbdfile);
- X ty_unlock();
- X RETURN S_NOMEM;
- X }
- X
- X read(dbdfile, file, sizeof(File) * header.files);
- X close(dbdfile);
- X
- X for( i=0; i < header.files; i++ ) /* Now remove all files */
- X unlink(file[i].name);
- X
- X ty_unlock();
- X RETURN S_OKAY;
- X }
- X
- X /*---------- Destroy current database ----------------------------------*/
- X for( i=0; i<DB->header.files; i++ )
- X {
- X ty_closefile(DB->fh + i); /* Close all database files */
- X unlink(DB->file[i].name); /* and remove them */
- X }
- X
- X FREE(DB->dbd);
- X
- X _db->clients = 0;
- X CURR_DB = -1;
- X CURR_REC = 0;
- X
- X ty_unlock();
- X RETURN S_OKAY;
- X}
- X
- X/* end-of-file */
- END_OF_FILE
- if test 13441 -ne `wc -c <'typhoon/src/ty_open.c'`; then
- echo shar: \"'typhoon/src/ty_open.c'\" unpacked with wrong size!
- fi
- # end of 'typhoon/src/ty_open.c'
- fi
- if test -f 'typhoon/src/util/backup.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'typhoon/src/util/backup.c'\"
- else
- echo shar: Extracting \"'typhoon/src/util/backup.c'\" \(12068 characters\)
- sed "s/^X//" >'typhoon/src/util/backup.c' <<'END_OF_FILE'
- X/*----------------------------------------------------------------------------
- X * File : backup.c
- X * Program : tybackup
- X * OS : UNIX, OS/2, DOS
- X * Author : Thomas B. Pedersen
- X *
- X * Copyright (c) 1994 Thomas B. Pedersen. All rights reserved.
- X *
- X * Permission is hereby granted, without written agreement and without
- X * license or royalty fees, to use, copy, modify, and distribute this
- X * software and its documentation for any purpose, provided that the above
- X * copyright notice and the following two paragraphs appear (1) in all
- X * source copies of this software and (2) in accompanying documentation
- X * wherever the programatic interface of this software, or any derivative
- X * of it, is described.
- X *
- X * IN NO EVENT SHALL THOMAS B. PEDERSEN BE LIABLE TO ANY PARTY FOR DIRECT,
- X * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
- X * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF HE HAS BEEN
- X * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- X *
- X * THOMAS B. PEDERSEN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
- X * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- X * A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
- X * BASIS, AND THOMAS B. PEDERSEN HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
- X * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- X *
- X * Description:
- X * Contains the tybackup utility.
- X *
- X * Functions:
- X *
- X * $Log: backup.c,v $
- X * Revision 1.2 1994/09/17 16:00:49 tbp
- X * typhoon.h and environ.h are now included from <>.
- X *
- X * Revision 1.1 1994/09/13 21:28:50 tbp
- X * Added to repository.
- X *
- X * Added to repository.
- X *
- X *
- X *--------------------------------------------------------------------------*/
- X
- Xstatic char rcsid[] = "$Id: backup.c,v 1.2 1994/09/17 16:00:49 tbp Exp $";
- X
- X#include <sys/types.h>
- X#include <sys/ipc.h>
- X#include <sys/shm.h>
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <string.h>
- X#include <fcntl.h>
- X#include <time.h>
- X#include <setjmp.h>
- X#include <errno.h>
- X#include <assert.h>
- X#include <signal.h>
- X#include <typhoon.h>
- X#include "../ty_dbd.h"
- X#include "../ty_type.h"
- X#include "../ty_glob.h"
- X#include "../ty_prot.h"
- X#include "../ty_log.h"
- X#include "util.h"
- X
- X/*------------------------------- Constants --------------------------------*/
- X#define VERSION "1.00"
- X#define BLOCK_SIZE 512
- X#define OUTBUF_SIZE (BLOCK_SIZE * 512)
- X#define INBUF_SIZE (64 * 1024)
- X
- X/*-------------------------- Function prototypes ---------------------------*/
- Xstatic void SignalHandler PRM( (int); )
- Xstatic void Write PRM( (void *, ulong); )
- Xstatic void Flush PRM( (void); )
- Xstatic void DisplayProgress PRM( (char *, ulong); )
- Xstatic void BackupDatabase PRM( (void); )
- Xstatic void BackupFile PRM( (char *); )
- Xstatic void help PRM( (void); )
- X
- X/*---------------------------- Global variables ----------------------------*/
- Xstatic ArchiveMediaHeader mediahd; /* Archive media header */
- Xstatic jmp_buf err_jmpbuf; /* Jumped to on error */
- Xstatic Dbentry dbd; /* DBD anchor */
- Xstatic int verbose = 0; /* Be verbose? */
- Xstatic int archive_fh = -1; /* Archive file handle */
- Xstatic char *dbname = ""; /* Database name */
- Xstatic char *datapath = ""; /* Path for database files */
- Xstatic char *device = "/dev/null"; /* Backup device */
- Xstatic char *outbuf; /* Output buffer */
- Xstatic ulong outbytes; /* Number of bytes in outbuf */
- Xstatic ulong total_written = 0; /* Total number of bytes written */
- X int db_status; /* Required by ../read_dbd.c */
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : SignalHandler
- X *
- X * Purpose :
- X *
- X * Parameters:
- X *
- X * Returns :
- X *
- X */
- Xstatic void SignalHandler(sig)
- Xint sig;
- X{
- X if( sig == SIGSEGV )
- X puts("Segmentation violation");
- X else if( sig == SIGBUS )
- X puts("Bus error");
- X
- X dbd.shm->backup_active = 0;
- X shm_free(&dbd);
- X unlink(LOG_FNAME);
- X puts("Restore aborted.");
- X exit(1);
- X}
- X
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : Write
- X *
- X * Purpose : Write a block of data to the archive. If data cannot be
- X * written because the backup media is full, the user will
- X * be prompted to insert a new media.
- X *
- X * Parameters: buf - Buffer to write.
- X * size - Number of bytes in buffer.
- X *
- X * Returns : Nothing.
- X *
- X */
- Xstatic void Write(buf, size)
- Xvoid *buf;
- Xulong size;
- X{
- X ArchiveBlockHeader blockhd;
- X char s[20];
- X ulong copymax;
- X long rc;
- X
- X /* Copy as much as possible to the output buffer */
- X copymax = size;
- X if( copymax > OUTBUF_SIZE-outbytes )
- X copymax = OUTBUF_SIZE-outbytes;
- X
- X memcpy(outbuf+outbytes, buf, copymax);
- X outbytes += copymax;
- X
- Xretry:
- X while( archive_fh == -1 )
- X {
- X clock_off();
- X printf("Insert backup media no %d [enter, q]", mediahd.seqno);
- X fflush(stdout);
- X gets(s);
- X clock_on();
- X
- X if( s[0] == 'q' )
- X return;
- X
- X if( (archive_fh = open(device, O_WRONLY)) == -1 )
- X printf("Cannot open '%s' (errno %d)\n", device, errno);
- X }
- X
- X if( outbytes == OUTBUF_SIZE )
- X {
- X rc = write(archive_fh, outbuf, OUTBUF_SIZE);
- X
- X if( rc == -1 )
- X {
- X printf("Write error (errno %d)\n", errno);
- X longjmp(err_jmpbuf, 1);
- X }
- X else if( rc != OUTBUF_SIZE )
- X {
- X close(archive_fh);
- X goto retry;
- X }
- X
- X /* Now copy the rest of the buffer */
- X outbytes = size - copymax;
- X memcpy(outbuf, (char *)buf + copymax, outbytes);
- X
- X total_written += rc;
- X }
- X}
- X
- X
- Xstatic void Flush()
- X{
- X long rc;
- X
- X /* Ensure that a complete block is written to archive */
- X outbytes += (BLOCK_SIZE - (outbytes % BLOCK_SIZE));
- X
- X if( (rc = write(archive_fh, outbuf, outbytes)) != outbytes )
- X {
- X printf("Write error (errno %d, rc %ld)\n", errno, rc);
- X longjmp(err_jmpbuf, 1);
- X }
- X
- X total_written += rc;
- X outbytes = 0;
- X}
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : DisplayProgress
- X *
- X * Purpose : Prints the number of bytes read so far from the current table.
- X *
- X * Parameters: table - Table name.
- X * bytes - Number of bytes read.
- X *
- X * Returns : Nothing.
- X *
- X */
- Xstatic void DisplayProgress(table, bytes)
- Xchar *table;
- Xulong bytes;
- X{
- X printf("\rReading %-26.26s %10s bytes", table, printlong(bytes));
- X fflush(stdout);
- X}
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : BackupDatabase
- X *
- X * Purpose : Controls the backup.
- X *
- X * Parameters: None.
- X *
- X * Returns : Nothing.
- X *
- X */
- Xstatic void BackupDatabase()
- X{
- X ArchiveRecordHeader recordhd;
- X ArchiveTableHeader tablehd;
- X Record *rec;
- X ulong recid; /* Record ID of current table */
- X ulong recno; /* Current record in current table */
- X ulong recsize; /* Record size in current table */
- X ulong bytecount; /* Number of bytes read in current table*/
- X ulong numread; /* Number of bytes read */
- X ulong timeout;
- X int fh;
- X int maxread, i, rc;
- X char fname[128], objname[128];
- X char buf[INBUF_SIZE];
- X RECORD filehd;
- X
- X dbd.shm->backup_active = 1;
- X
- X for( rec=dbd.record, recid=0; recid<dbd.header.records; recid++, rec++ )
- X {
- X dbd.shm->curr_recid = recid;
- X
- X sprintf(fname, "%s/%s", datapath, dbd.file[rec->fileid].name);
- X sprintf(objname, "table %s", rec->name);
- X
- X if( (fh = os_open(fname, O_RDONLY|O_BINARY, 0)) == -1 )
- X {
- X printf("Cannot open '%s'\n", fname);
- X return;
- X }
- X
- X /* Because of referential integrity data, the record size may
- X * be different from rec->size, so we read the header for H.recsize.
- X */
- X read(fh, &filehd.H, sizeof filehd.H);
- X
- X recsize = filehd.H.recsize;
- X maxread = INBUF_SIZE / recsize;
- X bytecount = 0;
- X recno = 0;
- X
- X /* Write table header */
- X strcpy(tablehd.fname, dbd.file[rec->fileid].name);
- X strcpy(tablehd.table, rec->name);
- X tablehd.id = ARCHIVE_TABLE;
- X tablehd.recsize = recsize;
- X Write(&tablehd, sizeof tablehd);
- X
- X if( verbose )
- X DisplayProgress(objname, 0);
- X
- X do
- X {
- X for( i=0; i<maxread; i++ )
- X {
- X dbd.shm->curr_recno = recno;
- X
- X lseek(fh, recno * recsize, SEEK_SET);
- X numread = read(fh, buf, recsize);
- X
- X if( numread != recsize )
- X break;
- X
- X recordhd.id = ARCHIVE_RECORD;
- X recordhd.recid = recid;
- X recordhd.recno = recno;
- X
- X Write(&recordhd, sizeof recordhd);
- X Write(buf, numread);
- X
- X bytecount += recsize;
- X recno++;
- X }
- X
- X if( verbose )
- X DisplayProgress(objname, bytecount);
- X }
- X while( i == maxread );
- X
- X if( verbose )
- X puts("");
- X
- X close(fh);
- X }
- X
- X /* Set curr_recid to max value, so that all changes are logged */
- X dbd.shm->curr_recid = 0xffffffff;
- X dbd.shm->backup_active = 0;
- X
- X /* Wait for last transaction to complete */
- X timeout = 120;
- X while( dbd.shm->num_trans_active > 0 && timeout-- )
- X sleep(1);
- X}
- X
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : BackupFile
- X *
- X * Purpose : Write a sequential file to archive.
- X *
- X * Parameters: fname - File name.
- X *
- X * Returns : Nothing.
- X *
- X */
- Xstatic void BackupFile(fname)
- Xchar *fname;
- X{
- X ArchiveFileHeader filehd;
- X ArchiveFileDataHeader datahd;
- X int fh;
- X char buf[INBUF_SIZE];
- X ulong numread;
- X ulong bytecount=0;
- X
- X if( (fh = open(fname, O_RDONLY)) == -1 )
- X {
- X printf("Cannot open '%s'\n", fname);
- X return;
- X }
- X
- X datahd.id = ARCHIVE_FILEDATA;
- X filehd.id = ARCHIVE_FILE;
- X strcpy(filehd.fname, fname);
- X Write(&filehd, sizeof filehd);
- X
- X while( numread = read(fh, buf, INBUF_SIZE) )
- X {
- X datahd.size = numread;
- X Write(&datahd, sizeof datahd);
- X Write(buf, numread);
- X
- X bytecount += numread;
- X
- X if( verbose )
- X DisplayProgress(fname, bytecount);
- X }
- X
- X datahd.size = 0;
- X Write(&datahd, sizeof datahd);
- X
- X if( verbose )
- X puts("");
- X
- X close(fh);
- X}
- X
- X
- X
- X
- Xstatic void help()
- X{
- X puts("Syntax: tybackup database [option]...\n"
- X "Options:\n"
- X " -d<device> Backup device\n"
- X " -f<path> Path for data files\n"
- X " -v Be verbose\n");
- X exit(1);
- X}
- X
- X
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X ArchiveEnd end;
- X char dbdname[20];
- X int i;
- X
- X /* The output buffer MUST be bigger than the input buffer */
- X assert(INBUF_SIZE < OUTBUF_SIZE);
- X
- X printf("Typhoon Online Backup version %s\n", VERSION);
- X
- X if( argc < 3 )
- X help();
- X
- X for( i=2; i<argc; i++ )
- X {
- X switch( *argv[i] )
- X {
- X case '-':
- X case '/':
- X switch( argv[i][1] )
- X {
- X case 'd':
- X device = argv[i]+2;
- X break;
- X case 'f':
- X datapath = argv[i]+2;
- X break;
- X case 'v':
- X verbose = 1;
- X break;
- X default:
- X printf("Invalid option '%c'\n", argv[i][1]);
- X break;
- X }
- X break;
- X default:
- X printf("Invalid switch '%c'\n", *argv[i]);
- X exit(1);
- X }
- X }
- X
- X dbname = argv[1];
- X sprintf(dbdname, "%s.dbd", dbname);
- X if( read_dbdfile(&dbd, dbdname) != S_OKAY )
- X {
- X printf("Invalid dbd-file '%s'\n", dbdname);
- X return;
- X }
- X
- X if( !(outbuf = (char *)malloc(OUTBUF_SIZE)) )
- X {
- X puts("Cannot allocate output buffer");
- X return;
- X }
- X outbytes = 0;
- X
- X strcpy(dbd.name, dbname);
- X if( shm_alloc(&dbd) == -1 )
- X {
- X printf("Cannot allocate shared memory");
- X return;
- X }
- X
- X signal(SIGINT, SignalHandler);
- X signal(SIGTERM, SignalHandler);
- X signal(SIGQUIT, SignalHandler);
- X signal(SIGSEGV, SignalHandler);
- X signal(SIGBUS, SignalHandler);
- X signal(SIGHUP, SIG_IGN);
- X
- X if( setjmp(err_jmpbuf) )
- X {
- X if( verbose )
- X puts("Backup aborted.");
- X goto out;
- X }
- X
- X /* Initialize media header */
- X memset(&mediahd, 0, sizeof mediahd);
- X strcpy(mediahd.dbname, dbname);
- X mediahd.id = ARCHIVE_MEDIA;
- X mediahd.date = time(NULL);
- X mediahd.seqno = 1;
- X
- X if( verbose )
- X printf("Backing up to %s\n", device);
- X
- X Write(&mediahd, sizeof mediahd);
- X
- X BackupFile(dbdname);
- X BackupDatabase();
- X BackupFile(LOG_FNAME);
- X
- X end.id = ARCHIVE_END;
- X Write(&end, sizeof end);
- X Flush();
- X close(archive_fh);
- X clock_off();
- X
- X if( verbose )
- X {
- X ulong secs = clock_secs();
- X
- X /* Guard against division by zero */
- X if( !secs )
- X secs = 1;
- X
- X printf("\rTotal %40s bytes\n", printlong(total_written));
- X printf("%s bytes/second\n", printlong(total_written / secs));
- X puts("Done.");
- X }
- X
- Xout:
- X free(outbuf);
- X shm_free(&dbd);
- X free(dbd.dbd);
- X
- X unlink(LOG_FNAME);
- X
- X return 0;
- X}
- X
- X/* end-of-file */
- END_OF_FILE
- if test 12068 -ne `wc -c <'typhoon/src/util/backup.c'`; then
- echo shar: \"'typhoon/src/util/backup.c'\" unpacked with wrong size!
- fi
- # end of 'typhoon/src/util/backup.c'
- fi
- if test -f 'typhoon/src/util/import.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'typhoon/src/util/import.c'\"
- else
- echo shar: Extracting \"'typhoon/src/util/import.c'\" \(12523 characters\)
- sed "s/^X//" >'typhoon/src/util/import.c' <<'END_OF_FILE'
- X/*----------------------------------------------------------------------------
- X * File : import.c
- X * Program : tyimport
- X * OS : UNIX, OS/2, DOS
- X * Author : Thomas B. Pedersen
- X *
- X * Copyright (c) 1994 Thomas B. Pedersen. All rights reserved.
- X *
- X * Permission is hereby granted, without written agreement and without
- X * license or royalty fees, to use, copy, modify, and distribute this
- X * software and its documentation for any purpose, provided that the above
- X * copyright notice and the following two paragraphs appear (1) in all
- X * source copies of this software and (2) in accompanying documentation
- X * wherever the programatic interface of this software, or any derivative
- X * of it, is described.
- X *
- X * IN NO EVENT SHALL THOMAS B. PEDERSEN BE LIABLE TO ANY PARTY FOR DIRECT,
- X * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
- X * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF HE HAS BEEN
- X * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- X *
- X * THOMAS B. PEDERSEN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
- X * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- X * A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
- X * BASIS, AND THOMAS B. PEDERSEN HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
- X * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- X *
- X * Description:
- X * Typhoon import utility.
- X *
- X * $Log: import.c,v $
- X * Revision 1.2 1994/09/17 16:00:55 tbp
- X * typhoon.h and environ.h are now included from <>.
- X *
- X * Revision 1.1 1994/09/13 21:28:58 tbp
- X * Added to repository.
- X *
- X * Added to repository.
- X *
- X *
- X *--------------------------------------------------------------------------*/
- X
- Xstatic char rcsid[] = "$Id: import.c,v 1.2 1994/09/17 16:00:55 tbp Exp $";
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include <fcntl.h>
- X#include <stdarg.h>
- X#ifndef UNIX
- X# include <sys\types.h>
- X# include <sys\stat.h>
- X# include <stdlib.h>
- X# include <io.h>
- X#endif
- X#define DEFINE_GLOBALS
- X#include <typhoon.h>
- X#include "../ty_dbd.h"
- X#include "../ty_type.h"
- X#include "import.h"
- X
- X#define DEBUG(x)
- X
- X
- X/*-------------------------------- prototypes ------------------------------*/
- Xstatic int ReadValue PRM( (int); )
- Xstatic int ReadString PRM( (void); )
- Xstatic int ReadChar PRM( (void); )
- Xstatic int ReadField PRM( (Field *, unsigned); )
- Xstatic int GetControlField PRM( (Structdef *, unsigned); )
- Xstatic int ReadFields PRM( (Structdef *, int, unsigned, int); )
- Xstatic void Import PRM( (char *); )
- X int yyparse PRM( (void); )
- Xstatic void import_error PRM( (char * ELLIPSIS); )
- X
- X/*------------------------------ public variables --------------------------*/
- X FILE *lex_file;
- Xstatic FILE *infile;
- Xstatic char *recbuf;
- Xstatic char *fldptr;
- Xstatic int fldtype;
- Xstatic int lineno;
- Xstatic char import_fname[256];
- X
- X/*------------------------------ local variables ---------------------------*/
- Xstatic char paramhelp[] = "\
- XSyntax: tyimport [option]... database[.dbd]\n\
- XOptions:\n\
- X -f<path> Specify data files path\n\
- X -g Generate import specification\n";
- X
- X
- X
- Xistrcmp(s1, s2)
- Xchar *s1, *s2;
- X{
- X while( tolower(*s1) == tolower(*s2) && *s1 && *s2 )
- X s1++, s2++;
- X
- X return tolower(*s1) - tolower(*s2);
- X}
- X
- X
- X#ifdef PROTOTYPES
- Xvoid err_quit(char *s, ...)
- X#else
- Xvoid err_quit(s)
- Xchar *s;
- X#endif
- X{
- X va_list ap;
- X
- X va_start(ap, s);
- X vfprintf(stderr, s, ap);
- X puts("");
- X va_end(ap);
- X exit(1);
- X}
- X
- X
- X#ifdef PROTOTYPES
- Xvoid import_error(char *fmt, ...)
- X#else
- Xvoid import_error(fmt ELLIPSIS)
- Xchar *fmt;
- X#endif
- X{
- X va_list ap;
- X
- X printf("%s %d: ", import_fname, lineno);
- X va_start(ap, fmt);
- X vprintf(fmt, ap);
- X puts("");
- X va_end(ap);
- X errors++;
- X}
- X
- X
- X
- X/* Floats not supported!!! */
- X
- Xstatic ReadValue(c)
- Xint c;
- X{
- X /* Integer formats: 002 (octal) 0x29 (hex) 231 (decimal) */
- X ulong value;
- X int negate = 0;
- X
- X if( c == '-' )
- X {
- X negate = 1;
- X c = getc(infile);
- X }
- X
- X if( c == '0' )
- X {
- X value = 0;
- X
- X c = getc(infile);
- X
- X if( c == 'x' )
- X {
- X while( (c = getc(infile)) && isxdigit(c) )
- X {
- X if( isdigit(c) )
- X value = value * 16 + c - '0';
- X else
- X value = value * 16 + 6 + tolower(c) - 'a';
- X }
- X ungetc(c, infile);
- X }
- X else if( isdigit(c) )
- X {
- X do
- X {
- X value = value * 8 + c - '0';
- X c = getc(infile);
- X }
- X while( isdigit(c) );
- X ungetc(c, infile);
- X }
- X else
- X ungetc(c, infile);
- X }
- X else
- X {
- X value = c - '0';
- X
- X c = getc(infile);
- X
- X while( isdigit(c) )
- X {
- X value = value * 10 + c - '0';
- X c = getc(infile);
- X }
- X
- X/*
- X do
- X {
- X value = value * 10 + c - '0';
- X c = getc(infile);
- X }
- X while( isdigit(c) );*/
- X ungetc(c, infile);
- X }
- X
- X if( fldtype & FT_UNSIGNED )
- X {
- X switch( fldtype )
- X {
- X case FT_UNSIGNED|FT_CHAR: *(uchar *)fldptr = value; break;
- X case FT_UNSIGNED|FT_SHORT: *(ushort *)fldptr = value; break;
- X case FT_UNSIGNED|FT_INT: *(unsigned *)fldptr = value; break;
- X case FT_UNSIGNED|FT_LONG: *(ulong *)fldptr = value; break;
- X }
- X
- X DEBUG( printf("%lu \n", (ulong)value); )
- X }
- X else
- X {
- X long svalue = negate ? -value : value;
- X
- X switch( fldtype )
- X {
- X case FT_CHAR: *(char *)fldptr = svalue; break;
- X case FT_SHORT: *(short *)fldptr = svalue; break;
- X case FT_INT: *(int *)fldptr = svalue; break;
- X case FT_LONG: *(long *)fldptr = svalue; break;
- X case FT_FLOAT:
- X case FT_DOUBLE: puts("floats not supported"); exit(1);
- X }
- X
- X DEBUG( printf("%ld \n", (long)value); )
- X }
- X
- X return 0;
- X}
- X
- X
- X
- X/* check for max length */
- X
- Xstatic ReadString()
- X{
- X char *p = fldptr;
- X int c;
- X
- X while( (*p = getc(infile)) != '"' )
- X {
- X if( *p == '\\' )
- X {
- X switch( c = getc(infile) )
- X {
- X case 'n': /* Newline */
- X *p = '\n';
- X break;
- X case '\\': /* Backslash */
- X *p = '\\';
- X break;
- X case '\"': /* Double-quote */
- X *p = '"';
- X break;
- X case 'x': /* Hexadecimal number */
- X case 'X':
- X c = getc(infile);
- X if( isxdigit(c) )
- X {
- X *p = isalpha(c) ? tolower(c) - 'a' + 10 : c - '0';
- X c = getc(infile);
- X if( isxdigit(c) )
- X {
- X *p <<= 4;
- X *p += isalpha(c) ? tolower(c) - 'a' + 10 : c - '0';
- X }
- X else
- X ungetc(c, infile);
- X }
- X/* *p = 0;
- X c = getc(infile);
- X
- X while( isxdigit(c) )
- X {
- X if( isdigit(c) )
- X *p = *p * 16 + c - '0';
- X else
- X *p = *p * 16 + 10 + tolower(c) - 'a';
- X c = getc(infile);
- X }
- X
- X ungetc(c, infile);*/
- X break;
- X default:
- X import_error("illegal character '%c' following '\\'", c);
- X break;
- X }
- X }
- X
- X p++;
- X }
- X *p = 0;
- X
- X DEBUG( printf("\"%s\"\n", fldptr); )
- X
- X return 0;
- X}
- X
- X
- Xstatic ReadChar()
- X{
- X int c = getc(infile);
- X int value, tmp;
- X
- X if( c == '\\' )
- X {
- X switch( tmp = getc(infile) )
- X {
- X case 'n': value = '\n'; break;
- X case 'r': value = '\r'; break;
- X case 't': value = '\t'; break;
- X case '\"':
- X case '\\':
- X case '\'': value = tmp; break;
- X case 'x':
- X c = getc(infile);
- X value = 0;
- X
- X while( isxdigit(c) )
- X {
- X if( isdigit(c) )
- X value = value * 16 + c - '0';
- X else
- X value = value * 16 + 10 + tolower(c) - 'a';
- X c = getc(infile);
- X }
- X
- X ungetc(c, infile);
- X break;
- X default:
- X import_error("invalid character constant");
- X return -1;
- X }
- X }
- X else
- X value = c;
- X
- X if( getc(infile) != '\'' )
- X import_error("unterminated character constant");
- X
- X switch( FT_GETBASIC(fldtype) )
- X {
- X case FT_CHAR: *(char *)fldptr = value; break;
- X case FT_INT: *(int *)fldptr = value; break;
- X case FT_SHORT: *(short *)fldptr = value; break;
- X case FT_LONG: *(long *)fldptr = value; break;
- X }
- X
- X DEBUG( printf("'%c'\n", value); )
- X
- X return 0;
- X}
- X
- X
- Xstatic ReadField(fld, offset)
- XField *fld;
- Xunsigned offset;
- X{
- X int c;
- X
- X fldptr = recbuf + offset;
- X fldtype = FT_GETBASIC(fld->type);
- X
- X for( ;; )
- X {
- X c = getc(infile);
- X
- X if( c == ' ' || c == '\t' || c == '{' || c == '}' || c == ',' )
- X ;
- X else if( isdigit(c) || c == '-' )
- X return ReadValue(c);
- X else if( c == '"' )
- X return ReadString();
- X else if( c == '\'' )
- X return ReadChar();
- X else if( c == '\n' )
- X lineno++;
- X else if( c == '/' )
- X {
- X if( (c = getc(infile)) == '*' ) /* C comment */
- X lex_skip_comment();
- X else if( c == '/' ) /* C++ comment */
- X {
- X while( getc(infile) != '\n' && !feof(infile) )
- X ;
- X lineno++;
- X }
- X else
- X import_error("unexpected '/'\n");
- X }
- X else if( c == EOF )
- X return -1;
- X else
- X import_error("unexpected '%c'\n", c);
- X }
- X}
- X
- X
- X
- Xstatic GetControlField(str, offset)
- XStructdef *str;
- Xunsigned offset;
- X{
- X return recbuf[offset + dbd.field[str->control_field].offset];
- X}
- X
- X
- X
- Xstatic ReadFields(str, nest, offset, control_value)
- XStructdef *str;
- Xint nest;
- Xunsigned offset;
- X{
- X Field *fld = dbd.field + str->first_member;
- X int fields = str->members;
- X int old_fields = fields;
- X int i, n, rc;
- X
- X if( str->is_union )
- X fld += control_value;
- X
- X while( fields-- )
- X {
- X if( fld->size != fld->elemsize && FT_GETBASIC(fld->type) != FT_CHARSTR )
- X {
- X if( fld->type & FT_VARIABLE )
- X n = *(ushort *)(recbuf + dbd.field[ fld->keyid ].offset);
- X else
- X n = fld->size / fld->elemsize;
- X }
- X else
- X n = 1;
- X
- X for( i=0; i<n; i++ )
- X {
- X if( FT_GETBASIC(fld->type) == FT_STRUCT )
- X {
- X Structdef *struc = dbd.structdef + fld->structid;
- X
- X rc = ReadFields(struc, nest+1,
- X offset + fld->offset + i * fld->elemsize,
- X struc->is_union ? GetControlField(struc, offset) : 0);
- X }
- X else if( fld->nesting == nest && fld->type & FT_INCLUDE )
- X {
- X DEBUG( printf("%s = ", fld->name); )
- X
- X if( ReadField(fld, offset + fld->offset + fld->elemsize * i) == -1 )
- X return -1;
- X }
- X }
- X
- X /* If n was 0 this array was a variable length array of size 0.
- X * Move fld to the next field at the same nesting.
- X */
- X if( n == 0 )
- X {
- X rc = 0;
- X
- X if( !fields )
- X break;
- X
- X do
- X rc++;
- X while( fld[rc].nesting != fld->nesting );
- X rc--;
- X }
- X
- X if( FT_GETBASIC(fld->type) == FT_STRUCT )
- X {
- X old_fields += rc;
- X fld += rc;
- X }
- X
- X fld++;
- X
- X if( str->is_union )
- X break;
- X }
- X
- X return old_fields;
- X}
- X
- X
- Xstatic void ImportTable(recid)
- Xulong recid;
- X{
- X Record *rec = &dbd.record[recid];
- X ulong count=0;
- X
- X recid = INTERN_TO_RECID(recid);
- X
- X memset(recbuf, 0, rec->size);
- X
- X while( ReadFields(&dbd.structdef[rec->structid], 0, 0, 0) != -1 )
- X {
- X if( d_fillnew(recid, recbuf) != S_OKAY )
- X printf("d_fillnew: db_status %d, db_subcode %d\n",
- X db_status, db_subcode);
- X memset(recbuf, 0, rec->size);
- X
- XDEBUG( puts(""); )
- X }
- X}
- X
- X
- Xstatic void Import(dbname)
- Xchar *dbname;
- X{
- X int i;
- X
- X if( d_open(dbname, "s") != S_OKAY )
- X err_quit("Cannot open database '%s'", dbname);
- X
- X for( i=0; i<dbd.header.records; i++ )
- X {
- X if( dbd.record[i].aux )
- X {
- X lineno = 1;
- X sprintf(import_fname, "%s.kom", dbd.record[i].name);
- X
- X if( !(infile = fopen(import_fname, "r")) )
- X err_quit("Cannot open '%s'", import_fname);
- X
- X printf("importing from '%s'\n", import_fname);
- X ImportTable(i);
- X fclose(infile);
- X }
- X }
- X
- X d_close();
- X}
- X
- X
- X
- Xmain(argc, argv)
- Xchar *argv[];
- X{
- X char *p, *realname;
- X int i;
- X long n=0, prev;
- X unsigned biggest_rec=0;
- X
- X puts("Typhoon Import Utility version 1.06");
- X
- X if( argc == 1 )
- X {
- X printf(paramhelp);
- X exit(1);
- X }
- X
- X /* Imtract the real name of the file */
- X if( (realname = strrchr(argv[argc-1], DIR_SWITCH)) != NULL )
- X realname++;
- X else
- X realname = argv[argc-1];
- X
- X /* remove extension if present */
- X if( p = strstr(realname, ".") )
- X *p = 0;
- X
- X /* generate file names for .ddl-file, .dbd-file and header file */
- X sprintf(dbd_fname, "%s.dbd", realname);
- X sprintf(spec_fname, "%s.imp", realname);
- X
- X if( read_dbdfile(&dbd, dbd_fname) != S_OKAY )
- X err_quit("Cannot open '%s'\n", dbd_fname);
- X
- X /* Find the size of the biggest record */
- X for( i=0; i<dbd.header.records; i++ )
- X if( biggest_rec < dbd.record[i].size )
- X biggest_rec = dbd.record[i].size;
- X
- X /* Allocate record buffer */
- X if( !(recbuf = (char *)malloc(biggest_rec)) )
- X err_quit("Out of memory");
- X
- X /* process command line options */
- X for( i=1; i<argc-1; i++ )
- X {
- X if( argv[i][0] == '-' || argv[i][0] == '/' )
- X {
- X switch( argv[i][1] )
- X {
- X case 'f':
- X if( d_dbfpath(argv[i]+2) != S_OKAY )
- X err_quit("Invalid data files path");
- X break;
- X case 'g':
- X GenerateImportSpec(realname);
- X exit(1);
- X default:
- X err_quit("unknown command line option");
- X }
- X }
- X else
- X err_quit("unknown command line option");
- X }
- X
- X /* Read the import specification */
- X ReadImportSpec(realname);
- X
- X if( !errors )
- X Import(realname);
- X
- X free(dbd.dbd);
- X free(recbuf);
- X}
- X
- X
- X/* end-of-file */
- END_OF_FILE
- if test 12523 -ne `wc -c <'typhoon/src/util/import.c'`; then
- echo shar: \"'typhoon/src/util/import.c'\" unpacked with wrong size!
- fi
- # end of 'typhoon/src/util/import.c'
- fi
- if test -f 'typhoon/src/util/restore.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'typhoon/src/util/restore.c'\"
- else
- echo shar: Extracting \"'typhoon/src/util/restore.c'\" \(13959 characters\)
- sed "s/^X//" >'typhoon/src/util/restore.c' <<'END_OF_FILE'
- X/*----------------------------------------------------------------------------
- X * File : restore.c
- X * Program : tybackup
- X * OS : UNIX, OS/2, DOS
- X * Author : Thomas B. Pedersen
- X *
- X * Copyright (c) 1994 Thomas B. Pedersen. All rights reserved.
- X *
- X * Permission is hereby granted, without written agreement and without
- X * license or royalty fees, to use, copy, modify, and distribute this
- X * software and its documentation for any purpose, provided that the above
- X * copyright notice and the following two paragraphs appear (1) in all
- X * source copies of this software and (2) in accompanying documentation
- X * wherever the programatic interface of this software, or any derivative
- X * of it, is described.
- X *
- X * IN NO EVENT SHALL THOMAS B. PEDERSEN BE LIABLE TO ANY PARTY FOR DIRECT,
- X * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
- X * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF HE HAS BEEN
- X * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- X *
- X * THOMAS B. PEDERSEN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
- X * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- X * A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
- X * BASIS, AND THOMAS B. PEDERSEN HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
- X * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- X *
- X * Description:
- X * Contains the tyrestore utility.
- X *
- X * Functions:
- X *
- X * $Log: restore.c,v $
- X * Revision 1.2 1994/09/17 16:00:56 tbp
- X * typhoon.h and environ.h are now included from <>.
- X *
- X * Revision 1.1 1994/09/13 21:29:00 tbp
- X * Added to repository.
- X *
- X * Added to repository.
- X *
- X *
- X *--------------------------------------------------------------------------*/
- X
- Xstatic char rcsid[] = "$Id: restore.c,v 1.2 1994/09/17 16:00:56 tbp Exp $";
- X
- X#include <sys/types.h>
- X#include <sys/ipc.h>
- X#include <sys/shm.h>
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <string.h>
- X#include <fcntl.h>
- X#include <time.h>
- X#include <setjmp.h>
- X#include <errno.h>
- X#include <assert.h>
- X#include <signal.h>
- X#include <typhoon.h>
- X#include "../ty_dbd.h"
- X#include "../ty_type.h"
- X#include "../ty_glob.h"
- X#include "../ty_prot.h"
- X#include "../ty_log.h"
- X#include "util.h"
- X
- X/*------------------------------- Constants --------------------------------*/
- X#define VERSION "1.00"
- X#define BLOCK_SIZE 512
- X#define OUTBUF_SIZE (BLOCK_SIZE * 128)
- X#define INBUF_SIZE (256 * 1024)
- X
- X/*-------------------------- Function prototypes ---------------------------*/
- Xstatic void SignalHandler PRM( (int); )
- Xstatic void Read PRM( (void *, ulong); )
- Xstatic void DisplayProgress PRM( (char *, ulong); )
- Xstatic void RestoreDatabase PRM( (void); )
- Xstatic void RestoreFile PRM( (char *); )
- Xstatic void RestoreDbdFile PRM( (void); )
- Xstatic void RestoreLogFile PRM( (void); )
- Xstatic void help PRM( (void); )
- X void FixLog PRM( (char *); )
- X
- X/*---------------------------- Global variables ----------------------------*/
- Xstatic ArchiveMediaHeader mediahd; /* Archive media header */
- Xstatic Dbentry dbd; /* DBD anchor */
- Xstatic int archive_fh = -1; /* Archive file handle */
- Xstatic char dbname[DBNAME_LEN+1]; /* Database name */
- Xstatic char *device = "/dev/null"; /* Archive device */
- Xstatic ulong curr_id; /* Current block header id */
- Xstatic char *inbuf; /* Input buffer */
- Xstatic ulong inreadpos; /* Current read position in buffer */
- Xstatic ulong inbytes; /* Number of bytes in outbuf */
- Xstatic ulong total_read = 0; /* Total number of bytes read */
- X jmp_buf err_jmpbuf; /* Jumped to on error */
- X char *datapath = ""; /* Database file path */
- X int db_status; /* Required by ../read_dbd.c */
- X int verbose = 0; /* Be verbose? */
- X
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : SignalHandler
- X *
- X * Purpose :
- X *
- X * Parameters:
- X *
- X * Returns :
- X *
- X */
- Xstatic void SignalHandler(sig)
- Xint sig;
- X{
- X printf("signal %d\n", sig);
- X
- X if( sig == SIGSEGV )
- X puts("Segmentation violation");
- X else if( sig == SIGBUS )
- X puts("Bus error");
- X
- X dbd.shm->restore_active = 0;
- X shm_free(&dbd);
- X d_close();
- X unlink(LOG_FNAME);
- X puts("Restore aborted.");
- X exit(1);
- X}
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : Read
- X *
- X * Purpose : Read x bytes from the archive. If the data is not entirely
- X * in the buffer, the rest will read immediately. If the end
- X * of the current media has been reached, the user is promted
- X * for the next media.
- X *
- X * Parameters: buf - Buffer to write.
- X * size - Number of bytes in buffer.
- X *
- X * Returns : Nothing.
- X *
- X */
- Xstatic void Read(buf, size)
- Xvoid *buf;
- Xulong size;
- X{
- X char s[20];
- X ulong copymax;
- X long numread;
- X
- X
- X/*printf("Read: size=%d, inbytes=%ld, inreadpos=%ld\n",
- X size, inbytes, inreadpos);*/
- X
- X /* Copy as much as possible to the output buffer */
- X if( inbytes > inreadpos )
- X {
- X copymax = size;
- X if( copymax > inbytes-inreadpos )
- X copymax = inbytes-inreadpos;
- X
- X memcpy(buf, inbuf+inreadpos, copymax);
- X inreadpos += copymax;
- X
- X if( copymax == size )
- X return;
- X }
- X else
- X copymax = 0;
- X
- X while( archive_fh == -1 )
- X {
- X clock_off();
- X printf("Insert backup media no %d [enter]", mediahd.seqno);
- X fflush(stdout);
- X gets(s);
- X
- X if( s[0] == 'q' )
- X longjmp(err_jmpbuf, 2);
- X
- X clock_on();
- X if( (archive_fh = open(device, O_RDONLY)) == -1 )
- X printf("Cannot open '%s' (errno %d)\n", device, errno);
- X }
- X
- X if( inreadpos == inbytes )
- X {
- X numread = read(archive_fh, inbuf, INBUF_SIZE);
- X/*printf("size=%ld, read=%ld, copymax=%ld, inreadpos=%ld, inbytes=%ld\n",
- X size, numread, copymax, inreadpos, inbytes);*/
- X
- X if( numread == -1 )
- X {
- X printf("Read error (errno %d)\n", errno);
- X longjmp(err_jmpbuf, 1);
- X }
- X else if( numread != INBUF_SIZE )
- X {
- X /* The number of bytes read is less than requested. If the
- X * Read request can be satisfied by the number of bytes actually
- X * returned by read(), we assume that the end of the current
- X * media has been reached.
- X */
- X if( numread + copymax < size )
- X {
- X printf("Read error (errno %d)\n", errno);
- X longjmp(err_jmpbuf, 1);
- X }
- X
- X mediahd.seqno++;
- X close(archive_fh);
- X archive_fh = -1;
- X }
- X
- X /* Now copy the rest of the buffer */
- X inbytes = numread;
- X inreadpos = size - copymax;
- X memcpy((char *)buf + copymax, inbuf, inreadpos);
- X
- X total_read += numread;
- X
- X/*printf("size=%ld, read=%ld, copymax=%ld, inreadpos=%ld, inbytes=%ld\n",
- X size, numread, copymax, inreadpos, inbytes);*/
- X }
- X}
- X
- X
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : DisplayProgress
- X *
- X * Purpose : Prints the number of bytes read so far from the current table.
- X *
- X * Parameters: table - Table name.
- X * bytes - Number of bytes read.
- X *
- X * Returns : Nothing.
- X *
- X */
- Xstatic void DisplayProgress(table, bytes)
- Xchar *table;
- Xulong bytes;
- X{
- X printf("\rWriting %-26.26s %10s bytes", table, printlong(bytes));
- X fflush(stdout);
- X}
- X
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : RestoreDatabase
- X *
- X * Purpose :
- X *
- X * Parameters: None.
- X *
- X * Returns : Nothing.
- X *
- X */
- Xstatic void RestoreDatabase()
- X{
- X ArchiveTableHeader tablehd;
- X ArchiveRecordHeader recordhd;
- X ulong prev_bytecount;
- X ulong bytecount;
- X char outbuf[OUTBUF_SIZE];
- X char fname[128];
- X char objname[128];
- X int fh;
- X
- X Read(&curr_id, sizeof curr_id);
- X
- X for( ;; )
- X {
- X if( curr_id != ARCHIVE_TABLE )
- X break;
- X
- X Read(&tablehd.recsize, sizeof(tablehd) - sizeof(tablehd.id));
- X
- X sprintf(fname, "%s/%s", datapath, tablehd.fname);
- X sprintf(objname, "table %s", tablehd.table);
- X
- X if( (fh = open(fname, O_WRONLY|O_TRUNC|O_CREAT|O_BINARY, CREATMASK)) == -1 )
- X {
- X printf("Cannot open file '%s'\n", fname);
- X longjmp(err_jmpbuf, 1);
- X }
- X prev_bytecount = bytecount = 0;
- X
- X for( ;; )
- X {
- X Read(&curr_id, sizeof curr_id);
- X
- X if( curr_id != ARCHIVE_RECORD )
- X break;
- X
- X Read(&recordhd.recid, sizeof(recordhd) - sizeof(recordhd.id));
- X Read(outbuf, tablehd.recsize);
- X
- X lseek(fh, tablehd.recsize * recordhd.recno, SEEK_SET);
- X write(fh, outbuf, tablehd.recsize);
- X
- X bytecount += tablehd.recsize;
- X
- X if( verbose && bytecount > prev_bytecount + 100000 )
- X {
- X prev_bytecount = bytecount;
- X DisplayProgress(objname, bytecount);
- X }
- X }
- X
- X if( verbose )
- X {
- X DisplayProgress(objname, bytecount);
- X puts("");
- X }
- X
- X
- X close(fh);
- X }
- X}
- X
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : RestoreFile
- X *
- X * Purpose : Read a sequential file from archive.
- X *
- X * Parameters: fname - File name.
- X *
- X * Returns : Nothing.
- X *
- X */
- Xstatic void RestoreFile(fname)
- Xchar *fname;
- X{
- X ArchiveFileDataHeader datahd;
- X int fh;
- X char buf[OUTBUF_SIZE];
- X ulong numread;
- X ulong readmax;
- X ulong bytecount=0;
- X
- X if( (fh = open(fname, O_WRONLY|O_TRUNC|O_CREAT, CREATMASK)) == -1 )
- X {
- X printf("Cannot open '%s'\n", fname);
- X return;
- X }
- X
- X for( ;; )
- X {
- X Read(&curr_id, sizeof curr_id);
- X
- X if( curr_id != ARCHIVE_FILEDATA )
- X {
- X printf("Unexpected header id %d in middle of file \n", curr_id);
- X longjmp(err_jmpbuf, 1);
- X }
- X
- X Read(&datahd.size, sizeof(datahd) - sizeof(datahd.size));
- X
- X if( !datahd.size ) /* End-of-file reached */
- X break;
- X
- X while( datahd.size > 0 )
- X {
- X /* Determine number of bytes to read */
- X readmax = sizeof buf;
- X if( readmax > datahd.size )
- X readmax = datahd.size;
- X
- X Read(buf, readmax);
- X write(fh, buf, readmax);
- X
- X bytecount += readmax;
- X
- X if( verbose )
- X DisplayProgress(fname, bytecount);
- X
- X datahd.size -= readmax;
- X }
- X }
- X
- X if( verbose )
- X puts("");
- X
- X close(fh);
- X}
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : RestoreDbdFile
- X *
- X * Purpose : Restores the dbd-file from the archive.
- X *
- X * Parameters: None.
- X *
- X * Returns : Nothing.
- X *
- X */
- Xstatic void RestoreDbdFile()
- X{
- X ArchiveFileHeader filehd;
- X
- X /* Restore dbd-file */
- X Read(&filehd, sizeof filehd);
- X
- X if( filehd.id != ARCHIVE_FILE )
- X {
- X printf("Unexpected header id %d\n", filehd.id);
- X longjmp(err_jmpbuf, 1);
- X }
- X
- X RestoreFile(filehd.fname);
- X}
- X
- X
- X/*--------------------------------------------------------------------------*\
- X *
- X * Function : RestoreLogFile
- X *
- X * Purpose : Restores the log file from the archive.
- X *
- X * Parameters: None.
- X *
- X * Returns : Nothing.
- X *
- X */
- Xstatic void RestoreLogFile()
- X{
- X ArchiveFileHeader filehd;
- X
- X if( curr_id == ARCHIVE_END )
- X return;
- X
- X /* Restore the database */
- X if( curr_id != ARCHIVE_FILE )
- X {
- X printf("Unexpected header id %ld\n", curr_id);
- X longjmp(err_jmpbuf, 1);
- X }
- X
- X Read(filehd.fname, sizeof(filehd) - sizeof(filehd.id));
- X
- X RestoreFile(filehd.fname);
- X}
- X
- X
- X
- Xstatic void VerboseFn(table, records, curr_rec)
- Xchar *table;
- Xulong records, curr_rec;
- X{
- X static int old_percent = 0;
- X int percent = curr_rec * 100 / records;
- X
- X if( curr_rec == 0 )
- X {
- X printf("\nRebuilding %-32.32s 0%%", table);
- X fflush(stdout);
- X old_percent = 0;
- X }
- X else if( percent != old_percent )
- X {
- X printf("\b\b\b\b%3d%%", percent);
- X fflush(stdout);
- X old_percent = percent;
- X }
- X}
- X
- X
- X
- Xstatic void help()
- X{
- X puts("Syntax: tyrestore [option]...\n"
- X "Options:\n"
- X " -d<device> Backup device\n"
- X " -f<path> Path for data files\n"
- X " -v Be verbose\n");
- X exit(1);
- X}
- X
- X
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X char dbdname[20];
- X int i;
- X struct tm *tm;
- X
- X /* The input buffer MUST be bigger than the output buffer */
- X assert(OUTBUF_SIZE < INBUF_SIZE);
- X
- X printf("Typhoon Restore version %s\n", VERSION);
- X
- X if( argc < 2 )
- X help();
- X
- X for( i=1; i<argc; i++ )
- X {
- X switch( *argv[i] )
- X {
- X case '-':
- X case '/':
- X switch( argv[i][1] )
- X {
- X case 'd':
- X device = argv[i]+2;
- X break;
- X case 'f':
- X datapath = argv[i]+2;
- X break;
- X case 'v':
- X verbose = 1;
- X break;
- X default:
- X printf("Invalid option '%c'\n", argv[i][1]);
- X break;
- X }
- X break;
- X default:
- X printf("Invalid switch '%c'\n", *argv[i]);
- X break;
- X }
- X }
- X
- X if( *datapath )
- X {
- X mkdir(datapath);
- X chmod(datapath, 0777);
- X }
- X
- X if( !(inbuf = (char *)malloc(INBUF_SIZE)) )
- X {
- X puts("Cannot allocate output buffer");
- X return;
- X }
- X inbytes = 0;
- X inreadpos = 0;
- X
- X if( setjmp(err_jmpbuf) )
- X {
- X if( verbose )
- X puts("Restore aborted.");
- X goto out;
- X }
- X
- X if( verbose )
- X printf("Restoring from %s\n", device);
- X
- X Read(&mediahd, sizeof mediahd);
- X if( mediahd.id != ARCHIVE_MEDIA )
- X {
- X printf("Unexpected header id %d\n", mediahd.id);
- X longjmp(err_jmpbuf, 1);
- X }
- X
- X strcpy(dbd.name, mediahd.dbname);
- X if( shm_alloc(&dbd) == -1 )
- X {
- X printf("Cannot allocate shared memory");
- X return;
- X }
- X dbd.shm->restore_active = 1;
- X
- X signal(SIGINT, SignalHandler);
- X signal(SIGTERM, SignalHandler);
- X signal(SIGQUIT, SignalHandler);
- X signal(SIGSEGV, SignalHandler);
- X signal(SIGBUS, SignalHandler);
- X signal(SIGHUP, SIG_IGN);
- X
- X if( dbd.shm->use_count > 1 )
- X {
- X puts("The database is currenly in use. Cannot restore");
- X goto out;
- X }
- X
- X /* Confirm restore */
- X clock_off();
- X tm = localtime(&mediahd.date);
- X printf("Database '%s' from %s", mediahd.dbname, asctime(tm));
- X printf("Restore? [y/n]: ");
- X fflush(stdout);
- X if( getchar() != 'y' )
- X goto out;
- X clock_on();
- X
- X RestoreDbdFile();
- X RestoreDatabase();
- X RestoreLogFile();
- X clock_off();
- X
- X if( verbose )
- X {
- X ulong secs = clock_secs();
- X
- X /* Guard against division by zero */
- X if( !secs )
- X secs = 1;
- X
- X printf("\rTotal %40s bytes\n", printlong(total_read));
- X printf("%s bytes/second\n", printlong(total_read / secs));
- X }
- X
- X FixLog(mediahd.dbname);
- X
- X printf("Rebuilding index files");
- X d_keybuild(VerboseFn);
- X d_dbfpath(datapath);
- X
- X if( d_open(mediahd.dbname, "o") != S_OKAY )
- X puts("Cannot open database");
- X else
- X {
- X d_close();
- X puts("");
- X }
- X
- Xout:
- X free(inbuf);
- X dbd.shm->restore_active = 0;
- X shm_free(&dbd);
- X free(dbd.dbd);
- X unlink(LOG_FNAME);
- X
- X return 0;
- X}
- X
- X/* end-of-file */
- END_OF_FILE
- if test 13959 -ne `wc -c <'typhoon/src/util/restore.c'`; then
- echo shar: \"'typhoon/src/util/restore.c'\" unpacked with wrong size!
- fi
- # end of 'typhoon/src/util/restore.c'
- fi
- echo shar: End of archive 2 \(of 9\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-