Bug Summary

File:bucoord/dump_sched.c
Location:line 529, column 6
Description:Assigned value is always the same as the existing value

Annotated Source Code

1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10/*
11 * ALL RIGHTS RESERVED
12 */
13
14#include <afsconfig.h>
15#include <afs/param.h>
16
17#include <roken.h>
18
19#include <afs/ktime.h>
20#include <afs/budb_client.h>
21#include <afs/cmd.h>
22#include <afs/com_err.h>
23#include <afs/bubasics.h>
24
25#include "bc.h"
26#include "error_macros.h"
27#include "bucoord_internal.h"
28#include "bucoord_prototypes.h"
29
30/* code to manage dump schedules
31 * specific to the ubik database implementation
32 */
33
34extern struct bc_config *bc_globalConfig;
35extern struct udbHandleS udbHandle;
36extern char *whoami;
37
38static int ListDumpSchedule(struct bc_dumpSchedule *adump, int alevel);
39
40/* ------------------------------------
41 * command level routines
42 * ------------------------------------
43 */
44
45/* bc_AddDumpCmd
46 * add a dump schedule
47 * params:
48 * parm 0: list of dump names
49 * parm 1: expiration date (list)
50 */
51
52int
53bc_AddDumpCmd(struct cmd_syndesc *as, void *arock)
54{
55 char *dname; /* dump schedule name */
56 int code;
57 afs_int32 expType, expDate;
58 struct cmd_item *ti;
59 udbClientTextP ctPtr;
60
61 /* if an expiration date has been specified */
62 if (as->parms[1].items) {
63 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
64 if (code) {
65 printf("Invalid expiration date syntax\n");
66 return (1);
67 }
68 } else {
69 /* no expiration date specified */
70 expDate = 0;
71 expType = BC_NO_EXPDATE0;
72 }
73
74 /* lock schedules and check validity */
75 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE0];
76
77 code = bc_LockText(ctPtr);
78 if (code)
79 ERROR(code)do { code = code; goto error_exit; } while (0);
80
81 code = bc_UpdateDumpSchedule();
82 if (code) {
83 afs_com_err(whoami, code, "; Can't retrieve dump schedule");
84 return (code);
85 }
86
87 /* process each dump name using the expiration date computed above */
88 for (ti = as->parms[0].items; ti != 0; ti = ti->next) {
89 /* get next dump name to process */
90 dname = ti->data;
91
92 /* validate the name dump name length */
93 if (strlen(dname) >= BU_MAX_DUMP_PATH256) {
94 afs_com_err(whoami, 0, "Dump names must be < %d characters",
95 BU_MAX_DUMP_PATH256);
96 afs_com_err(whoami, 0, "Dump %s not added", dname);
97 code = -1;
98 continue;
99 }
100
101 code =
102 bc_CreateDumpSchedule(bc_globalConfig, dname, expDate, expType);
103 if (code) {
104 if (code == -1)
105 afs_com_err(whoami, 0, "Dump already exists");
106 else if (code == -2)
107 afs_com_err(whoami, 0, "Invalid path name '%s'", dname);
108 else if (code == -3)
109 afs_com_err(whoami, 0, "Name specification error");
110 else
111 afs_com_err(whoami, code, "; Failed to create dump schedule");
112 continue;
113 }
114
115 /* save the new schedule item */
116 code = bc_SaveDumpSchedule();
117 if (code) {
118 afs_com_err(whoami, code, "Cannot save dump schedule");
119 afs_com_err(whoami, 0,
120 "Changes are temporary - for this session only");
121 break;
122 }
123
124 afs_com_err(whoami, 0, "Created new dump schedule %s", dname);
125 }
126
127 error_exit:
128 if (ctPtr->lockHandle)
129 bc_UnlockText(ctPtr);
130 return (code);
131}
132
133
134/* bc_DeleteDumpCmd
135 * delete a dump schedule
136 */
137
138int
139bc_DeleteDumpCmd(struct cmd_syndesc *as, void *arock)
140{
141 /* parm 0 is vol set name
142 * parm 1 is dump schedule name
143 */
144 char *dname;
145 int code;
146 udbClientTextP ctPtr;
147
148 /* lock schedules and check validity */
149 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE0];
150
151 code = bc_LockText(ctPtr);
152 if (code)
153 ERROR(code)do { code = code; goto error_exit; } while (0);
154
155 code = bc_UpdateDumpSchedule();
156 if (code) {
157 afs_com_err(whoami, code, "; Can't retrieve dump schedule");
158 return (code);
159 }
160
161 dname = as->parms[0].items->data;
162
163 code = bc_DeleteDumpSchedule(bc_globalConfig, dname);
164 if (code) {
165 if (code == -1)
166 afs_com_err(whoami, 0, "No such dump as %s", dname);
167 else
168 afs_com_err(whoami, code, "; Failed to delete dump schedule");
169 goto error_exit;
170 }
171
172 code = bc_SaveDumpSchedule();
173 if (code == 0)
174 printf("backup: deleted dump schedule %s\n", dname);
175 else {
176 afs_com_err(whoami, code, "Cannot save dump schedule file");
177 afs_com_err(whoami, 0, "Deletion is temporary - for this session only");
178 }
179
180 error_exit:
181 if (ctPtr->lockHandle != 0)
182 bc_UnlockText(ctPtr);
183 return code;
184}
185
186/* ListDumpSchedule
187 * Print out the dump schedule tree whose root is adump. Alevel should
188 * be passed in as 0, and is incremented for the recursive calls
189 * entry:
190 * adump - ptr to the root node of a dump schedule
191 * alevel - 0
192 */
193
194static int
195ListDumpSchedule(struct bc_dumpSchedule *adump, int alevel)
196{
197 int i;
198 struct bc_dumpSchedule *child;
199
200 /* sanity check for loops */
201 if (alevel > 100) {
202 printf("backup: recursing listing dump schedule\n");
203 return -1;
204 }
205
206 /* move to appropriate indentation level */
207 for (i = 0; i < alevel; i++)
208 printf(" ");
209
210 /* name is a pathname style name, determine trailing name and only print
211 * it
212 */
213
214 printf("/%s ", tailCompPtr(adump->name));
215
216
217 /* list expiration time */
218 switch (adump->expType) {
219 case BC_ABS_EXPDATE1:
220 /* absolute expiration date. Never expires if date is 0 */
221 if (adump->expDate) {
222 time_t t = adump->expDate;
223 printf("expires at %.24s", cTIME(&t)( (*(&t) == 037777777777) ? (char *)"NEVER \n"
: (char *)ctime(&t) )
);
224 }
225 break;
226
227 case BC_REL_EXPDATE2:
228 {
229 struct ktime_date kt;
230
231 /* expiration date relative to the time that the dump is done */
232 LongTo_ktimeRelDateInt32To_ktimeRelDate(adump->expDate, &kt);
233 printf(" expires in %s", RelDatetoString(&kt));
234 }
235 break;
236
237 default:
238 break;
239 }
240 printf("\n");
241 for (child = adump->firstChild; child; child = child->nextSibling)
242 ListDumpSchedule(child, alevel + 1);
243
244 return 0;
245}
246
247/* bc_ListDumpScheduleCmd
248 * list the (internally held) dump schedule tree
249 * parameters:
250 * ignored
251 */
252
253int
254bc_ListDumpScheduleCmd(struct cmd_syndesc *as, void *arock)
255{
256 /* no parms */
257 int code;
258 struct bc_dumpSchedule *tdump;
259
260 /* first check to see if schedules must be updated */
261 code = bc_UpdateDumpSchedule();
262 if (code) {
263 afs_com_err(whoami, code, "; Can't retrieve dump schedule");
264 return (code);
265 }
266
267 /* go through entire list, displaying trees for root-level dump
268 * schedules
269 */
270 for (tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next) {
271 /* if this is a root-level dump, show it and its kids */
272 if (!tdump->parent)
273 ListDumpSchedule(tdump, 0);
274 }
275 return 0;
276}
277
278
279/* bc_SetExpCmd
280 * Set/clear expiration date on existing dump node
281 * params:
282 * parm 0: list of dump names
283 * parm 1: expiration date (list)
284 */
285
286int
287bc_SetExpCmd(struct cmd_syndesc *as, void *arock)
288{
289 char *dname; /* dump schedule name */
290 struct cmd_item *ti;
291 struct bc_dumpSchedule *node, *parent;
292 afs_int32 expType, expDate;
293 udbClientTextP ctPtr;
294 int code;
295
296 /* if an expiration date has been specified */
297 if (as->parms[1].items) {
298 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
299 if (code) {
300 printf("Invalid expiration date syntax\n");
301 return (1);
302 }
303 } else {
304 /* no expiration date specified */
305 expDate = 0;
306 expType = BC_NO_EXPDATE0;
307 }
308
309 /* lock schedules and check validity */
310 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE0];
311
312 code = bc_LockText(ctPtr);
313 if (code)
314 ERROR(code)do { code = code; goto error_exit; } while (0);
315
316 code = bc_UpdateDumpSchedule();
317 if (code) {
318 afs_com_err(whoami, code, "; Can't retrieve dump schedule");
319 return (code);
320 }
321
322 /* process each dump name using the expiration date computed above */
323 for (ti = as->parms[0].items; ti != 0; ti = ti->next) {
324 /* get next dump name to process */
325 dname = ti->data;
326
327 /* validate the name dump name length */
328 if (strlen(dname) >= BU_MAX_DUMP_PATH256) {
329 code = -1;
330 afs_com_err(whoami, 0, "Dump names must be < %d characters",
331 BU_MAX_DUMP_PATH256);
332 afs_com_err(whoami, 0, "Dump %s not added", dname);
333 continue;
334 }
335
336 code = FindDump(bc_globalConfig, dname, &parent, &node);
337 if (code) {
338 afs_com_err(whoami, 0, "Dump level %s not found", dname);
339 continue;
340 }
341
342 node->expDate = expDate;
343 node->expType = expType;
344 }
345
346 code = bc_SaveDumpSchedule();
347 if (code) {
348 afs_com_err(whoami, code, "Cannot save dump schedule");
349 afs_com_err(whoami, 0,
350 "Expiration changes effective for this session only");
351 }
352
353 error_exit:
354 if (ctPtr->lockHandle)
355 bc_UnlockText(ctPtr);
356 return (code);
357}
358
359
360
361/* ------------------------------------
362 * general dump schedule handling routines
363 * ------------------------------------
364 */
365
366int
367bc_ParseDumpSchedule(void)
368{
369 char tbuffer[1024];
370 char dsname[256], period[64];
371 char *tp;
372 afs_int32 code;
373 udbClientTextP ctPtr;
374 struct bc_dumpSchedule *tds;
375 struct bc_dumpSchedule **ppds, *pds;
376 afs_int32 expDate, expType;
377
378 FILE *stream;
379
380 /* initialize locally used variables */
381 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE0];
382 stream = ctPtr->textStream;
383
384 if (ctPtr->textSize == 0) /* nothing defined yet */
385 return (0);
386
387 if (stream == NULL((void *)0))
388 return (BC_INTERNALERROR(156288014L));
389
390 rewind(stream);
391
392 /* check the magic number and version */
393 tp = fgets(tbuffer, sizeof(tbuffer), stream);
394 if (tp == 0)
395 /* can't read first line - error */
396 return (BC_INTERNALERROR(156288014L));
397 else {
398 afs_int32 dsmagic, dsversion;
399
400 /* read the first line, and then check magic # and version */
401
402 code = sscanf(tbuffer, "%d %d", &dsmagic, &dsversion);
403 if ((code != 2)
404 || (dsmagic != BC_SCHEDULE_MAGIC0x74327285)
405 || (dsversion != BC_SCHEDULE_VERSION1)
406 ) {
407 /* invalid or unexpected header - error */
408 afs_com_err(whoami, 0, "Unable to understand dump schedule file");
409 return (BC_INTERNALERROR(156288014L));
410 }
411 }
412
413 while (1) {
414 /* read all of the lines out */
415 tp = fgets(tbuffer, sizeof(tbuffer), stream);
416 if (tp == 0)
417 break; /* hit eof? */
418 code =
419 sscanf(tbuffer, "%s %s %d %d", dsname, period, &expDate,
420 &expType);
421 if (code != 4) {
422 afs_com_err(whoami, 0,
423 "Syntax error in dump schedule file, line is: %s",
424 tbuffer);
425 return (BC_INTERNALERROR(156288014L));
426 }
427 tds =
428 (struct bc_dumpSchedule *)malloc(sizeof(struct bc_dumpSchedule));
429 memset(tds, 0, sizeof(*tds));
430
431 tds->next = (struct bc_dumpSchedule *)0;
432 tds->name = (char *)malloc(strlen(dsname) + 1);
433 strcpy(tds->name, dsname);
434
435 tds->expDate = expDate;
436 tds->expType = expType;
437
438 /* find the end of the schedule list, and append the new item to it */
439 ppds = &bc_globalConfig->dsched;
440 pds = *ppds;
441 while (pds != 0) {
442 ppds = &pds->next;
443 pds = *ppds;
444 }
445 *ppds = tds;
446 }
447 return 0;
448}
449
450int
451bc_SaveDumpSchedule(void)
452{
453 struct bc_dumpSchedule *tdump;
454 udbClientTextP ctPtr;
455 afs_int32 code = 0;
456
457 extern struct bc_config *bc_globalConfig;
458
459 /* setup the right ptr */
460 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE0];
461
462 /* must be locked */
463 if (ctPtr->lockHandle == 0)
464 return (BC_INTERNALERROR(156288014L));
465
466 /* truncate the file */
467 code = ftruncate(fileno(ctPtr->textStream)(!__isthreaded ? ((ctPtr->textStream)->_file) : (fileno
)(ctPtr->textStream))
, 0);
468 if (code)
469 ERROR(errno)do { code = (* __error()); goto error_exit; } while (0);
470
471 rewind(ctPtr->textStream);
472
473 /* write the new information */
474 fprintf(ctPtr->textStream, "%d %d\n", BC_SCHEDULE_MAGIC0x74327285,
475 BC_SCHEDULE_VERSION1);
476
477 for (tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next) {
478 fprintf(ctPtr->textStream, "%s %s %d %d\n", tdump->name, "any",
479 tdump->expDate, tdump->expType);
480 }
481
482 if (ferror(ctPtr->textStream)(!__isthreaded ? (((ctPtr->textStream)->_flags & 0x0040
) != 0) : (ferror)(ctPtr->textStream))
)
483 return (BC_INTERNALERROR(156288014L));
484
485 fflush(ctPtr->textStream); /* debug */
486
487 /* send to server */
488 code = bcdb_SaveTextFile(ctPtr);
489 if (code)
490 ERROR(code)do { code = code; goto error_exit; } while (0);
491
492 /* increment local version number */
493 ctPtr->textVersion++;
494
495 /* update locally stored file size */
496 ctPtr->textSize = filesize(ctPtr->textStream);
497 error_exit:
498 return (code);
499}
500
501
502/* ------------------------------------
503 * misc. support routines - specific to dump schedules
504 * ------------------------------------
505 */
506
507afs_int32
508bc_UpdateDumpSchedule(void)
509{
510 struct bc_dumpSchedule *dumpPtr, *nextDumpPtr;
511 struct udbHandleS *uhptr = &udbHandle;
512 udbClientTextP ctPtr;
513 afs_int32 code;
514 int lock = 0;
515
516 /* lock schedules and check validity */
517 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE0];
518
519 code = bc_CheckTextVersion(ctPtr);
520 if (code != BC_VERSIONMISMATCH(156288001L)) {
1
Taking false branch
521 ERROR(code)do { code = code; goto error_exit; } while (0); /* Version matches or some other error */
522 }
523
524 /* Must update the dump schedules */
525 /* If we are not already locked, then lock it now */
526 if (!ctPtr->lockHandle) {
2
Taking true branch
527 code = bc_LockText(ctPtr);
528 if (code)
3
Taking true branch
529 ERROR(code)do { code = code; goto error_exit; } while (0);
4
Within the expansion of the macro 'ERROR':
a
Assigned value is always the same as the existing value
530 lock = 1;
531 }
532
533 if (ctPtr->textVersion != -1) {
534 printf("backup: obsolete dump schedule - updating\n");
535
536 /* clear all old schedule information */
537 dumpPtr = bc_globalConfig->dsched;
538 while (dumpPtr) {
539 nextDumpPtr = dumpPtr->next;
540 free(dumpPtr);
541 dumpPtr = nextDumpPtr;
542 }
543 bc_globalConfig->dsched = 0;;
544 }
545
546 /* open a temp file to store the config text received from buserver *
547 * The open file stream is stored in ctPtr->textStream */
548 code =
549 bc_openTextFile(ctPtr,
550 &bc_globalConfig->
551 tmpTextFileNames[TB_DUMPSCHEDULE0][0]);
552 if (code)
553 ERROR(code)do { code = code; goto error_exit; } while (0);
554 /* now get a fresh set of information from the database */
555 code = bcdb_GetTextFile(ctPtr);
556 if (code)
557 ERROR(code)do { code = code; goto error_exit; } while (0);
558
559 /* fetch the version number */
560 code =
561 ubik_BUDB_GetTextVersion(uhptr->uh_client, 0, ctPtr->textType,
562 &ctPtr->textVersion);
563 if (code)
564 ERROR(code)do { code = code; goto error_exit; } while (0);
565
566 /* parse the file */
567 code = bc_ParseDumpSchedule();
568 if (code)
569 ERROR(code)do { code = code; goto error_exit; } while (0);
570
571 /* rebuild the tree */
572 code = bc_ProcessDumpSchedule(bc_globalConfig);
573 if (code)
574 ERROR(code)do { code = code; goto error_exit; } while (0);
575
576 error_exit:
577 if (lock && ctPtr->lockHandle)
578 bc_UnlockText(ctPtr);
579 return (code);
580}
581