dba59f965f2ca10bc88a789b950e0386ca6a9fe5
[oweals/cde.git] / cde / lib / tt / mini_isam / isgarbage.c
1 /*%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                   */
2 /*%%  (c) Copyright 1993, 1994 International Business Machines Corp.     */
3 /*%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                    */
4 /*%%  (c) Copyright 1993, 1994 Novell, Inc.                              */
5 /*%%  $TOG: isgarbage.c /main/5 1998/04/10 08:04:25 mgreess $                                                    */
6 #include "isam_impl.h"
7 #include <stdlib.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10
11 int
12 isgarbage(char * isfname)
13 {
14         char                    isfname2[MAXPATHLEN];
15         int                     isfd = -1, isfd2 = -1;
16         char                    buffer[ISMAXRECLEN];
17         char                    *recbuf;
18         struct dictinfo         info;
19         struct keydesc          keybuf;
20         struct stat             statbuf;
21         int                     count = 0,i;
22
23         (void)strcpy(isfname2, isfname);
24         (void)strcat(isfname2, "~");
25
26         if ((isfd = isopen(isfname, ISEXCLLOCK + ISINPUT)) == ISERROR) {
27                 goto ERROR;
28         }
29
30         if (isindexinfo(isfd, (struct keydesc *)&info, 0) == ISERROR) {
31                 goto ERROR;
32         }
33
34         if (strlen(isfname) + 5 >= ISMAXRECLEN)
35           recbuf = (char*) malloc(strlen(isfname) + 5);
36         else
37           recbuf = buffer;
38
39         sprintf(recbuf, "%s.rec", isfname);
40         if (stat(recbuf, &statbuf) < 0) {
41                 goto ERROR;
42         }
43
44         iserase(isfname2);      /* Delete any old backup (~) files. */
45
46         if ((isfd2 = isbuild(isfname2, info.di_recsize, nokey,
47                      (DICTVARLENBIT&info.di_nkeys?ISVARLEN: ISFIXLEN)
48                              + ISEXCLLOCK + ISINOUT)) == ISERROR) {
49                 goto ERROR;
50         }
51
52         /* Copy all records */
53
54         while (isread(isfd, recbuf, ISNEXT) == ISOK) {
55                 iswrite(isfd2, recbuf);
56                 count++;
57         }
58
59         if (count != info.di_nrecords) {
60                 goto ERROR;
61         }
62         
63         /* Build all indexes from index info */
64
65         for (i = 1; i <= (info.di_nkeys & DICTNKEYSMASK); i++) {
66                 if (isindexinfo(isfd, &keybuf, i) == ISERROR) {
67                         goto ERROR;
68                 }
69                 if (i == 1 && keybuf.k_nparts != 0) {
70                         /* Add primary index */
71                         if (isaddprimary(isfd2, &keybuf) == ISERROR) {
72                                 goto ERROR;
73                         }
74                 } 
75                 else if (i > 1) {
76                         /* Add secondary index */
77                         if (isaddindex(isfd2, &keybuf) == ISERROR) {
78                                 goto ERROR;
79                         }
80                 }
81         }
82
83         (void)isclose(isfd);
84         (void)isclose(isfd2);
85
86         iserase(isfname);               /* cannot abort at this point ! */
87         if (isrename(isfname2, isfname) == ISERROR) {
88                 return (ISERROR);
89         }
90
91         return (ISOK);
92
93       ERROR:
94
95         if (isfd != -1)
96           (void)isclose(isfd);
97
98         if (isfd2 != -1) {
99                 (void)isclose(isfd2);
100                 (void)iserase(isfname2);
101         }
102         if (recbuf != buffer) free(recbuf);
103         return (ISERROR);
104 }
105