home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume44 / typhoon / part02 < prev    next >
Internet Message Format  |  1994-09-17  |  62KB

  1. From: zeppelin@login.dknet.dk (Thomas B. Pedersen)
  2. Newsgroups: comp.sources.misc
  3. Subject: v44i058:  typhoon - Typhoon Relational Database Management System, Part02/09
  4. Date: 17 Sep 1994 21:44:15 -0500
  5. Organization: Sterling Software
  6. Sender: kent@sparky.sterling.com
  7. Approved: kent@sparky.sterling.com
  8. Message-ID: <35g9hv$ofg@sparky.sterling.com>
  9. X-Md4-Signature: ae0f28b0c926f38174b9f245402b9fdc
  10.  
  11. Submitted-by: zeppelin@login.dknet.dk (Thomas B. Pedersen)
  12. Posting-number: Volume 44, Issue 58
  13. Archive-name: typhoon/part02
  14. Environment: SCO UNIX, Tandem NonStop UNIX, Sun Solaris, AIX, Linux, OS/2
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  typhoon/src/os2.c typhoon/src/ty_open.c
  21. #   typhoon/src/util/backup.c typhoon/src/util/import.c
  22. #   typhoon/src/util/restore.c
  23. # Wrapped by kent@sparky on Sat Sep 17 21:38:15 1994
  24. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 2 (of 9)."'
  27. if test -f 'typhoon/src/os2.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'typhoon/src/os2.c'\"
  29. else
  30.   echo shar: Extracting \"'typhoon/src/os2.c'\" \(3660 characters\)
  31.   sed "s/^X//" >'typhoon/src/os2.c' <<'END_OF_FILE'
  32. X/*----------------------------------------------------------------------------
  33. X * File    : os2.c
  34. X * Library : typhoon
  35. X * OS      : UNIX, OS/2, DOS
  36. X * Author  : Thomas B. Pedersen
  37. X *
  38. X * Copyright (c) 1994 Thomas B. Pedersen.  All rights reserved.
  39. X *
  40. X * Permission is hereby granted, without written agreement and without
  41. X * license or royalty fees, to use, copy, modify, and distribute this
  42. X * software and its documentation for any purpose, provided that the above
  43. X * copyright notice and the following two  paragraphs appear (1) in all 
  44. X * source copies of this software and (2) in accompanying documentation
  45. X * wherever the programatic interface of this software, or any derivative
  46. X * of it, is described.
  47. X *
  48. X * IN NO EVENT SHALL THOMAS B. PEDERSEN BE LIABLE TO ANY PARTY FOR DIRECT,
  49. X * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
  50. X * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF HE HAS BEEN 
  51. X * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52. X *
  53. X * THOMAS B. PEDERSEN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
  54. X * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  55. X * A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" 
  56. X * BASIS, AND THOMAS B. PEDERSEN HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
  57. X * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  58. X *
  59. X * Description:
  60. X *   Contains functions specific to OS/2.
  61. X *
  62. X * Functions:
  63. X *   ty_openlock    - Create/open the locking resource.
  64. X *   ty_closelock    - Close the locking resource.
  65. X *   ty_lock        - Obtain the lock.
  66. X *   ty_unlock        - Release the lock.
  67. X *
  68. X * $Log: os2.c,v $
  69. X * Revision 1.1  1994/09/13  21:28:31  tbp
  70. X * Added to repository.
  71. X * 
  72. X *
  73. X *--------------------------------------------------------------------------*/
  74. X
  75. Xstatic char rcsid[] = "$Id";
  76. X
  77. X#define INCL_NOPMAPI
  78. X#define INCL_DOSSEMAPHORES
  79. X#include <os2.h>
  80. X
  81. X#define TIMEOUT        -1            /* Wait maximum 30 seconds for excl. access    */
  82. X
  83. X/*---------------------------- Global variables ----------------------------*/
  84. Xstatic HMTX block_sem;            /* Blocking semaphore used by d_block()        */
  85. Xstatic HMTX    ty_sem;                 /* API function semaphore                    */
  86. X
  87. X
  88. X#ifdef __BORLANDC__
  89. XULONG _dllmain(ULONG termflag, HMODULE modhandle)
  90. X#endif
  91. X#ifdef __IBMC__
  92. Xvoid _CRT_init(void);
  93. XULONG _System _DLL_InitTerm(ULONG modhandle, ULONG termflag)
  94. X#endif
  95. X{
  96. X    static char fname[] = "\\SEM32\\TYPHOON";
  97. X
  98. X    switch( termflag )
  99. X    {
  100. X        case 0:
  101. X#ifdef __IBMC__
  102. X            _CRT_init();
  103. X#endif
  104. X            if( DosOpenMutexSem(fname, &ty_sem) )
  105. X                if( DosCreateMutexSem(fname, &ty_sem, 0, 0) )
  106. X                    return 0;
  107. X
  108. X            if( DosCreateMutexSem(NULL, &block_sem, 0, 0) )
  109. X                return 0;
  110. X            break;
  111. X
  112. X        case 1:
  113. X            /* Never release the ty_sem semaphore */
  114. X            DosCloseMutexSem(ty_sem);
  115. X            DosCloseMutexSem(block_sem);
  116. X            break;
  117. X    }
  118. X
  119. X    return 1;
  120. X}
  121. X
  122. X/*------------------------------ ty_openlock  ------------------------------*\
  123. X *
  124. X * Purpose     : This function ensures that only one instance of a Typhoon
  125. X *             function is active at the time, at least in its critical
  126. X *             section.
  127. X *
  128. X * Parameters: None.
  129. X *
  130. X * Returns     : -1        - Semaphore could not be created.
  131. X *               0        - Successful.
  132. X *
  133. X */
  134. X
  135. Xty_openlock()
  136. X{
  137. X/*
  138. X    static char fname[] = "\\SEM32\\TYPHOON";
  139. X
  140. X    if( DosOpenMutexSem(fname, &ty_sem) )
  141. X        if( DosCreateMutexSem(fname, &ty_sem, 0, 0) )
  142. X            return -1;
  143. X
  144. X    locked = 0;
  145. X*/
  146. X    return 0;
  147. X}
  148. X
  149. X
  150. Xty_closelock()
  151. X{
  152. X/*    DosCloseMutexSem(ty_sem);*/
  153. X    return 0;
  154. X}
  155. X
  156. X
  157. Xty_lock()
  158. X{
  159. X    if( DosRequestMutexSem(ty_sem, TIMEOUT) )
  160. X        return -1;
  161. X
  162. X    return 0;
  163. X}
  164. X
  165. X
  166. Xty_unlock()
  167. X{
  168. X    DosReleaseMutexSem(ty_sem);
  169. X    return 0;
  170. X}
  171. X
  172. X
  173. Xvoid os2_block()
  174. X{
  175. X    DosRequestMutexSem(block_sem, -1L);
  176. X}
  177. X
  178. X
  179. Xvoid os2_unblock()
  180. X{
  181. X    DosReleaseMutexSem(block_sem);
  182. X}
  183. X
  184. X/* end-of-file */
  185. END_OF_FILE
  186.   if test 3660 -ne `wc -c <'typhoon/src/os2.c'`; then
  187.     echo shar: \"'typhoon/src/os2.c'\" unpacked with wrong size!
  188.   fi
  189.   # end of 'typhoon/src/os2.c'
  190. fi
  191. if test -f 'typhoon/src/ty_open.c' -a "${1}" != "-c" ; then 
  192.   echo shar: Will not clobber existing file \"'typhoon/src/ty_open.c'\"
  193. else
  194.   echo shar: Extracting \"'typhoon/src/ty_open.c'\" \(13441 characters\)
  195.   sed "s/^X//" >'typhoon/src/ty_open.c' <<'END_OF_FILE'
  196. X/*----------------------------------------------------------------------------
  197. X * File    : ty_open.c
  198. X * Library : typhoon
  199. X * OS      : UNIX, OS/2, DOS
  200. X * Author  : Thomas B. Pedersen
  201. X *
  202. X * Copyright (c) 1994 Thomas B. Pedersen.  All rights reserved.
  203. X *
  204. X * Permission is hereby granted, without written agreement and without
  205. X * license or royalty fees, to use, copy, modify, and distribute this
  206. X * software and its documentation for any purpose, provided that the above
  207. X * copyright notice and the following two  paragraphs appear (1) in all 
  208. X * source copies of this software and (2) in accompanying documentation
  209. X * wherever the programatic interface of this software, or any derivative
  210. X * of it, is described.
  211. X *
  212. X * IN NO EVENT SHALL THOMAS B. PEDERSEN BE LIABLE TO ANY PARTY FOR DIRECT,
  213. X * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
  214. X * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF HE HAS BEEN 
  215. X * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  216. X *
  217. X * THOMAS B. PEDERSEN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
  218. X * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  219. X * A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" 
  220. X * BASIS, AND THOMAS B. PEDERSEN HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
  221. X * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  222. X *
  223. X * Description:
  224. X *
  225. X * Functions:
  226. X *   Contains functions for opening and closing the database.
  227. X *
  228. X * $Log: ty_open.c,v $
  229. X * Revision 1.2  1994/09/17  16:00:19  tbp
  230. X * typhoon.h and environ.h are now included from <>.
  231. X *
  232. X * Revision 1.1  1994/09/13  21:28:36  tbp
  233. X * Added to repository.
  234. X * 
  235. X *
  236. X *--------------------------------------------------------------------------*/
  237. X
  238. Xstatic char rcsid[] = "$Id";
  239. X
  240. X#ifdef UNIX
  241. X#  include <unistd.h>
  242. X#  include <stdio.h>
  243. X#  ifdef __STDC__
  244. X#    include <stdlib.h>
  245. X#  endif
  246. X#  define DIR_SWITCH    '/'
  247. X#else
  248. X#  include <stdlib.h>
  249. X#  include <io.h>
  250. X#  define DIR_SWITCH    '\\'
  251. X#endif
  252. X#include <fcntl.h>
  253. X#include <assert.h>
  254. X#include <string.h>
  255. X#include <stdio.h>
  256. X#include <typhoon.h>
  257. X#include "ty_dbd.h"
  258. X#include "ty_type.h"
  259. X#include "ty_glob.h"
  260. X#include "ty_prot.h"
  261. X
  262. X/*--------------------------- Function prototypes --------------------------*/
  263. Xstatic void    fixpath            PRM( (char *, char *); )
  264. X       int  read_dbdfile    PRM( (Dbentry *, char *); )
  265. Xstatic int  perform_rebuild PRM( (unsigned); )
  266. X
  267. X
  268. Xstatic void (*rebuildverbose_fn) PRM((char *, ulong, ulong);)
  269. X
  270. X
  271. Xstatic void fixpath(path, s)
  272. Xchar *path, *s;
  273. X{
  274. X    int len = strlen(s);
  275. X
  276. X    if( len > 0 )
  277. X    {
  278. X        strcpy(path, s);
  279. X
  280. X        if( path[len-1] != DIR_SWITCH )
  281. X        {
  282. X            path[len++] = DIR_SWITCH;
  283. X            path[len] = 0;
  284. X        }
  285. X    }
  286. X    else
  287. X    {
  288. X        path[0] = '.';
  289. X        path[1] = DIR_SWITCH;
  290. X        path[2] = 0;
  291. X    }
  292. X}
  293. X
  294. X
  295. X
  296. X/*-------------------------------- d_dbdpath -------------------------------*\
  297. X *
  298. X * Purpose     : Set the path of the dbd-file. This function is called prior
  299. X *               d_open().
  300. X *
  301. X * Parameters: path        - The path of the dbd-file.
  302. X *
  303. X * Returns     : S_OKAY    - Successful.
  304. X *
  305. X */
  306. X
  307. X
  308. XFNCLASS d_dbdpath(path)
  309. Xchar *path;
  310. X{
  311. X    fixpath(typhoon.dbdpath, path);
  312. X
  313. X    return S_OKAY;
  314. X}
  315. X
  316. X
  317. X
  318. X/*-------------------------------- d_dbfpath -------------------------------*\
  319. X *
  320. X * Purpose     : Set the path of the database files. This function is called
  321. X *               prior to d_open().
  322. X *
  323. X * Parameters: path        - The path of the database files.
  324. X *
  325. X * Returns     : S_OKAY    - Successful.
  326. X *
  327. X */
  328. X
  329. X
  330. XFNCLASS d_dbfpath(path)
  331. Xchar *path;
  332. X{
  333. X    fixpath(typhoon.dbfpath, path);
  334. X
  335. X    return S_OKAY;
  336. X}
  337. X
  338. X
  339. X
  340. X/*--------------------------------- d_dbget --------------------------------*\
  341. X *
  342. X * Purpose     : Gets the current database ID.
  343. X *
  344. X * Parameters: id        - Pointer to database ID.
  345. X *
  346. X * Returns     : S_OKAY    - The database ID is stored in <id>.
  347. X *               S_NOCD    - There is no current database.
  348. X *
  349. X */
  350. X
  351. XFNCLASS d_dbget(id)
  352. Xint *id;
  353. X{
  354. X    if( CURR_DB == -1 )
  355. X        RETURN S_NOCD;
  356. X
  357. X    *id = CURR_DB;
  358. X
  359. X    RETURN S_OKAY;
  360. X}
  361. X
  362. X
  363. X
  364. X/*--------------------------------- d_dbset --------------------------------*\
  365. X *
  366. X * Purpose     : Sets the current database ID.
  367. X *
  368. X * Parameters: id        - Database ID obtained by call to d_dbget().
  369. X *
  370. X * Returns     : S_OKAY    - The database ID is stored in <id>.
  371. X *               S_INVDB    - Invalid database ID.
  372. X *
  373. X */
  374. X
  375. XFNCLASS d_dbset(id)
  376. Xint id;
  377. X{
  378. X    int i;
  379. X
  380. X    /* Ensure that the id is valid */
  381. X    if( id < 0 || id >= DB_MAX )
  382. X        RETURN S_INVDB;
  383. X
  384. X    /* Ensure that the database is actually open */
  385. X    if( typhoon.dbtab[id].clients == 0 )
  386. X        RETURN S_INVDB;
  387. X
  388. X    DB->db_status = db_status;
  389. X
  390. X    typhoon.curr_db = id;
  391. X    typhoon.db = typhoon.dbtab + id;
  392. X
  393. X    db_status = DB->db_status;
  394. X
  395. X    RETURN S_OKAY;
  396. X}
  397. X
  398. X
  399. X/*------------------------------- d_setfiles -------------------------------*\
  400. X *
  401. X * Purpose     : Set the maximum number of open files.
  402. X *
  403. X * Parameters: maxfiles    - The maximum number of open files allowed.
  404. X *
  405. X * Returns     : S_OKAY    - Ok.
  406. X *                S_INVPARM- The maximum is invalid.
  407. X *
  408. X */
  409. XFNCLASS d_setfiles(maxfiles)
  410. Xint maxfiles;
  411. X{
  412. X    if( maxfiles < 2 )
  413. X        RETURN S_INVPARM;
  414. X
  415. X    if( maxfiles < typhoon.max_open )
  416. X    {
  417. X        /* maxfiles is less than max_open, so we need minimize the number
  418. X         * of open files right away.
  419. X         */
  420. X        int diff = typhoon.max_open - maxfiles;
  421. X
  422. X        while( typhoon.cur_open > maxfiles && diff-- )
  423. X            ty_closeafile();
  424. X
  425. X        /* If it was not possible to closed the required number of files
  426. X         * anyway, an error code is returned
  427. X         */
  428. X        if( typhoon.cur_open > maxfiles )
  429. X            RETURN S_INVPARM;
  430. X    }
  431. X
  432. X    typhoon.max_open = maxfiles;
  433. X    
  434. X    RETURN S_OKAY;
  435. X}
  436. X
  437. X
  438. X
  439. XFNCLASS d_keybuild(fn)
  440. Xvoid (*fn)PRM((char *, ulong, ulong);)
  441. X{
  442. X    typhoon.do_rebuild = 1;
  443. X    rebuildverbose_fn = fn;
  444. X}
  445. X
  446. X
  447. Xstatic perform_rebuild(biggest_rec)
  448. Xunsigned biggest_rec;
  449. X{
  450. X    ulong        recno;
  451. X    ulong        recid;
  452. X    ulong        datasize;
  453. X    ulong        records;
  454. X    char        *buf;
  455. X    int         fh, i;
  456. X    Record        *rec;
  457. X    RECORD        filehd;
  458. X    char        fname[128];
  459. X    int            preamble;
  460. X    int            foreign_keys;
  461. X    
  462. X    if( (buf = (void *)malloc(biggest_rec)) == NULL )
  463. X        RETURN S_NOMEM;
  464. X
  465. X    for( i=0, rec=DB->record; i<DB->header.records; i++, rec++ )
  466. X    {
  467. X        sprintf(fname, "%s%c%s_tmp", DB->dbfpath, DIR_SWITCH, 
  468. X            DB->file[rec->fileid].name);
  469. X
  470. X        fh = os_open(fname, O_RDWR|O_BINARY, 0);
  471. X        read(fh, &filehd.H, sizeof filehd.H);
  472. X
  473. X        recno     = (sizeof(filehd.H) + filehd.H.recsize - 1) / filehd.H.recsize;
  474. X        recid     = INTERN_TO_RECID(i);
  475. X        records    = lseek(fh, 0, SEEK_END) / filehd.H.recsize;
  476. X
  477. X        rebuildverbose_fn(rec->name, records, 0);
  478. X
  479. X        if( rec->first_foreign == -1 )
  480. X            foreign_keys = 0;
  481. X        else
  482. X            foreign_keys = rec->keys - (rec->first_foreign - rec->first_key);
  483. X        preamble= sizeof(long) * foreign_keys + offsetof(RECORDHEAD, data[0]);
  484. X        datasize= filehd.H.recsize - preamble;
  485. X
  486. X        for( ;; )
  487. X        {
  488. X            lseek(fh, filehd.H.recsize * recno + preamble, SEEK_SET);
  489. X            if( read(fh, buf, datasize) != datasize )
  490. X                break;
  491. X            
  492. X            if( d_fillnew(recid, buf) != S_OKAY )
  493. X                printf("%s: d_fillnew failed\n", rec->name);
  494. X
  495. X            recno++;
  496. X
  497. X            rebuildverbose_fn(rec->name, records, recno);
  498. X        }
  499. X        
  500. X        close(fh);
  501. X        unlink(fname);
  502. X
  503. X        rebuildverbose_fn(rec->name, records, records);
  504. X    }        
  505. X    free(buf);
  506. X
  507. X    RETURN S_OKAY;
  508. X}
  509. X
  510. X
  511. X
  512. X/*--------------------------------- d_open ---------------------------------*\
  513. X *
  514. X * Purpose     : Opens a database of the name <dbname>. The dbd-file is
  515. X *               expected to be in <dbdpath> and the data and index file are
  516. X *               expected to be in (or will be created in) <dbfpath>, set by
  517. X *               d_dbdpath() and d_dbfpath().
  518. X *
  519. X *               If the database is opened in exclusive or one-user mode the
  520. X *               first file is locked. This will make future calls to d_open()
  521. X *               return S_UNAVAIL.
  522. X *
  523. X * Parameters: dbname        - Database name.
  524. X *               mode            - [s]hared, e[x]clusive or [o]ne user mode.
  525. X *
  526. X * Returns     : S_OKAY        - Database successfully opened.
  527. X *               S_NOTAVAIL    - Database is currently not available.
  528. X *               S_NOMEM        - Not enough memory to open database.
  529. X *               S_INVDB        - Invalid database name.
  530. X *               S_BADTYPE    - The mode parmeter was invalid.
  531. X *
  532. X */
  533. X
  534. XFNCLASS d_open(dbname, mode)
  535. Xchar *dbname, *mode;
  536. X{
  537. X    char fname[129];
  538. X    Record *rec;
  539. X    int i, n;
  540. X    unsigned biggest_rec = 0;
  541. X    Dbentry    *_db;
  542. X
  543. X    db_status = S_OKAY;
  544. X
  545. X    /* Validate the mode parameter */
  546. X    if( *mode != 's' && *mode != 'x' && *mode != 'o' )
  547. X        RETURN_RAP(S_BADTYPE);
  548. X
  549. X    /* Initialize locking resource */
  550. X    if( ty_openlock() == -1 )
  551. X        RETURN S_FATAL;
  552. X
  553. X    ty_lock();
  554. X
  555. X    /* Find an available database slot */
  556. X    for( i=0, _db=typhoon.dbtab; i<DB_MAX; i++, _db++ )
  557. X        if( !_db->clients )
  558. X            break;
  559. X
  560. X    if( i == DB_MAX )
  561. X    {
  562. X        ty_unlock();
  563. X        RETURN S_NOTAVAIL;
  564. X    }
  565. X
  566. X    DB = _db;
  567. X    DB->mode     = *mode;
  568. X    strcpy(DB->name, dbname);
  569. X    strcpy(DB->dbfpath, typhoon.dbfpath);
  570. X
  571. X    /* dbd-file is located in <dbdpath> */
  572. X    sprintf(fname, "%s%s.dbd", typhoon.dbdpath, dbname);
  573. X    if( read_dbdfile(DB, fname) != S_OKAY )
  574. X    {
  575. X        ty_unlock();
  576. X        return db_status;
  577. X    }
  578. X
  579. X    /* Allocate 'current record' buffer (add room for record numbers of
  580. X     * parent records (one per foreign key)
  581. X     */
  582. X    for( i=0, rec=DB->record; i<DB->header.records; i++, rec++ )
  583. X    {
  584. X        if( rec->first_foreign == -1 )
  585. X            n = rec->size;
  586. X        else
  587. X            n = rec->size + (rec->keys - (rec->first_foreign - rec->first_key))
  588. X                          * sizeof(ulong);
  589. X
  590. X        if( n > biggest_rec )
  591. X            biggest_rec = n;
  592. X    }
  593. X
  594. X    if( (DB->real_recbuf = (char *)malloc(biggest_rec)) == NULL )
  595. X    {
  596. X        ty_unlock();
  597. X        free(DB->dbd);
  598. X        RETURN S_NOMEM;
  599. X    }
  600. X
  601. X    if( shm_alloc(DB) == -1 )
  602. X    {
  603. X        ty_unlock();
  604. X        free(DB->dbd);
  605. X        return S_NOMEM;
  606. X    }
  607. X
  608. X    /* The database cannot be opened during a restore (except for rebuild) */
  609. X    if( DB->shm->restore_active && !typhoon.do_rebuild )
  610. X    {
  611. X        ty_unlock();
  612. X        free(DB->dbd);
  613. X        shm_free(DB);
  614. X        RETURN S_NOTAVAIL;
  615. X    }
  616. X
  617. X    DB->recbuf = DB->real_recbuf;
  618. X    DB->clients++;
  619. X
  620. X    /* If the indices should be rebuilt we'll remove them first */
  621. X    if( typhoon.do_rebuild )
  622. X    {
  623. X        char fname[256];
  624. X        char new_fname[256];
  625. X
  626. X        for( i=0; i<DB->header.files; i++ )
  627. X            if( DB->file[i].type == 'k' )
  628. X            {
  629. X                sprintf(fname, "%s%c%s", typhoon.dbfpath, DIR_SWITCH, DB->file[i].name);
  630. X                unlink(fname);
  631. X            }
  632. X            else
  633. X            {
  634. X                sprintf(fname, "%s%c%s", typhoon.dbfpath, DIR_SWITCH, DB->file[i].name);
  635. X                sprintf(new_fname, "%s_tmp", fname);
  636. X                unlink(new_fname);
  637. X                rename(fname, new_fname);
  638. X            }
  639. X    }
  640. X
  641. X    /* Before opening the database we mark all file handles are closed */
  642. X    for( i=0; i<DB->header.files; i++ )
  643. X        DB->fh[i].any = NULL;
  644. X
  645. X    /* Open all the database files */
  646. X    for( i=0; i<DB->header.files && db_status == S_OKAY; i++ )
  647. X        ty_openfile(DB->file + i, DB->fh + i, *mode == 's');
  648. X
  649. X    /* Roll back if a file could not be opened */
  650. X    if( db_status != S_OKAY )
  651. X    {
  652. X        i--;
  653. X        while( i-- )
  654. X            ty_closefile(DB->fh + i);
  655. X
  656. X        DB->clients--;
  657. X        CURR_DB = -1;
  658. X        shm_free(DB);
  659. X        free(DB->real_recbuf);
  660. X        free(DB->dbd);
  661. X        ty_unlock();
  662. X        RETURN db_status;
  663. X    }
  664. X
  665. X    CURR_DB          = _db - typhoon.dbtab;
  666. X    CURR_REC        = 0;
  667. X    CURR_RECID        = 0;
  668. X    CURR_BUFREC        = 0;
  669. X    CURR_BUFRECID    = 0;
  670. X
  671. X    if( typhoon.do_rebuild )
  672. X    {
  673. X        perform_rebuild(biggest_rec);
  674. X        typhoon.do_rebuild = 0;
  675. X    }
  676. X
  677. X    typhoon.dbs_open++;
  678. X    ty_unlock();
  679. X
  680. X    /* Return the status of the last db_open command */
  681. X    return db_status;
  682. X}
  683. X
  684. X
  685. X
  686. X/*--------------------------------- d_close --------------------------------*\
  687. X *
  688. X * Purpose     : Close the current database.
  689. X *
  690. X * Parameters: None.
  691. X *
  692. X * Returns     : S_NOCD        - No current database.
  693. X *               S_OKAY        - Database successfully closed.
  694. X *
  695. X */
  696. X
  697. XFNCLASS d_close()
  698. X{
  699. X    int i;
  700. X
  701. X    if( CURR_DB == -1 )
  702. X        RETURN_RAP(S_NOCD);
  703. X
  704. X    DB->clients--;
  705. X
  706. X    for( i=0; i<DB->header.files; i++ )
  707. X        ty_closefile(DB->fh + i);
  708. X
  709. X    /* If there is currently a transaction active the transaction counter
  710. X     * in shared memory must be decremented.
  711. X     */
  712. X    d_abortwork();
  713. X
  714. X    shm_free(DB);
  715. X    FREE(DB->dbd);
  716. X    FREE(DB->real_recbuf);
  717. X
  718. X    CURR_DB  = -1;
  719. X    CURR_REC = 0;
  720. X
  721. X    if( !--typhoon.dbs_open )
  722. X        ty_closelock();
  723. X
  724. X    RETURN S_OKAY;
  725. X}
  726. X
  727. X
  728. X
  729. X/*-------------------------------- d_destroy -------------------------------*\
  730. X *
  731. X * Purpose     : Destroy a database.
  732. X *
  733. X * Parameters: dbname        - Database name.
  734. X *
  735. X * Returns     : S_NOMEM        - Not enough memory to open database and destroy.
  736. X *               S_INVDB        - Invalid database name.
  737. X *               S_OKAY        - Database successfully closed.
  738. X *               S_NOTAVAIL    - The database is already opened in non-shared
  739. X *                              mode.
  740. X *
  741. X *
  742. X *        INSERT LOCK CHECK HERE!!!!!
  743. X *
  744. X *
  745. X */
  746. X
  747. XFNCLASS d_destroy(dbname)
  748. Xchar *dbname;
  749. X{
  750. X    int i, dbdfile;
  751. X    char fname[80];
  752. X    Header   header;
  753. X    File    *file;
  754. X    Dbentry *_db = typhoon.dbtab;
  755. X
  756. X    ty_lock();
  757. X
  758. X    for( i=0; i<DB_MAX; i++, _db++ )        /* Find database name in table  */
  759. X        if( !strcmp(_db->name, dbname) )
  760. X            break;
  761. X
  762. X    if( i == DB_MAX )
  763. X    {                                        /* Database currently not open    */
  764. X        sprintf(fname, "%s%s.dbd", typhoon.dbdpath, dbname);
  765. X
  766. X        if( (dbdfile = open(fname, O_BINARY|O_RDONLY)) == -1 )
  767. X        {
  768. X            ty_unlock();
  769. X            RETURN S_INVDB;                 /* Database name not found      */
  770. X        }
  771. X        read(dbdfile, &header, sizeof header);
  772. X
  773. X        if( !(file = (File *)malloc(sizeof(File) * header.files)) )
  774. X        {
  775. X            close(dbdfile);
  776. X            ty_unlock();
  777. X            RETURN S_NOMEM;
  778. X        }
  779. X
  780. X        read(dbdfile, file, sizeof(File) * header.files);
  781. X        close(dbdfile);
  782. X
  783. X        for( i=0; i < header.files; i++ )   /* Now remove all files         */
  784. X            unlink(file[i].name);
  785. X
  786. X        ty_unlock();
  787. X        RETURN S_OKAY;
  788. X    }
  789. X
  790. X    /*---------- Destroy current database ----------------------------------*/
  791. X    for( i=0; i<DB->header.files; i++ )
  792. X    {
  793. X        ty_closefile(DB->fh + i);           /* Close all database files     */
  794. X        unlink(DB->file[i].name);           /* and remove them              */
  795. X    }
  796. X
  797. X    FREE(DB->dbd);
  798. X
  799. X    _db->clients = 0;
  800. X    CURR_DB  = -1;
  801. X    CURR_REC = 0;
  802. X
  803. X    ty_unlock();
  804. X    RETURN S_OKAY;
  805. X}
  806. X
  807. X/* end-of-file */
  808. END_OF_FILE
  809.   if test 13441 -ne `wc -c <'typhoon/src/ty_open.c'`; then
  810.     echo shar: \"'typhoon/src/ty_open.c'\" unpacked with wrong size!
  811.   fi
  812.   # end of 'typhoon/src/ty_open.c'
  813. fi
  814. if test -f 'typhoon/src/util/backup.c' -a "${1}" != "-c" ; then 
  815.   echo shar: Will not clobber existing file \"'typhoon/src/util/backup.c'\"
  816. else
  817.   echo shar: Extracting \"'typhoon/src/util/backup.c'\" \(12068 characters\)
  818.   sed "s/^X//" >'typhoon/src/util/backup.c' <<'END_OF_FILE'
  819. X/*----------------------------------------------------------------------------
  820. X * File    : backup.c
  821. X * Program : tybackup
  822. X * OS      : UNIX, OS/2, DOS
  823. X * Author  : Thomas B. Pedersen
  824. X *
  825. X * Copyright (c) 1994 Thomas B. Pedersen.  All rights reserved.
  826. X *
  827. X * Permission is hereby granted, without written agreement and without
  828. X * license or royalty fees, to use, copy, modify, and distribute this
  829. X * software and its documentation for any purpose, provided that the above
  830. X * copyright notice and the following two  paragraphs appear (1) in all 
  831. X * source copies of this software and (2) in accompanying documentation
  832. X * wherever the programatic interface of this software, or any derivative
  833. X * of it, is described.
  834. X *
  835. X * IN NO EVENT SHALL THOMAS B. PEDERSEN BE LIABLE TO ANY PARTY FOR DIRECT,
  836. X * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
  837. X * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF HE HAS BEEN 
  838. X * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  839. X *
  840. X * THOMAS B. PEDERSEN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
  841. X * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  842. X * A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" 
  843. X * BASIS, AND THOMAS B. PEDERSEN HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
  844. X * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  845. X *
  846. X * Description:
  847. X *   Contains the tybackup utility.
  848. X *
  849. X * Functions:
  850. X *
  851. X * $Log: backup.c,v $
  852. X * Revision 1.2  1994/09/17  16:00:49  tbp
  853. X * typhoon.h and environ.h are now included from <>.
  854. X *
  855. X * Revision 1.1  1994/09/13  21:28:50  tbp
  856. X * Added to repository.
  857. X *
  858. X * Added to repository.
  859. X * 
  860. X *
  861. X *--------------------------------------------------------------------------*/
  862. X
  863. Xstatic char rcsid[] = "$Id: backup.c,v 1.2 1994/09/17 16:00:49 tbp Exp $";
  864. X
  865. X#include <sys/types.h>
  866. X#include <sys/ipc.h>
  867. X#include <sys/shm.h>
  868. X#include <stdio.h>
  869. X#include <stdlib.h>
  870. X#include <string.h>
  871. X#include <fcntl.h>
  872. X#include <time.h>
  873. X#include <setjmp.h>
  874. X#include <errno.h>
  875. X#include <assert.h>
  876. X#include <signal.h>
  877. X#include <typhoon.h>
  878. X#include "../ty_dbd.h"
  879. X#include "../ty_type.h"
  880. X#include "../ty_glob.h"
  881. X#include "../ty_prot.h"
  882. X#include "../ty_log.h"
  883. X#include "util.h"
  884. X
  885. X/*------------------------------- Constants --------------------------------*/
  886. X#define VERSION            "1.00"
  887. X#define BLOCK_SIZE        512
  888. X#define OUTBUF_SIZE        (BLOCK_SIZE * 512)
  889. X#define INBUF_SIZE        (64 * 1024)
  890. X
  891. X/*-------------------------- Function prototypes ---------------------------*/
  892. Xstatic void        SignalHandler            PRM( (int); )
  893. Xstatic void        Write                    PRM( (void *, ulong); )
  894. Xstatic void        Flush                    PRM( (void); )
  895. Xstatic void        DisplayProgress            PRM( (char *, ulong); )
  896. Xstatic void        BackupDatabase            PRM( (void); )
  897. Xstatic void     BackupFile                PRM( (char *); )
  898. Xstatic void        help                    PRM( (void); )
  899. X
  900. X/*---------------------------- Global variables ----------------------------*/
  901. Xstatic ArchiveMediaHeader    mediahd;    /* Archive media header                */
  902. Xstatic jmp_buf    err_jmpbuf;                /* Jumped to on error                */
  903. Xstatic Dbentry    dbd;                    /* DBD anchor                        */
  904. Xstatic int        verbose = 0;            /* Be verbose?                        */
  905. Xstatic int        archive_fh = -1;        /* Archive file handle                */
  906. Xstatic char        *dbname = "";            /* Database name                    */
  907. Xstatic char        *datapath = "";            /* Path for database files            */
  908. Xstatic char        *device = "/dev/null";    /* Backup device                    */
  909. Xstatic char        *outbuf;                /* Output buffer                    */
  910. Xstatic ulong    outbytes;                /* Number of bytes in outbuf        */
  911. Xstatic ulong    total_written = 0;        /* Total number of bytes written    */
  912. X       int        db_status;                /* Required by ../read_dbd.c        */
  913. X
  914. X
  915. X/*--------------------------------------------------------------------------*\
  916. X *
  917. X * Function  : SignalHandler
  918. X *
  919. X * Purpose   : 
  920. X *
  921. X * Parameters: 
  922. X *
  923. X * Returns   : 
  924. X *
  925. X */
  926. Xstatic void SignalHandler(sig)
  927. Xint sig;
  928. X{
  929. X    if( sig == SIGSEGV )
  930. X        puts("Segmentation violation");
  931. X    else if( sig == SIGBUS )
  932. X        puts("Bus error");
  933. X
  934. X    dbd.shm->backup_active = 0;
  935. X    shm_free(&dbd);
  936. X    unlink(LOG_FNAME);
  937. X    puts("Restore aborted.");
  938. X    exit(1);
  939. X}
  940. X
  941. X
  942. X
  943. X/*--------------------------------------------------------------------------*\
  944. X *
  945. X * Function  : Write
  946. X *
  947. X * Purpose   : Write a block of data to the archive. If data cannot be
  948. X *               written because the backup media is full, the user will
  949. X *               be prompted to insert a new media.
  950. X *
  951. X * Parameters: buf        - Buffer to write.
  952. X *               size        - Number of bytes in buffer.
  953. X *
  954. X * Returns   : Nothing.
  955. X *
  956. X */
  957. Xstatic void Write(buf, size)
  958. Xvoid *buf;
  959. Xulong size;
  960. X{
  961. X    ArchiveBlockHeader    blockhd;
  962. X    char                s[20];
  963. X    ulong                copymax;
  964. X    long                rc;
  965. X
  966. X    /* Copy as much as possible to the output buffer */
  967. X    copymax = size;
  968. X    if( copymax > OUTBUF_SIZE-outbytes )
  969. X        copymax = OUTBUF_SIZE-outbytes;
  970. X
  971. X    memcpy(outbuf+outbytes, buf, copymax);
  972. X    outbytes += copymax;
  973. X
  974. Xretry:
  975. X    while( archive_fh == -1 )
  976. X    {
  977. X        clock_off();
  978. X        printf("Insert backup media no %d [enter, q]", mediahd.seqno);
  979. X        fflush(stdout);
  980. X        gets(s);
  981. X        clock_on();
  982. X        
  983. X        if( s[0] == 'q' )
  984. X            return;
  985. X            
  986. X        if( (archive_fh = open(device, O_WRONLY)) == -1 )
  987. X            printf("Cannot open '%s' (errno %d)\n", device, errno);
  988. X    }
  989. X
  990. X    if( outbytes == OUTBUF_SIZE )
  991. X    {
  992. X        rc = write(archive_fh, outbuf, OUTBUF_SIZE);
  993. X        
  994. X        if( rc == -1 )
  995. X        {
  996. X            printf("Write error (errno %d)\n", errno);
  997. X            longjmp(err_jmpbuf, 1);
  998. X        }
  999. X        else if( rc != OUTBUF_SIZE )
  1000. X        {
  1001. X            close(archive_fh);
  1002. X            goto retry;
  1003. X        }
  1004. X
  1005. X        /* Now copy the rest of the buffer */
  1006. X        outbytes = size - copymax;
  1007. X        memcpy(outbuf, (char *)buf + copymax, outbytes);
  1008. X
  1009. X        total_written += rc;
  1010. X    }
  1011. X}
  1012. X
  1013. X
  1014. Xstatic void Flush()
  1015. X{
  1016. X    long rc;
  1017. X
  1018. X    /* Ensure that a complete block is written to archive */
  1019. X    outbytes += (BLOCK_SIZE - (outbytes % BLOCK_SIZE));
  1020. X
  1021. X    if( (rc = write(archive_fh, outbuf, outbytes)) != outbytes )
  1022. X    {
  1023. X        printf("Write error (errno %d, rc %ld)\n", errno, rc);
  1024. X        longjmp(err_jmpbuf, 1);
  1025. X    }
  1026. X
  1027. X    total_written += rc;
  1028. X    outbytes = 0;
  1029. X}
  1030. X
  1031. X
  1032. X/*--------------------------------------------------------------------------*\
  1033. X *
  1034. X * Function  : DisplayProgress
  1035. X *
  1036. X * Purpose   : Prints the number of bytes read so far from the current table.
  1037. X *
  1038. X * Parameters: table        - Table name.
  1039. X *               bytes        - Number of bytes read.
  1040. X *
  1041. X * Returns   : Nothing.
  1042. X *
  1043. X */
  1044. Xstatic void DisplayProgress(table, bytes)
  1045. Xchar *table;
  1046. Xulong bytes;
  1047. X{
  1048. X    printf("\rReading %-26.26s  %10s bytes", table, printlong(bytes));
  1049. X    fflush(stdout);
  1050. X}
  1051. X
  1052. X
  1053. X/*--------------------------------------------------------------------------*\
  1054. X *
  1055. X * Function  : BackupDatabase
  1056. X *
  1057. X * Purpose   : Controls the backup.
  1058. X *
  1059. X * Parameters: None.
  1060. X *
  1061. X * Returns   : Nothing.
  1062. X *
  1063. X */
  1064. Xstatic void BackupDatabase()
  1065. X{
  1066. X    ArchiveRecordHeader recordhd;
  1067. X    ArchiveTableHeader    tablehd;
  1068. X    Record        *rec;
  1069. X    ulong        recid;                /* Record ID of current table            */
  1070. X    ulong        recno;                /* Current record in current table        */
  1071. X    ulong        recsize;            /* Record size in current table            */
  1072. X    ulong        bytecount;            /* Number of bytes read in current table*/
  1073. X    ulong        numread;            /* Number of bytes read                    */
  1074. X    ulong        timeout;
  1075. X    int            fh;
  1076. X    int            maxread, i, rc;
  1077. X    char        fname[128], objname[128];
  1078. X    char        buf[INBUF_SIZE];
  1079. X    RECORD        filehd;
  1080. X    
  1081. X    dbd.shm->backup_active = 1;
  1082. X
  1083. X    for( rec=dbd.record, recid=0; recid<dbd.header.records; recid++, rec++ )
  1084. X    {
  1085. X        dbd.shm->curr_recid = recid;
  1086. X
  1087. X        sprintf(fname, "%s/%s", datapath, dbd.file[rec->fileid].name);
  1088. X        sprintf(objname, "table %s", rec->name);
  1089. X        
  1090. X        if( (fh = os_open(fname, O_RDONLY|O_BINARY, 0)) == -1 )
  1091. X        {
  1092. X            printf("Cannot open '%s'\n", fname);
  1093. X            return;
  1094. X        }
  1095. X
  1096. X        /* Because of referential integrity data, the record size may
  1097. X         * be different from rec->size, so we read the header for H.recsize.
  1098. X         */
  1099. X        read(fh, &filehd.H, sizeof filehd.H);
  1100. X
  1101. X        recsize        = filehd.H.recsize;
  1102. X        maxread        = INBUF_SIZE / recsize;
  1103. X        bytecount    = 0;
  1104. X        recno        = 0;
  1105. X
  1106. X        /* Write table header */
  1107. X        strcpy(tablehd.fname, dbd.file[rec->fileid].name);
  1108. X        strcpy(tablehd.table, rec->name);
  1109. X        tablehd.id        = ARCHIVE_TABLE;
  1110. X        tablehd.recsize    = recsize;
  1111. X        Write(&tablehd, sizeof tablehd);
  1112. X
  1113. X        if( verbose )
  1114. X            DisplayProgress(objname, 0);
  1115. X
  1116. X        do
  1117. X        {
  1118. X            for( i=0; i<maxread; i++ )
  1119. X            {
  1120. X                dbd.shm->curr_recno = recno;
  1121. X
  1122. X                lseek(fh, recno * recsize, SEEK_SET);
  1123. X                numread = read(fh, buf, recsize);
  1124. X
  1125. X                if( numread != recsize )
  1126. X                    break;
  1127. X
  1128. X                recordhd.id        = ARCHIVE_RECORD;
  1129. X                recordhd.recid    = recid;
  1130. X                recordhd.recno    = recno;
  1131. X
  1132. X                Write(&recordhd, sizeof recordhd);
  1133. X                Write(buf, numread);
  1134. X
  1135. X                bytecount += recsize;
  1136. X                recno++;
  1137. X            }            
  1138. X
  1139. X            if( verbose )
  1140. X                DisplayProgress(objname, bytecount);
  1141. X        }
  1142. X        while( i == maxread );
  1143. X
  1144. X        if( verbose )
  1145. X            puts("");
  1146. X
  1147. X        close(fh);
  1148. X    }
  1149. X
  1150. X    /* Set curr_recid to max value, so that all changes are logged */
  1151. X    dbd.shm->curr_recid = 0xffffffff;
  1152. X    dbd.shm->backup_active = 0;
  1153. X    
  1154. X    /* Wait for last transaction to complete */
  1155. X    timeout = 120;
  1156. X    while( dbd.shm->num_trans_active > 0 && timeout-- )
  1157. X        sleep(1);
  1158. X}
  1159. X
  1160. X
  1161. X
  1162. X/*--------------------------------------------------------------------------*\
  1163. X *
  1164. X * Function  : BackupFile
  1165. X *
  1166. X * Purpose   : Write a sequential file to archive.
  1167. X *
  1168. X * Parameters: fname    - File name.
  1169. X *
  1170. X * Returns   : Nothing.
  1171. X *
  1172. X */
  1173. Xstatic void BackupFile(fname)
  1174. Xchar *fname;
  1175. X{
  1176. X    ArchiveFileHeader    filehd;
  1177. X    ArchiveFileDataHeader datahd;
  1178. X    int                    fh;
  1179. X    char                buf[INBUF_SIZE];
  1180. X    ulong                numread;
  1181. X    ulong                bytecount=0;
  1182. X
  1183. X    if( (fh = open(fname, O_RDONLY)) == -1 )
  1184. X    {
  1185. X        printf("Cannot open '%s'\n", fname);
  1186. X        return;
  1187. X    }        
  1188. X
  1189. X    datahd.id = ARCHIVE_FILEDATA;
  1190. X    filehd.id = ARCHIVE_FILE;
  1191. X    strcpy(filehd.fname, fname);
  1192. X    Write(&filehd, sizeof filehd);
  1193. X
  1194. X    while( numread = read(fh, buf, INBUF_SIZE) )
  1195. X    {
  1196. X        datahd.size = numread;
  1197. X        Write(&datahd, sizeof datahd);
  1198. X        Write(buf, numread);
  1199. X
  1200. X        bytecount += numread;
  1201. X
  1202. X        if( verbose )
  1203. X            DisplayProgress(fname, bytecount);
  1204. X    }
  1205. X
  1206. X    datahd.size = 0;
  1207. X    Write(&datahd, sizeof datahd);
  1208. X
  1209. X    if( verbose )
  1210. X        puts("");
  1211. X
  1212. X    close(fh);
  1213. X}
  1214. X
  1215. X
  1216. X
  1217. X
  1218. Xstatic void help()
  1219. X{
  1220. X    puts("Syntax: tybackup database [option]...\n"
  1221. X         "Options:\n"
  1222. X         "    -d<device>      Backup device\n"
  1223. X         "    -f<path>        Path for data files\n"
  1224. X         "    -v              Be verbose\n");
  1225. X    exit(1);
  1226. X}
  1227. X
  1228. X
  1229. X
  1230. Xmain(argc, argv)
  1231. Xint        argc;
  1232. Xchar     *argv[];
  1233. X{
  1234. X    ArchiveEnd            end;
  1235. X    char                dbdname[20];
  1236. X    int                    i;
  1237. X
  1238. X    /* The output buffer MUST be bigger than the input buffer */
  1239. X    assert(INBUF_SIZE < OUTBUF_SIZE);
  1240. X
  1241. X    printf("Typhoon Online Backup version %s\n", VERSION);
  1242. X
  1243. X    if( argc < 3 )
  1244. X        help();
  1245. X
  1246. X    for( i=2; i<argc; i++ )
  1247. X    {
  1248. X        switch( *argv[i] )
  1249. X        {
  1250. X            case '-':
  1251. X            case '/':
  1252. X                switch( argv[i][1] )
  1253. X                {
  1254. X                    case 'd':
  1255. X                        device = argv[i]+2;
  1256. X                        break;
  1257. X                    case 'f':
  1258. X                        datapath = argv[i]+2;
  1259. X                        break;
  1260. X                    case 'v':
  1261. X                        verbose = 1;
  1262. X                        break;
  1263. X                    default:
  1264. X                        printf("Invalid option '%c'\n", argv[i][1]);
  1265. X                        break;
  1266. X                }
  1267. X                break;
  1268. X            default:
  1269. X                printf("Invalid switch '%c'\n", *argv[i]);
  1270. X                exit(1);
  1271. X        }
  1272. X    }
  1273. X
  1274. X    dbname = argv[1];
  1275. X    sprintf(dbdname, "%s.dbd", dbname);
  1276. X    if( read_dbdfile(&dbd, dbdname) != S_OKAY )
  1277. X    {
  1278. X        printf("Invalid dbd-file '%s'\n", dbdname);
  1279. X        return;
  1280. X    }
  1281. X
  1282. X    if( !(outbuf = (char *)malloc(OUTBUF_SIZE)) )
  1283. X    {
  1284. X        puts("Cannot allocate output buffer");
  1285. X        return;
  1286. X    }
  1287. X    outbytes = 0;    
  1288. X    
  1289. X    strcpy(dbd.name, dbname);
  1290. X    if( shm_alloc(&dbd) == -1 )
  1291. X    {
  1292. X        printf("Cannot allocate shared memory");
  1293. X        return;
  1294. X    }
  1295. X
  1296. X    signal(SIGINT,    SignalHandler);
  1297. X    signal(SIGTERM, SignalHandler);
  1298. X    signal(SIGQUIT, SignalHandler);
  1299. X    signal(SIGSEGV, SignalHandler);
  1300. X    signal(SIGBUS,  SignalHandler);
  1301. X    signal(SIGHUP, SIG_IGN);
  1302. X
  1303. X    if( setjmp(err_jmpbuf) )
  1304. X    {
  1305. X        if( verbose )
  1306. X            puts("Backup aborted.");
  1307. X        goto out;
  1308. X    }
  1309. X
  1310. X    /* Initialize media header */
  1311. X    memset(&mediahd, 0, sizeof mediahd);
  1312. X    strcpy(mediahd.dbname, dbname);
  1313. X    mediahd.id        = ARCHIVE_MEDIA;
  1314. X    mediahd.date    = time(NULL);
  1315. X    mediahd.seqno    = 1;
  1316. X
  1317. X    if( verbose )
  1318. X        printf("Backing up to %s\n", device);
  1319. X
  1320. X    Write(&mediahd, sizeof mediahd);
  1321. X
  1322. X    BackupFile(dbdname);
  1323. X    BackupDatabase();
  1324. X    BackupFile(LOG_FNAME);
  1325. X
  1326. X    end.id = ARCHIVE_END;
  1327. X    Write(&end, sizeof end);
  1328. X    Flush();
  1329. X    close(archive_fh);
  1330. X    clock_off();
  1331. X
  1332. X    if( verbose )
  1333. X    {
  1334. X        ulong secs = clock_secs();
  1335. X    
  1336. X        /* Guard against division by zero */
  1337. X        if( !secs )
  1338. X            secs = 1;
  1339. X    
  1340. X        printf("\rTotal %40s bytes\n", printlong(total_written));
  1341. X        printf("%s bytes/second\n", printlong(total_written / secs));
  1342. X        puts("Done.");
  1343. X    }
  1344. X
  1345. Xout:
  1346. X    free(outbuf);
  1347. X    shm_free(&dbd);
  1348. X    free(dbd.dbd);
  1349. X
  1350. X    unlink(LOG_FNAME);
  1351. X
  1352. X    return 0;
  1353. X}
  1354. X
  1355. X/* end-of-file */
  1356. END_OF_FILE
  1357.   if test 12068 -ne `wc -c <'typhoon/src/util/backup.c'`; then
  1358.     echo shar: \"'typhoon/src/util/backup.c'\" unpacked with wrong size!
  1359.   fi
  1360.   # end of 'typhoon/src/util/backup.c'
  1361. fi
  1362. if test -f 'typhoon/src/util/import.c' -a "${1}" != "-c" ; then 
  1363.   echo shar: Will not clobber existing file \"'typhoon/src/util/import.c'\"
  1364. else
  1365.   echo shar: Extracting \"'typhoon/src/util/import.c'\" \(12523 characters\)
  1366.   sed "s/^X//" >'typhoon/src/util/import.c' <<'END_OF_FILE'
  1367. X/*----------------------------------------------------------------------------
  1368. X * File    : import.c
  1369. X * Program : tyimport
  1370. X * OS      : UNIX, OS/2, DOS
  1371. X * Author  : Thomas B. Pedersen
  1372. X *
  1373. X * Copyright (c) 1994 Thomas B. Pedersen.  All rights reserved.
  1374. X *
  1375. X * Permission is hereby granted, without written agreement and without
  1376. X * license or royalty fees, to use, copy, modify, and distribute this
  1377. X * software and its documentation for any purpose, provided that the above
  1378. X * copyright notice and the following two  paragraphs appear (1) in all 
  1379. X * source copies of this software and (2) in accompanying documentation
  1380. X * wherever the programatic interface of this software, or any derivative
  1381. X * of it, is described.
  1382. X *
  1383. X * IN NO EVENT SHALL THOMAS B. PEDERSEN BE LIABLE TO ANY PARTY FOR DIRECT,
  1384. X * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
  1385. X * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF HE HAS BEEN 
  1386. X * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1387. X *
  1388. X * THOMAS B. PEDERSEN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
  1389. X * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  1390. X * A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" 
  1391. X * BASIS, AND THOMAS B. PEDERSEN HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
  1392. X * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  1393. X *
  1394. X * Description:
  1395. X *   Typhoon import utility.
  1396. X *
  1397. X * $Log: import.c,v $
  1398. X * Revision 1.2  1994/09/17  16:00:55  tbp
  1399. X * typhoon.h and environ.h are now included from <>.
  1400. X *
  1401. X * Revision 1.1  1994/09/13  21:28:58  tbp
  1402. X * Added to repository.
  1403. X *
  1404. X * Added to repository.
  1405. X * 
  1406. X *
  1407. X *--------------------------------------------------------------------------*/
  1408. X
  1409. Xstatic char rcsid[] = "$Id: import.c,v 1.2 1994/09/17 16:00:55 tbp Exp $";
  1410. X
  1411. X#include <stdio.h>
  1412. X#include <string.h>
  1413. X#include <ctype.h>
  1414. X#include <fcntl.h>
  1415. X#include <stdarg.h>
  1416. X#ifndef UNIX
  1417. X#  include <sys\types.h>
  1418. X#  include <sys\stat.h>
  1419. X#  include <stdlib.h>
  1420. X#  include <io.h>
  1421. X#endif
  1422. X#define DEFINE_GLOBALS
  1423. X#include <typhoon.h>
  1424. X#include "../ty_dbd.h"
  1425. X#include "../ty_type.h"
  1426. X#include "import.h"
  1427. X
  1428. X#define DEBUG(x)    
  1429. X
  1430. X
  1431. X/*-------------------------------- prototypes ------------------------------*/
  1432. Xstatic int  ReadValue        PRM( (int); )
  1433. Xstatic int  ReadString        PRM( (void); )
  1434. Xstatic int  ReadChar        PRM( (void); )
  1435. Xstatic int     ReadField        PRM( (Field *, unsigned); )
  1436. Xstatic int    GetControlField PRM( (Structdef *, unsigned); )
  1437. Xstatic int    ReadFields        PRM( (Structdef *, int, unsigned, int); )
  1438. Xstatic void    Import            PRM( (char *); )
  1439. X       int    yyparse            PRM( (void); )
  1440. Xstatic void import_error    PRM( (char * ELLIPSIS); )
  1441. X
  1442. X/*------------------------------ public variables --------------------------*/
  1443. X       FILE     *lex_file;
  1444. Xstatic FILE        *infile;
  1445. Xstatic char        *recbuf;
  1446. Xstatic char        *fldptr;
  1447. Xstatic int        fldtype;
  1448. Xstatic int        lineno;
  1449. Xstatic char        import_fname[256];
  1450. X
  1451. X/*------------------------------ local variables ---------------------------*/
  1452. Xstatic char paramhelp[] = "\
  1453. XSyntax: tyimport [option]... database[.dbd]\n\
  1454. XOptions:\n\
  1455. X    -f<path>    Specify data files path\n\
  1456. X    -g          Generate import specification\n";
  1457. X
  1458. X
  1459. X
  1460. Xistrcmp(s1, s2)
  1461. Xchar *s1, *s2;
  1462. X{
  1463. X    while( tolower(*s1) == tolower(*s2) && *s1 && *s2 )
  1464. X        s1++, s2++;
  1465. X    
  1466. X    return tolower(*s1) - tolower(*s2);
  1467. X}
  1468. X
  1469. X
  1470. X#ifdef PROTOTYPES
  1471. Xvoid err_quit(char *s, ...)
  1472. X#else
  1473. Xvoid err_quit(s)
  1474. Xchar *s;
  1475. X#endif
  1476. X{
  1477. X    va_list ap;
  1478. X    
  1479. X    va_start(ap, s);
  1480. X    vfprintf(stderr, s, ap);
  1481. X    puts("");
  1482. X    va_end(ap);
  1483. X    exit(1);
  1484. X}
  1485. X
  1486. X
  1487. X#ifdef PROTOTYPES
  1488. Xvoid import_error(char *fmt, ...)
  1489. X#else
  1490. Xvoid import_error(fmt ELLIPSIS)
  1491. Xchar *fmt;
  1492. X#endif
  1493. X{
  1494. X    va_list ap;
  1495. X
  1496. X    printf("%s %d: ", import_fname, lineno);
  1497. X    va_start(ap, fmt);
  1498. X    vprintf(fmt, ap);
  1499. X    puts("");
  1500. X    va_end(ap);
  1501. X    errors++;
  1502. X}
  1503. X
  1504. X
  1505. X
  1506. X/* Floats not supported!!! */
  1507. X
  1508. Xstatic ReadValue(c)
  1509. Xint c;
  1510. X{
  1511. X    /* Integer formats:  002 (octal) 0x29 (hex) 231 (decimal) */
  1512. X    ulong value;
  1513. X    int negate = 0;
  1514. X
  1515. X    if( c == '-' )
  1516. X    {
  1517. X        negate = 1;
  1518. X        c = getc(infile);
  1519. X    }
  1520. X
  1521. X    if( c == '0' )
  1522. X    {
  1523. X        value = 0;
  1524. X
  1525. X        c = getc(infile);
  1526. X
  1527. X        if( c == 'x' )
  1528. X        {
  1529. X            while( (c = getc(infile)) && isxdigit(c) )
  1530. X            {
  1531. X                if( isdigit(c) )
  1532. X                    value = value * 16 + c - '0';
  1533. X                else
  1534. X                    value = value * 16 + 6 + tolower(c) - 'a';
  1535. X            }
  1536. X            ungetc(c, infile);
  1537. X        }
  1538. X        else if( isdigit(c) )
  1539. X        {
  1540. X            do
  1541. X            {
  1542. X                value = value * 8 + c - '0';
  1543. X                c = getc(infile);
  1544. X            }
  1545. X            while( isdigit(c) );
  1546. X            ungetc(c, infile);
  1547. X        }
  1548. X        else
  1549. X            ungetc(c, infile);
  1550. X    }
  1551. X    else
  1552. X    {
  1553. X        value = c - '0';
  1554. X
  1555. X        c = getc(infile);
  1556. X
  1557. X        while( isdigit(c) )
  1558. X        {
  1559. X            value = value * 10 + c - '0';
  1560. X            c = getc(infile);
  1561. X        }
  1562. X
  1563. X/*
  1564. X        do 
  1565. X        {
  1566. X            value = value * 10 + c - '0';
  1567. X            c = getc(infile);
  1568. X        }
  1569. X        while( isdigit(c) );*/
  1570. X        ungetc(c, infile);
  1571. X    }
  1572. X
  1573. X    if( fldtype & FT_UNSIGNED )
  1574. X    {
  1575. X        switch( fldtype )
  1576. X        {
  1577. X            case FT_UNSIGNED|FT_CHAR:    *(uchar *)fldptr    = value;    break;
  1578. X            case FT_UNSIGNED|FT_SHORT:    *(ushort *)fldptr    = value;    break;
  1579. X            case FT_UNSIGNED|FT_INT:    *(unsigned *)fldptr    = value;    break;
  1580. X            case FT_UNSIGNED|FT_LONG:    *(ulong *)fldptr    = value;    break;
  1581. X        }
  1582. X
  1583. X        DEBUG( printf("%lu \n", (ulong)value); )
  1584. X    }
  1585. X    else
  1586. X    {
  1587. X        long svalue = negate ? -value : value;
  1588. X
  1589. X        switch( fldtype )
  1590. X        {
  1591. X            case FT_CHAR:      *(char *)fldptr       = svalue;    break;
  1592. X            case FT_SHORT:     *(short *)fldptr    = svalue;    break;
  1593. X            case FT_INT:       *(int *)fldptr        = svalue;    break;
  1594. X            case FT_LONG:      *(long *)fldptr       = svalue;    break;
  1595. X            case FT_FLOAT:
  1596. X            case FT_DOUBLE:    puts("floats not supported"); exit(1);
  1597. X        }
  1598. X
  1599. X        DEBUG( printf("%ld \n", (long)value); )
  1600. X    }
  1601. X
  1602. X    return 0;
  1603. X}
  1604. X
  1605. X
  1606. X
  1607. X/* check for max length */
  1608. X
  1609. Xstatic ReadString()
  1610. X{
  1611. X    char *p = fldptr;
  1612. X    int c;
  1613. X
  1614. X    while( (*p = getc(infile)) != '"' )
  1615. X    {
  1616. X        if( *p == '\\' )
  1617. X        {
  1618. X            switch( c = getc(infile) )
  1619. X            {    
  1620. X                case 'n':                            /* Newline                */
  1621. X                    *p = '\n';
  1622. X                    break;
  1623. X                case '\\':                            /* Backslash            */
  1624. X                    *p = '\\';
  1625. X                    break;
  1626. X                case '\"':                            /* Double-quote            */
  1627. X                    *p = '"';
  1628. X                    break;
  1629. X                case 'x':                            /* Hexadecimal number    */
  1630. X                case 'X':
  1631. X                    c = getc(infile);
  1632. X                    if( isxdigit(c) )
  1633. X                    {
  1634. X                        *p = isalpha(c) ? tolower(c) - 'a' + 10 : c - '0';
  1635. X                        c = getc(infile);
  1636. X                        if( isxdigit(c) )
  1637. X                        {
  1638. X                            *p <<= 4;
  1639. X                            *p += isalpha(c) ? tolower(c) - 'a' + 10 : c - '0';
  1640. X                        }
  1641. X                        else
  1642. X                            ungetc(c, infile);
  1643. X                    }
  1644. X/*                    *p = 0;
  1645. X                    c = getc(infile);
  1646. X
  1647. X                    while( isxdigit(c) )
  1648. X                    {
  1649. X                         if( isdigit(c) )
  1650. X                             *p = *p * 16 + c - '0';
  1651. X                         else
  1652. X                             *p = *p * 16 + 10 + tolower(c) - 'a';
  1653. X                         c = getc(infile);
  1654. X                    }
  1655. X
  1656. X                    ungetc(c, infile);*/
  1657. X                    break;
  1658. X                default:
  1659. X                    import_error("illegal character '%c' following '\\'", c);
  1660. X                    break;
  1661. X            }          
  1662. X        }
  1663. X
  1664. X        p++;        
  1665. X    }
  1666. X    *p = 0;
  1667. X
  1668. X    DEBUG( printf("\"%s\"\n", fldptr); )
  1669. X
  1670. X    return 0;
  1671. X}
  1672. X
  1673. X
  1674. Xstatic ReadChar()
  1675. X{
  1676. X    int c = getc(infile);
  1677. X    int value, tmp;
  1678. X
  1679. X    if( c == '\\' )
  1680. X    {
  1681. X        switch( tmp = getc(infile) )
  1682. X        {
  1683. X            case 'n':    value = '\n';    break;
  1684. X            case 'r':    value = '\r';    break;
  1685. X            case 't':    value = '\t';    break;
  1686. X            case '\"':
  1687. X            case '\\':
  1688. X            case '\'':    value = tmp;    break;
  1689. X            case 'x':
  1690. X                c = getc(infile);
  1691. X                value = 0;
  1692. X
  1693. X                while( isxdigit(c) )
  1694. X                {
  1695. X                     if( isdigit(c) )
  1696. X                         value = value * 16 + c - '0';
  1697. X                     else
  1698. X                         value = value * 16 + 10 + tolower(c) - 'a';
  1699. X                     c = getc(infile);
  1700. X                }
  1701. X
  1702. X                ungetc(c, infile);
  1703. X                break;
  1704. X            default:
  1705. X                import_error("invalid character constant");
  1706. X                return -1;
  1707. X        }
  1708. X    }
  1709. X    else
  1710. X        value = c;
  1711. X
  1712. X    if( getc(infile) != '\'' )
  1713. X        import_error("unterminated character constant");
  1714. X
  1715. X    switch( FT_GETBASIC(fldtype) )
  1716. X    {
  1717. X        case FT_CHAR:    *(char *)fldptr = value;    break;
  1718. X        case FT_INT:    *(int *)fldptr = value;        break;
  1719. X        case FT_SHORT:    *(short *)fldptr = value;    break;
  1720. X        case FT_LONG:    *(long *)fldptr = value;    break;
  1721. X    }
  1722. X
  1723. X    DEBUG( printf("'%c'\n", value); )
  1724. X
  1725. X    return 0;
  1726. X}
  1727. X
  1728. X
  1729. Xstatic ReadField(fld, offset)
  1730. XField *fld;
  1731. Xunsigned offset;
  1732. X{
  1733. X    int c;
  1734. X
  1735. X    fldptr     = recbuf + offset;
  1736. X    fldtype = FT_GETBASIC(fld->type);
  1737. X
  1738. X    for( ;; )
  1739. X    {
  1740. X        c = getc(infile);
  1741. X
  1742. X        if( c == ' ' || c == '\t' || c == '{' || c == '}' || c == ',' )
  1743. X            ;
  1744. X        else if( isdigit(c) || c == '-' )
  1745. X            return ReadValue(c);
  1746. X        else if( c == '"' )
  1747. X            return ReadString();
  1748. X        else if( c == '\'' )
  1749. X            return ReadChar();
  1750. X        else if( c == '\n' )
  1751. X            lineno++;
  1752. X        else if( c == '/' )
  1753. X        {
  1754. X            if( (c = getc(infile)) == '*' )    /* C comment                       */
  1755. X                lex_skip_comment();
  1756. X            else if( c == '/' )                   /* C++ comment                     */
  1757. X            {
  1758. X                while( getc(infile) != '\n' && !feof(infile) )
  1759. X                    ;
  1760. X                lineno++;
  1761. X            }
  1762. X            else
  1763. X                import_error("unexpected '/'\n");
  1764. X        }
  1765. X        else if( c == EOF )
  1766. X            return -1;
  1767. X        else
  1768. X            import_error("unexpected '%c'\n", c);
  1769. X    }
  1770. X}
  1771. X
  1772. X
  1773. X
  1774. Xstatic GetControlField(str, offset)
  1775. XStructdef *str;
  1776. Xunsigned offset;
  1777. X{
  1778. X    return recbuf[offset + dbd.field[str->control_field].offset];
  1779. X}
  1780. X
  1781. X
  1782. X
  1783. Xstatic ReadFields(str, nest, offset, control_value)
  1784. XStructdef *str;
  1785. Xint nest;
  1786. Xunsigned offset;
  1787. X{
  1788. X    Field    *fld        = dbd.field + str->first_member;
  1789. X    int     fields        = str->members;
  1790. X    int     old_fields    = fields;
  1791. X    int     i, n, rc;
  1792. X
  1793. X    if( str->is_union )
  1794. X        fld += control_value;
  1795. X
  1796. X    while( fields-- )
  1797. X    {
  1798. X        if( fld->size != fld->elemsize && FT_GETBASIC(fld->type) != FT_CHARSTR )
  1799. X        {
  1800. X            if( fld->type & FT_VARIABLE )
  1801. X                n = *(ushort *)(recbuf + dbd.field[ fld->keyid ].offset);
  1802. X            else
  1803. X                n = fld->size / fld->elemsize;
  1804. X        }
  1805. X        else
  1806. X            n = 1;
  1807. X
  1808. X        for( i=0; i<n; i++ )
  1809. X        {
  1810. X            if( FT_GETBASIC(fld->type) == FT_STRUCT )
  1811. X            {
  1812. X                Structdef *struc = dbd.structdef + fld->structid;
  1813. X
  1814. X                rc  = ReadFields(struc, nest+1, 
  1815. X                        offset + fld->offset + i * fld->elemsize,
  1816. X                         struc->is_union ? GetControlField(struc, offset) : 0);
  1817. X            }
  1818. X            else if( fld->nesting == nest && fld->type & FT_INCLUDE )
  1819. X            {
  1820. X                DEBUG( printf("%s = ", fld->name); )
  1821. X            
  1822. X                if( ReadField(fld, offset + fld->offset + fld->elemsize * i) == -1 )
  1823. X                    return -1;
  1824. X            }
  1825. X        }
  1826. X
  1827. X        /* If n was 0 this array was a variable length array of size 0.
  1828. X         * Move fld to the next field at the same nesting.
  1829. X          */
  1830. X        if( n == 0 )
  1831. X        {
  1832. X            rc = 0;
  1833. X
  1834. X            if( !fields )
  1835. X                break;
  1836. X
  1837. X            do
  1838. X                rc++;
  1839. X            while( fld[rc].nesting != fld->nesting );
  1840. X            rc--;
  1841. X        }
  1842. X
  1843. X        if( FT_GETBASIC(fld->type) == FT_STRUCT )
  1844. X        {
  1845. X               old_fields += rc;
  1846. X            fld += rc;
  1847. X        }
  1848. X
  1849. X        fld++;
  1850. X
  1851. X        if( str->is_union )
  1852. X            break;
  1853. X    }
  1854. X
  1855. X    return old_fields;
  1856. X}
  1857. X
  1858. X
  1859. Xstatic void ImportTable(recid)
  1860. Xulong recid;
  1861. X{
  1862. X    Record *rec = &dbd.record[recid];
  1863. X    ulong count=0;
  1864. X
  1865. X    recid = INTERN_TO_RECID(recid);
  1866. X
  1867. X    memset(recbuf, 0, rec->size);
  1868. X
  1869. X    while( ReadFields(&dbd.structdef[rec->structid], 0, 0, 0) != -1 )
  1870. X    {
  1871. X        if( d_fillnew(recid, recbuf) != S_OKAY )
  1872. X            printf("d_fillnew: db_status %d, db_subcode %d\n", 
  1873. X                db_status, db_subcode);
  1874. X        memset(recbuf, 0, rec->size);
  1875. X
  1876. XDEBUG( puts(""); )
  1877. X    }
  1878. X}
  1879. X
  1880. X
  1881. Xstatic void Import(dbname)
  1882. Xchar *dbname;
  1883. X{
  1884. X    int i;
  1885. X
  1886. X    if( d_open(dbname, "s") != S_OKAY )
  1887. X        err_quit("Cannot open database '%s'", dbname);
  1888. X
  1889. X    for( i=0; i<dbd.header.records; i++ )
  1890. X    {
  1891. X        if( dbd.record[i].aux )
  1892. X        {
  1893. X            lineno = 1;
  1894. X            sprintf(import_fname, "%s.kom", dbd.record[i].name);
  1895. X
  1896. X            if( !(infile = fopen(import_fname, "r")) )
  1897. X                err_quit("Cannot open '%s'", import_fname);
  1898. X
  1899. X            printf("importing from '%s'\n", import_fname);
  1900. X            ImportTable(i);
  1901. X            fclose(infile);
  1902. X        }
  1903. X    }
  1904. X
  1905. X    d_close();
  1906. X}
  1907. X
  1908. X
  1909. X
  1910. Xmain(argc, argv)
  1911. Xchar *argv[];
  1912. X{
  1913. X    char *p, *realname;
  1914. X    int i;
  1915. X    long n=0, prev;
  1916. X    unsigned biggest_rec=0;
  1917. X
  1918. X    puts("Typhoon Import Utility version 1.06");
  1919. X
  1920. X    if( argc == 1 )
  1921. X    {
  1922. X        printf(paramhelp);
  1923. X        exit(1);
  1924. X    }
  1925. X
  1926. X    /* Imtract the real name of the file */
  1927. X    if( (realname = strrchr(argv[argc-1], DIR_SWITCH)) != NULL )
  1928. X        realname++;
  1929. X    else
  1930. X        realname = argv[argc-1];
  1931. X
  1932. X    /* remove extension if present */
  1933. X    if( p = strstr(realname, ".") )
  1934. X        *p = 0;
  1935. X
  1936. X    /* generate file names for .ddl-file, .dbd-file and header file */
  1937. X    sprintf(dbd_fname,     "%s.dbd", realname);
  1938. X    sprintf(spec_fname,  "%s.imp", realname);
  1939. X
  1940. X    if( read_dbdfile(&dbd, dbd_fname) != S_OKAY )
  1941. X        err_quit("Cannot open '%s'\n", dbd_fname);
  1942. X
  1943. X    /* Find the size of the biggest record */
  1944. X    for( i=0; i<dbd.header.records; i++ )
  1945. X        if( biggest_rec < dbd.record[i].size )
  1946. X            biggest_rec = dbd.record[i].size;
  1947. X
  1948. X    /* Allocate record buffer */
  1949. X    if( !(recbuf = (char *)malloc(biggest_rec)) )
  1950. X        err_quit("Out of memory");
  1951. X
  1952. X    /* process command line options */
  1953. X    for( i=1; i<argc-1; i++ )
  1954. X    {
  1955. X        if( argv[i][0] == '-' || argv[i][0] == '/' )
  1956. X        {
  1957. X            switch( argv[i][1] )
  1958. X            {
  1959. X                case 'f':
  1960. X                    if( d_dbfpath(argv[i]+2) != S_OKAY )
  1961. X                        err_quit("Invalid data files path");
  1962. X                    break;
  1963. X                case 'g':
  1964. X                    GenerateImportSpec(realname);
  1965. X                    exit(1);
  1966. X                default:
  1967. X                    err_quit("unknown command line option");
  1968. X            }
  1969. X        }
  1970. X        else
  1971. X            err_quit("unknown command line option");
  1972. X    }
  1973. X
  1974. X    /* Read the import specification */
  1975. X    ReadImportSpec(realname);
  1976. X
  1977. X    if( !errors )
  1978. X        Import(realname);
  1979. X
  1980. X    free(dbd.dbd);
  1981. X    free(recbuf);
  1982. X}
  1983. X
  1984. X
  1985. X/* end-of-file */
  1986. END_OF_FILE
  1987.   if test 12523 -ne `wc -c <'typhoon/src/util/import.c'`; then
  1988.     echo shar: \"'typhoon/src/util/import.c'\" unpacked with wrong size!
  1989.   fi
  1990.   # end of 'typhoon/src/util/import.c'
  1991. fi
  1992. if test -f 'typhoon/src/util/restore.c' -a "${1}" != "-c" ; then 
  1993.   echo shar: Will not clobber existing file \"'typhoon/src/util/restore.c'\"
  1994. else
  1995.   echo shar: Extracting \"'typhoon/src/util/restore.c'\" \(13959 characters\)
  1996.   sed "s/^X//" >'typhoon/src/util/restore.c' <<'END_OF_FILE'
  1997. X/*----------------------------------------------------------------------------
  1998. X * File    : restore.c
  1999. X * Program : tybackup
  2000. X * OS      : UNIX, OS/2, DOS
  2001. X * Author  : Thomas B. Pedersen
  2002. X *
  2003. X * Copyright (c) 1994 Thomas B. Pedersen.  All rights reserved.
  2004. X *
  2005. X * Permission is hereby granted, without written agreement and without
  2006. X * license or royalty fees, to use, copy, modify, and distribute this
  2007. X * software and its documentation for any purpose, provided that the above
  2008. X * copyright notice and the following two  paragraphs appear (1) in all 
  2009. X * source copies of this software and (2) in accompanying documentation
  2010. X * wherever the programatic interface of this software, or any derivative
  2011. X * of it, is described.
  2012. X *
  2013. X * IN NO EVENT SHALL THOMAS B. PEDERSEN BE LIABLE TO ANY PARTY FOR DIRECT,
  2014. X * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
  2015. X * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF HE HAS BEEN 
  2016. X * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2017. X *
  2018. X * THOMAS B. PEDERSEN SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
  2019. X * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  2020. X * A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" 
  2021. X * BASIS, AND THOMAS B. PEDERSEN HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
  2022. X * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  2023. X *
  2024. X * Description:
  2025. X *   Contains the tyrestore utility.
  2026. X *
  2027. X * Functions:
  2028. X *
  2029. X * $Log: restore.c,v $
  2030. X * Revision 1.2  1994/09/17  16:00:56  tbp
  2031. X * typhoon.h and environ.h are now included from <>.
  2032. X *
  2033. X * Revision 1.1  1994/09/13  21:29:00  tbp
  2034. X * Added to repository.
  2035. X *
  2036. X * Added to repository.
  2037. X * 
  2038. X *
  2039. X *--------------------------------------------------------------------------*/
  2040. X
  2041. Xstatic char rcsid[] = "$Id: restore.c,v 1.2 1994/09/17 16:00:56 tbp Exp $";
  2042. X
  2043. X#include <sys/types.h>
  2044. X#include <sys/ipc.h>
  2045. X#include <sys/shm.h>
  2046. X#include <stdio.h>
  2047. X#include <stdlib.h>
  2048. X#include <string.h>
  2049. X#include <fcntl.h>
  2050. X#include <time.h>
  2051. X#include <setjmp.h>
  2052. X#include <errno.h>
  2053. X#include <assert.h>
  2054. X#include <signal.h>
  2055. X#include <typhoon.h>
  2056. X#include "../ty_dbd.h"
  2057. X#include "../ty_type.h"
  2058. X#include "../ty_glob.h"
  2059. X#include "../ty_prot.h"
  2060. X#include "../ty_log.h"
  2061. X#include "util.h"
  2062. X
  2063. X/*------------------------------- Constants --------------------------------*/
  2064. X#define VERSION            "1.00"
  2065. X#define BLOCK_SIZE        512
  2066. X#define OUTBUF_SIZE        (BLOCK_SIZE * 128)
  2067. X#define INBUF_SIZE        (256 * 1024)
  2068. X
  2069. X/*-------------------------- Function prototypes ---------------------------*/
  2070. Xstatic void     SignalHandler            PRM( (int); )
  2071. Xstatic void        Read                    PRM( (void *, ulong); )
  2072. Xstatic void        DisplayProgress            PRM( (char *, ulong); )
  2073. Xstatic void        RestoreDatabase            PRM( (void); )
  2074. Xstatic void        RestoreFile                PRM( (char *); )
  2075. Xstatic void        RestoreDbdFile            PRM( (void); )
  2076. Xstatic void        RestoreLogFile            PRM( (void); )
  2077. Xstatic void     help                    PRM( (void); )
  2078. X       void        FixLog                    PRM( (char *); )
  2079. X
  2080. X/*---------------------------- Global variables ----------------------------*/
  2081. Xstatic ArchiveMediaHeader    mediahd;    /* Archive media header                */
  2082. Xstatic Dbentry    dbd;                    /* DBD anchor                        */
  2083. Xstatic int        archive_fh = -1;        /* Archive file handle                */
  2084. Xstatic char        dbname[DBNAME_LEN+1];    /* Database name                    */
  2085. Xstatic char        *device = "/dev/null";    /* Archive device                    */
  2086. Xstatic ulong    curr_id;                /* Current block header id            */
  2087. Xstatic char        *inbuf;                    /* Input buffer                        */
  2088. Xstatic ulong    inreadpos;                /* Current read position in buffer    */
  2089. Xstatic ulong    inbytes;                /* Number of bytes in outbuf        */
  2090. Xstatic ulong    total_read = 0;            /* Total number of bytes read         */
  2091. X       jmp_buf    err_jmpbuf;                /* Jumped to on error                */
  2092. X       char        *datapath = "";            /* Database file path                */
  2093. X       int        db_status;                /* Required by ../read_dbd.c        */
  2094. X       int        verbose = 0;            /* Be verbose?                        */
  2095. X
  2096. X
  2097. X
  2098. X/*--------------------------------------------------------------------------*\
  2099. X *
  2100. X * Function  : SignalHandler
  2101. X *
  2102. X * Purpose   : 
  2103. X *
  2104. X * Parameters: 
  2105. X *
  2106. X * Returns   : 
  2107. X *
  2108. X */
  2109. Xstatic void SignalHandler(sig)
  2110. Xint sig;
  2111. X{
  2112. X    printf("signal %d\n", sig);
  2113. X
  2114. X    if( sig == SIGSEGV )
  2115. X        puts("Segmentation violation");
  2116. X    else if( sig == SIGBUS )
  2117. X        puts("Bus error");
  2118. X
  2119. X    dbd.shm->restore_active = 0;
  2120. X    shm_free(&dbd);
  2121. X    d_close();
  2122. X    unlink(LOG_FNAME);
  2123. X    puts("Restore aborted.");
  2124. X    exit(1);
  2125. X}
  2126. X
  2127. X
  2128. X/*--------------------------------------------------------------------------*\
  2129. X *
  2130. X * Function  : Read
  2131. X *
  2132. X * Purpose   : Read x bytes from the archive. If the data is not entirely
  2133. X *               in the buffer, the rest will read immediately. If the end
  2134. X *               of the current media has been reached, the user is promted
  2135. X *               for the next media.
  2136. X *
  2137. X * Parameters: buf        - Buffer to write.
  2138. X *               size        - Number of bytes in buffer.
  2139. X *
  2140. X * Returns   : Nothing.
  2141. X *
  2142. X */
  2143. Xstatic void Read(buf, size)
  2144. Xvoid *buf;
  2145. Xulong size;
  2146. X{
  2147. X    char s[20];
  2148. X    ulong copymax;
  2149. X    long numread;
  2150. X
  2151. X
  2152. X/*printf("Read: size=%d, inbytes=%ld, inreadpos=%ld\n",
  2153. X    size, inbytes, inreadpos);*/
  2154. X
  2155. X    /* Copy as much as possible to the output buffer */
  2156. X    if( inbytes > inreadpos )
  2157. X    {
  2158. X        copymax = size;
  2159. X        if( copymax > inbytes-inreadpos )
  2160. X            copymax = inbytes-inreadpos;
  2161. X
  2162. X        memcpy(buf, inbuf+inreadpos, copymax);
  2163. X        inreadpos += copymax;
  2164. X
  2165. X        if( copymax == size )
  2166. X            return;
  2167. X    }
  2168. X    else
  2169. X        copymax = 0;
  2170. X
  2171. X    while( archive_fh == -1 )
  2172. X    {
  2173. X        clock_off();
  2174. X        printf("Insert backup media no %d [enter]", mediahd.seqno);
  2175. X        fflush(stdout);
  2176. X        gets(s);
  2177. X        
  2178. X        if( s[0] == 'q' )
  2179. X            longjmp(err_jmpbuf, 2);
  2180. X
  2181. X        clock_on();            
  2182. X        if( (archive_fh = open(device, O_RDONLY)) == -1 )
  2183. X            printf("Cannot open '%s' (errno %d)\n", device, errno);
  2184. X    }
  2185. X
  2186. X    if( inreadpos == inbytes )
  2187. X    {
  2188. X        numread = read(archive_fh, inbuf, INBUF_SIZE);
  2189. X/*printf("size=%ld, read=%ld, copymax=%ld, inreadpos=%ld, inbytes=%ld\n", 
  2190. X    size, numread, copymax, inreadpos, inbytes);*/
  2191. X
  2192. X        if( numread == -1 )
  2193. X        {
  2194. X            printf("Read error (errno %d)\n", errno);
  2195. X            longjmp(err_jmpbuf, 1);
  2196. X        }
  2197. X        else if( numread != INBUF_SIZE )
  2198. X        {
  2199. X            /* The number of bytes read is less than requested. If the
  2200. X             * Read request can be satisfied by the number of bytes actually
  2201. X             * returned by read(), we assume that the end of the current
  2202. X             * media has been reached.
  2203. X             */
  2204. X            if( numread + copymax < size )
  2205. X            {
  2206. X                printf("Read error (errno %d)\n", errno);
  2207. X                longjmp(err_jmpbuf, 1);
  2208. X            }
  2209. X
  2210. X            mediahd.seqno++;
  2211. X            close(archive_fh);
  2212. X            archive_fh = -1;
  2213. X        }
  2214. X
  2215. X        /* Now copy the rest of the buffer */
  2216. X        inbytes        = numread;
  2217. X        inreadpos    = size - copymax;
  2218. X        memcpy((char *)buf + copymax, inbuf, inreadpos);
  2219. X
  2220. X        total_read += numread;
  2221. X
  2222. X/*printf("size=%ld, read=%ld, copymax=%ld, inreadpos=%ld, inbytes=%ld\n", 
  2223. X    size, numread, copymax, inreadpos, inbytes);*/
  2224. X    }
  2225. X}
  2226. X
  2227. X
  2228. X
  2229. X
  2230. X/*--------------------------------------------------------------------------*\
  2231. X *
  2232. X * Function  : DisplayProgress
  2233. X *
  2234. X * Purpose   : Prints the number of bytes read so far from the current table.
  2235. X *
  2236. X * Parameters: table        - Table name.
  2237. X *               bytes        - Number of bytes read.
  2238. X *
  2239. X * Returns   : Nothing.
  2240. X *
  2241. X */
  2242. Xstatic void DisplayProgress(table, bytes)
  2243. Xchar *table;
  2244. Xulong bytes;
  2245. X{
  2246. X    printf("\rWriting %-26.26s  %10s bytes", table, printlong(bytes));
  2247. X    fflush(stdout);
  2248. X}
  2249. X
  2250. X
  2251. X
  2252. X/*--------------------------------------------------------------------------*\
  2253. X *
  2254. X * Function  : RestoreDatabase
  2255. X *
  2256. X * Purpose   : 
  2257. X *
  2258. X * Parameters: None.
  2259. X *
  2260. X * Returns   : Nothing.
  2261. X *
  2262. X */
  2263. Xstatic void RestoreDatabase()
  2264. X{
  2265. X    ArchiveTableHeader    tablehd;
  2266. X    ArchiveRecordHeader    recordhd;
  2267. X    ulong                prev_bytecount;
  2268. X    ulong                bytecount;
  2269. X    char                outbuf[OUTBUF_SIZE];
  2270. X    char                fname[128];
  2271. X    char                objname[128];
  2272. X    int                    fh;
  2273. X
  2274. X    Read(&curr_id, sizeof curr_id);
  2275. X
  2276. X    for( ;; )
  2277. X    {
  2278. X        if( curr_id != ARCHIVE_TABLE )
  2279. X            break;
  2280. X        
  2281. X        Read(&tablehd.recsize, sizeof(tablehd) - sizeof(tablehd.id));
  2282. X
  2283. X        sprintf(fname, "%s/%s", datapath, tablehd.fname);
  2284. X        sprintf(objname, "table %s", tablehd.table);
  2285. X
  2286. X        if( (fh = open(fname, O_WRONLY|O_TRUNC|O_CREAT|O_BINARY, CREATMASK)) == -1 )
  2287. X        {
  2288. X            printf("Cannot open file '%s'\n", fname);
  2289. X            longjmp(err_jmpbuf, 1);
  2290. X        }
  2291. X        prev_bytecount = bytecount = 0;
  2292. X
  2293. X        for( ;; )
  2294. X        {
  2295. X            Read(&curr_id, sizeof curr_id);
  2296. X        
  2297. X            if( curr_id != ARCHIVE_RECORD )
  2298. X                break;
  2299. X    
  2300. X            Read(&recordhd.recid, sizeof(recordhd) - sizeof(recordhd.id));
  2301. X            Read(outbuf, tablehd.recsize);
  2302. X
  2303. X            lseek(fh, tablehd.recsize * recordhd.recno, SEEK_SET);
  2304. X            write(fh, outbuf, tablehd.recsize);
  2305. X
  2306. X            bytecount += tablehd.recsize;
  2307. X
  2308. X            if( verbose && bytecount > prev_bytecount + 100000 )
  2309. X            {
  2310. X                prev_bytecount = bytecount;
  2311. X                DisplayProgress(objname, bytecount);
  2312. X            }
  2313. X        }
  2314. X
  2315. X        if( verbose )
  2316. X        {
  2317. X            DisplayProgress(objname, bytecount);
  2318. X            puts("");
  2319. X        }
  2320. X        
  2321. X        
  2322. X        close(fh);
  2323. X    }
  2324. X}
  2325. X
  2326. X
  2327. X
  2328. X/*--------------------------------------------------------------------------*\
  2329. X *
  2330. X * Function  : RestoreFile
  2331. X *
  2332. X * Purpose   : Read a sequential file from archive.
  2333. X *
  2334. X * Parameters: fname    - File name.
  2335. X *
  2336. X * Returns   : Nothing.
  2337. X *
  2338. X */
  2339. Xstatic void RestoreFile(fname)
  2340. Xchar *fname;
  2341. X{
  2342. X    ArchiveFileDataHeader datahd;
  2343. X    int                    fh;
  2344. X    char                buf[OUTBUF_SIZE];
  2345. X    ulong                numread;
  2346. X    ulong                readmax;
  2347. X    ulong                bytecount=0;
  2348. X
  2349. X    if( (fh = open(fname, O_WRONLY|O_TRUNC|O_CREAT, CREATMASK)) == -1 )
  2350. X    {
  2351. X        printf("Cannot open '%s'\n", fname);
  2352. X        return;
  2353. X    }        
  2354. X
  2355. X    for( ;; )
  2356. X    {
  2357. X        Read(&curr_id, sizeof curr_id);
  2358. X
  2359. X        if( curr_id != ARCHIVE_FILEDATA )
  2360. X        {
  2361. X            printf("Unexpected header id %d in middle of file \n", curr_id);
  2362. X            longjmp(err_jmpbuf, 1);
  2363. X        }        
  2364. X
  2365. X        Read(&datahd.size, sizeof(datahd) - sizeof(datahd.size));
  2366. X
  2367. X        if( !datahd.size )                        /* End-of-file reached        */
  2368. X            break;
  2369. X
  2370. X        while( datahd.size > 0 )
  2371. X        {
  2372. X            /* Determine number of bytes to read */
  2373. X            readmax = sizeof buf;
  2374. X            if( readmax > datahd.size )
  2375. X                readmax = datahd.size;
  2376. X
  2377. X            Read(buf, readmax);
  2378. X            write(fh, buf, readmax);
  2379. X
  2380. X            bytecount += readmax;
  2381. X
  2382. X            if( verbose )
  2383. X                DisplayProgress(fname, bytecount);
  2384. X        
  2385. X            datahd.size -= readmax;
  2386. X        }
  2387. X    }
  2388. X
  2389. X    if( verbose )
  2390. X        puts("");
  2391. X
  2392. X    close(fh);
  2393. X}
  2394. X
  2395. X
  2396. X/*--------------------------------------------------------------------------*\
  2397. X *
  2398. X * Function  : RestoreDbdFile
  2399. X *
  2400. X * Purpose   : Restores the dbd-file from the archive.
  2401. X *
  2402. X * Parameters: None.
  2403. X *
  2404. X * Returns   : Nothing.
  2405. X *
  2406. X */
  2407. Xstatic void RestoreDbdFile()
  2408. X{
  2409. X    ArchiveFileHeader    filehd;
  2410. X
  2411. X    /* Restore dbd-file */    
  2412. X    Read(&filehd, sizeof filehd);
  2413. X    
  2414. X    if( filehd.id != ARCHIVE_FILE )
  2415. X    {
  2416. X        printf("Unexpected header id %d\n", filehd.id);
  2417. X        longjmp(err_jmpbuf, 1);
  2418. X    }
  2419. X
  2420. X    RestoreFile(filehd.fname);
  2421. X}
  2422. X
  2423. X
  2424. X/*--------------------------------------------------------------------------*\
  2425. X *
  2426. X * Function  : RestoreLogFile
  2427. X *
  2428. X * Purpose   : Restores the log file from the archive.
  2429. X *
  2430. X * Parameters: None.
  2431. X *
  2432. X * Returns   : Nothing.
  2433. X *
  2434. X */
  2435. Xstatic void RestoreLogFile()
  2436. X{
  2437. X    ArchiveFileHeader filehd;
  2438. X
  2439. X    if( curr_id == ARCHIVE_END )
  2440. X        return;
  2441. X
  2442. X    /* Restore the database */
  2443. X    if( curr_id != ARCHIVE_FILE )
  2444. X    {
  2445. X        printf("Unexpected header id %ld\n", curr_id);
  2446. X        longjmp(err_jmpbuf, 1);
  2447. X    }    
  2448. X
  2449. X    Read(filehd.fname, sizeof(filehd) - sizeof(filehd.id));
  2450. X
  2451. X    RestoreFile(filehd.fname);
  2452. X}
  2453. X
  2454. X
  2455. X
  2456. Xstatic void VerboseFn(table, records, curr_rec)
  2457. Xchar *table;
  2458. Xulong records, curr_rec;
  2459. X{
  2460. X    static int old_percent = 0;
  2461. X    int percent = curr_rec * 100 / records;
  2462. X
  2463. X    if( curr_rec == 0 )
  2464. X    {
  2465. X        printf("\nRebuilding %-32.32s    0%%", table);
  2466. X        fflush(stdout);
  2467. X        old_percent = 0;
  2468. X    }
  2469. X    else if( percent != old_percent )
  2470. X    {
  2471. X        printf("\b\b\b\b%3d%%", percent);
  2472. X        fflush(stdout);
  2473. X        old_percent = percent;
  2474. X    }
  2475. X}
  2476. X
  2477. X
  2478. X
  2479. Xstatic void help()
  2480. X{
  2481. X    puts("Syntax: tyrestore [option]...\n"
  2482. X         "Options:\n"
  2483. X         "    -d<device>      Backup device\n"
  2484. X         "    -f<path>        Path for data files\n"
  2485. X         "    -v              Be verbose\n");
  2486. X    exit(1);
  2487. X}
  2488. X
  2489. X
  2490. X
  2491. Xmain(argc, argv)
  2492. Xint        argc;
  2493. Xchar     *argv[];
  2494. X{
  2495. X    char                dbdname[20];
  2496. X    int                    i;
  2497. X    struct tm            *tm;
  2498. X
  2499. X    /* The input buffer MUST be bigger than the output buffer */
  2500. X    assert(OUTBUF_SIZE < INBUF_SIZE);
  2501. X
  2502. X    printf("Typhoon Restore version %s\n", VERSION);
  2503. X
  2504. X    if( argc < 2 )
  2505. X        help();
  2506. X
  2507. X    for( i=1; i<argc; i++ )
  2508. X    {
  2509. X        switch( *argv[i] )
  2510. X        {
  2511. X            case '-':
  2512. X            case '/':
  2513. X                switch( argv[i][1] )
  2514. X                {
  2515. X                    case 'd':
  2516. X                        device = argv[i]+2;
  2517. X                        break;
  2518. X                    case 'f':
  2519. X                        datapath = argv[i]+2;
  2520. X                        break;
  2521. X                    case 'v':
  2522. X                        verbose = 1;
  2523. X                        break;
  2524. X                    default:
  2525. X                        printf("Invalid option '%c'\n", argv[i][1]);
  2526. X                        break;
  2527. X                }
  2528. X                break;
  2529. X            default:
  2530. X                printf("Invalid switch '%c'\n", *argv[i]);
  2531. X                break;
  2532. X        }
  2533. X    }
  2534. X
  2535. X    if( *datapath  )
  2536. X    {
  2537. X        mkdir(datapath);
  2538. X        chmod(datapath, 0777);
  2539. X    }
  2540. X    
  2541. X    if( !(inbuf = (char *)malloc(INBUF_SIZE)) )
  2542. X    {
  2543. X        puts("Cannot allocate output buffer");
  2544. X        return;
  2545. X    }
  2546. X    inbytes = 0;    
  2547. X    inreadpos = 0;
  2548. X
  2549. X    if( setjmp(err_jmpbuf) )
  2550. X    {
  2551. X        if( verbose )
  2552. X            puts("Restore aborted.");
  2553. X        goto out;
  2554. X    }
  2555. X
  2556. X    if( verbose )
  2557. X        printf("Restoring from %s\n", device);
  2558. X
  2559. X    Read(&mediahd, sizeof mediahd);
  2560. X    if( mediahd.id != ARCHIVE_MEDIA )
  2561. X    {
  2562. X        printf("Unexpected header id %d\n", mediahd.id);
  2563. X        longjmp(err_jmpbuf, 1);
  2564. X    }
  2565. X
  2566. X    strcpy(dbd.name, mediahd.dbname);
  2567. X    if( shm_alloc(&dbd) == -1 )
  2568. X    {
  2569. X        printf("Cannot allocate shared memory");
  2570. X        return;
  2571. X    }
  2572. X    dbd.shm->restore_active = 1;
  2573. X
  2574. X    signal(SIGINT,    SignalHandler);
  2575. X    signal(SIGTERM, SignalHandler);
  2576. X    signal(SIGQUIT, SignalHandler);
  2577. X    signal(SIGSEGV, SignalHandler);
  2578. X    signal(SIGBUS,  SignalHandler);
  2579. X    signal(SIGHUP, SIG_IGN);
  2580. X
  2581. X    if( dbd.shm->use_count > 1 )
  2582. X    {
  2583. X        puts("The database is currenly in use. Cannot restore");
  2584. X        goto out;
  2585. X    }
  2586. X
  2587. X    /* Confirm restore */
  2588. X    clock_off();
  2589. X    tm = localtime(&mediahd.date);
  2590. X    printf("Database '%s' from %s", mediahd.dbname, asctime(tm));
  2591. X    printf("Restore? [y/n]: ");
  2592. X    fflush(stdout);
  2593. X    if( getchar() != 'y' )
  2594. X        goto out;
  2595. X    clock_on();
  2596. X
  2597. X    RestoreDbdFile();
  2598. X    RestoreDatabase();
  2599. X    RestoreLogFile();
  2600. X    clock_off();
  2601. X
  2602. X    if( verbose )
  2603. X    {
  2604. X        ulong secs = clock_secs();
  2605. X    
  2606. X        /* Guard against division by zero */
  2607. X        if( !secs )
  2608. X            secs = 1;
  2609. X
  2610. X        printf("\rTotal %40s bytes\n", printlong(total_read));
  2611. X        printf("%s bytes/second\n", printlong(total_read / secs));
  2612. X    }
  2613. X
  2614. X    FixLog(mediahd.dbname);
  2615. X
  2616. X    printf("Rebuilding index files");
  2617. X    d_keybuild(VerboseFn);
  2618. X    d_dbfpath(datapath);
  2619. X
  2620. X    if( d_open(mediahd.dbname, "o") != S_OKAY )
  2621. X        puts("Cannot open database");
  2622. X    else
  2623. X    {
  2624. X        d_close();
  2625. X        puts("");
  2626. X    }
  2627. X
  2628. Xout:
  2629. X    free(inbuf);
  2630. X    dbd.shm->restore_active = 0;
  2631. X    shm_free(&dbd);
  2632. X    free(dbd.dbd);
  2633. X    unlink(LOG_FNAME);
  2634. X
  2635. X    return 0;
  2636. X}
  2637. X
  2638. X/* end-of-file */
  2639. END_OF_FILE
  2640.   if test 13959 -ne `wc -c <'typhoon/src/util/restore.c'`; then
  2641.     echo shar: \"'typhoon/src/util/restore.c'\" unpacked with wrong size!
  2642.   fi
  2643.   # end of 'typhoon/src/util/restore.c'
  2644. fi
  2645. echo shar: End of archive 2 \(of 9\).
  2646. cp /dev/null ark2isdone
  2647. MISSING=""
  2648. for I in 1 2 3 4 5 6 7 8 9 ; do
  2649.     if test ! -f ark${I}isdone ; then
  2650.     MISSING="${MISSING} ${I}"
  2651.     fi
  2652. done
  2653. if test "${MISSING}" = "" ; then
  2654.     echo You have unpacked all 9 archives.
  2655.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2656. else
  2657.     echo You still must unpack the following archives:
  2658.     echo "        " ${MISSING}
  2659. fi
  2660. exit 0
  2661. exit 0 # Just in case...
  2662.