source: trunk/athena/bin/discuss/server/expunge2.c @ 22864

Revision 22864, 7.4 KB checked in by andersk, 17 years ago (diff)
Fix obsolete names for Kerberos library functions, which no longer worked on Mac OS X. Patch from broder.
Line 
1/*
2 *
3 * expunge -- program to expunge a meeting; i.e. really delete those
4 *            deleted transaction.  This program is linked to a server
5 *            so it can use the privileged procedure of create_mtg, and
6 *            the like.
7 *
8 */
9
10#include <stdio.h>
11#include <strings.h>
12#include <sys/types.h>
13#include <sys/file.h>
14#include <sys/stat.h>
15#include <unistd.h>
16
17#include <discuss/types.h>
18#include <discuss/dsc_et.h>
19#include <discuss/tfile.h>
20#include <discuss/interface.h>
21#include <discuss/acl.h>
22#include "mtg.h"
23
24#define NULL 0
25#define MAX_TRNS 1000
26#define min(a, b) (a < b ? a : b)
27
28static int tempf;
29static char *mtg_name = NULL, *location = NULL, *chairman = NULL, *trn_file = NULL;
30static char *backup_location = NULL;
31static char *future_location = NULL;
32static int found_eof = 0;
33static int error_occurred = 0;
34
35tfile unix_tfile ();
36char *malloc();
37
38extern char rpc_caller[];
39extern int has_privs;
40extern int errno;
41extern int no_nuke;
42
43main (argc, argv)
44int argc;
45char **argv;
46{
47     int i,n,low,high;
48     mtg_info old_mtg_info,new_mtg_info;
49     trn_info old_trn_info;
50     int result;
51     dsc_acl *acl_list,*new_acl_list;
52     dsc_acl_entry *ae;
53     char *new_modes;
54     tfile tf;
55     char control_name[256];
56     int control_fd;
57     
58     initialize_dsc_error_table();
59
60     for (i = 1; i < argc; i++) {
61          if (*argv[i] == '-') switch (argv[i][1]) {
62          case 'c':
63               if (++i < argc)
64                    chairman = argv[i];
65               continue;
66
67          case 'n':
68               if (++i < argc)
69                    mtg_name = argv[i];
70               continue;
71
72          default:
73               goto lusage;
74          }
75          if (location == NULL)
76               location = argv[i];
77          else goto lusage;
78     }
79
80     if (location == NULL)
81          goto lusage;                                  /* required */
82
83     has_privs = TRUE;                                  /* Tell discuss we're special */
84     strcpy (rpc_caller, "expunger");
85
86     /* First, we get the mtg info to make sure it exists */
87     get_mtg_info (location, &old_mtg_info, &result);
88     if (result != 0) {
89          fprintf(stderr, "%s: %s while getting mtg info\n", location, error_message(result));
90          exit (1);
91     }
92
93     get_acl (location, &result, &acl_list);
94     if (result != 0) {
95          fprintf(stderr, "%s: %s while getting acl\n", location, error_message(result));
96          exit (1);
97     }
98
99     /* Create the new meeting */
100     backup_location = malloc (strlen(location)+5);     /* be generous */
101     strcpy (backup_location, location);
102     strcat (backup_location, "~");
103
104     future_location = malloc (strlen(location)+5);     /* be generous */
105     strcpy (future_location, location);
106     strcat (future_location, "#");
107
108     printf("Creating new meeting\n");
109     fflush(stdout);
110
111     if (mtg_name == NULL) {
112          mtg_name = old_mtg_info.long_name;
113     }
114     if (chairman == NULL) {
115          chairman = old_mtg_info.chairman;
116     }
117
118     /* get acl's on old meeting, so we can make it new one */
119     get_acl (location, &result, &new_acl_list);
120     if (result != 0) {
121          fprintf(stderr, "%s: %s while getting acl\n", backup_location, error_message(result));
122          exit (1);
123     }
124
125     create_mtg_priv (backup_location, mtg_name, old_mtg_info.public_flag,
126                      old_mtg_info.date_created, chairman,
127                      new_acl_list, &result);
128     if (result != 0) {
129          fprintf (stderr, "%s: %s while creating new meeting\n",
130                   location, error_message(result));
131          exit (1);
132     }
133     
134     /* now, do the actual expunging */
135     low = old_mtg_info.lowest;
136     high = old_mtg_info.highest;
137     create_temp ();
138
139expunge_range:
140     for (i = low; i <= high; i++) {
141          get_trn_info (location, i, &old_trn_info, &result);
142          if (result != 0 && result != DELETED_TRN && result != EXPUNGED_TRN) {
143               fprintf(stderr,
144                       "Error getting info for transaction [%04d]: %s\n",
145                       i, error_message(result));
146               error_occurred = TRUE;
147          } else if (result != 0) {             /* expunge it */
148               no_nuke = TRUE;
149               printf("Expunging transaction [%04d]\n", i);
150               expunge_trn (backup_location, i, &result);
151               no_nuke = FALSE;
152               if (result != 0) {
153                    fprintf(stderr,
154                            "Error expunging transaction [%04d]: %s\n",
155                            i, error_message(result));
156                    error_occurred = TRUE;
157               }
158          } else if (result == 0) {
159               ftruncate(tempf,0);
160               lseek(tempf,0,SEEK_SET);
161               tf = unix_tfile (tempf);
162
163               get_trn (location, i, tf, &result);
164               if (result != 0) {
165                    fprintf(stderr, "Error getting transaction [%04d]: %s\n",
166                            i, error_message(result));
167                    error_occurred = TRUE;
168                    free(old_trn_info. author);
169                    free(old_trn_info.subject);
170                    continue;
171               }
172
173               tdestroy (tf);
174               lseek(tempf,0,SEEK_SET);
175
176               tf = unix_tfile (tempf);
177               no_nuke = TRUE;
178               add_trn_priv (backup_location, tf, old_trn_info.subject,
179                             old_trn_info.pref, old_trn_info.current,
180                             old_trn_info.author, old_trn_info.date_entered,
181                             &n, &result);
182               no_nuke = FALSE;
183               if (result != 0) {
184                    fprintf(stderr,
185                            "Error getting info for transaction %d: %s\n", i,
186                            error_message(result));
187                    error_occurred = TRUE;
188               }
189               free(old_trn_info.author);
190               free(old_trn_info.subject);
191          }
192     }
193
194     /* Check if any new transactions have been added */
195     free(old_mtg_info.long_name);
196     free(old_mtg_info.chairman);
197     free(old_mtg_info.location);
198     get_mtg_info(location, &old_mtg_info, &result);
199     if (result != 0) {
200          fprintf(stderr, "%s: %s while getting mtg info\n", location, error_message(result));
201          error_occurred = TRUE;
202     } else if (old_mtg_info.highest > high) {          /* New transactions added */
203          low = high+1;
204          high = old_mtg_info.highest;
205          goto expunge_range;
206     }
207
208     strcpy(control_name, location);
209     strcat(control_name, "/control");
210     if ((control_fd = open (control_name, O_RDWR, 0700)) < 0) {
211          error_occurred = TRUE;
212     } else {
213          flock(control_fd, LOCK_EX);           /* Hold meeting by the balls */
214          free(old_mtg_info.long_name);
215          free(old_mtg_info.chairman);
216          free(old_mtg_info.location);
217
218          no_nuke = TRUE;
219          get_mtg_info(location, &old_mtg_info, &result);
220          if (result != 0) {           
221               fprintf(stderr, "%s: %s while getting mtg info\n", location, error_message(result));
222               error_occurred = TRUE;
223               flock(control_fd,LOCK_UN);
224               close(control_fd);
225          } else if (old_mtg_info.highest > high) {             /* New transactions added */
226               low = high + 1;
227               high = old_mtg_info.highest;
228               flock(control_fd,LOCK_UN);
229               close(control_fd);
230               goto expunge_range;
231          }
232     }
233
234     /* When we get here, we have the old meeting locked.  Now we do the move
235        as atomically as we can */
236     if (!error_occurred) {
237          if (rename(location, future_location) < 0) {
238               perror("rename of old meeting failed");
239               exit (1);
240          }
241          if (rename(backup_location, location) < 0) {
242               perror("rename of new meeting");
243               exit (1);
244          }
245          remove_mtg (future_location, &result);
246          if (result != 0) {
247               fprintf(stderr, "%s: %s while removing new meeting.\n",
248                       location, error_message(result));
249               exit (1);
250          }
251     } else exit (1);                           /* error occurred */
252
253     exit (0);
254
255lusage:
256     fprintf(stderr, "usage: expunge mtg_location {-c chairman} {-n name}\n");
257     exit (1);
258}
259
260/*
261 *
262 * create_temp () -- Create temp file, and let it be tempf.
263 *
264 */
265create_temp()
266{
267     char filename [20];
268
269     strcpy (filename, "/tmp/rcXXXXXX");
270     mktemp (filename);
271
272     tempf = open (filename, O_RDWR | O_CREAT, 0700);
273     if (tempf < 0) {
274          fprintf (stderr, "Cannot open temp file\n");
275          exit (1);
276     }
277}
278
279
Note: See TracBrowser for help on using the repository browser.