2 * Copyright 2000, International Business Machines Corporation and others.
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
14 #include <sys/types.h>
16 #include <afsconfig.h>
17 #include <afs/param.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
31 #include <afs/ktime.h>
32 #include <afs/budb_client.h>
34 #include <afs/com_err.h>
35 #include <afs/bubasics.h>
37 #include "error_macros.h"
39 /* code to manage dump schedules
40 * specific to the ubik database implementation
43 afs_int32 bc_UpdateDumpSchedule();
44 extern struct bc_config *bc_globalConfig;
45 extern struct udbHandleS udbHandle;
49 /* ------------------------------------
50 * command level routines
51 * ------------------------------------
57 * parm 0: list of dump names
58 * parm 1: expiration date (list)
62 bc_AddDumpCmd(as, arock)
63 struct cmd_syndesc *as;
66 register char *dname; /* dump schedule name */
67 register afs_int32 code;
68 afs_int32 expType, expDate;
69 register struct cmd_item *ti;
72 afs_int32 bc_ParseExpiration();
74 /* if an expiration date has been specified */
75 if (as->parms[1].items) {
76 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
78 printf("Invalid expiration date syntax\n");
82 /* no expiration date specified */
84 expType = BC_NO_EXPDATE;
87 /* lock schedules and check validity */
88 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
90 code = bc_LockText(ctPtr);
94 code = bc_UpdateDumpSchedule();
96 com_err(whoami, code, "; Can't retrieve dump schedule");
100 /* process each dump name using the expiration date computed above */
101 for (ti = as->parms[0].items; ti != 0; ti = ti->next) {
102 /* get next dump name to process */
105 /* validate the name dump name length */
106 if (strlen(dname) >= BU_MAX_DUMP_PATH) {
107 com_err(whoami, 0, "Dump names must be < %d characters",
109 com_err(whoami, 0, "Dump %s not added", dname);
115 bc_CreateDumpSchedule(bc_globalConfig, dname, expDate, expType);
118 com_err(whoami, 0, "Dump already exists");
120 com_err(whoami, 0, "Invalid path name '%s'", dname);
122 com_err(whoami, 0, "Name specification error");
124 com_err(whoami, code, "; Failed to create dump schedule");
128 /* save the new schedule item */
129 code = bc_SaveDumpSchedule();
131 com_err(whoami, code, "Cannot save dump schedule");
133 "Changes are temporary - for this session only");
137 com_err(whoami, 0, "Created new dump schedule %s", dname);
141 if (ctPtr->lockHandle)
142 bc_UnlockText(ctPtr);
148 * delete a dump schedule
152 bc_DeleteDumpCmd(as, arock)
153 struct cmd_syndesc *as;
156 /* parm 0 is vol set name
157 * parm 1 is dump schedule name
159 register char *dname;
160 register afs_int32 code;
161 udbClientTextP ctPtr;
163 /* lock schedules and check validity */
164 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
166 code = bc_LockText(ctPtr);
170 code = bc_UpdateDumpSchedule();
172 com_err(whoami, code, "; Can't retrieve dump schedule");
176 dname = as->parms[0].items->data;
178 code = bc_DeleteDumpSchedule(bc_globalConfig, dname);
181 com_err(whoami, 0, "No such dump as %s", dname);
183 com_err(whoami, code, "; Failed to delete dump schedule");
187 code = bc_SaveDumpSchedule();
189 printf("backup: deleted dump schedule %s\n", dname);
191 com_err(whoami, code, "Cannot save dump schedule file");
192 com_err(whoami, 0, "Deletion is temporary - for this session only");
196 if (ctPtr->lockHandle != 0)
197 bc_UnlockText(ctPtr);
203 /* bc_ListDumpScheduleCmd
204 * list the (internally held) dump schedule tree
210 bc_ListDumpScheduleCmd(as, arock)
211 struct cmd_syndesc *as;
216 register struct bc_dumpSchedule *tdump;
218 /* first check to see if schedules must be updated */
219 code = bc_UpdateDumpSchedule();
221 com_err(whoami, code, "; Can't retrieve dump schedule");
225 /* go through entire list, displaying trees for root-level dump
228 for (tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next) {
229 /* if this is a root-level dump, show it and its kids */
231 ListDumpSchedule(tdump, 0);
238 * Set/clear expiration date on existing dump node
240 * parm 0: list of dump names
241 * parm 1: expiration date (list)
245 bc_SetExpCmd(as, arock)
246 struct cmd_syndesc *as;
249 register char *dname; /* dump schedule name */
250 register struct cmd_item *ti;
251 struct bc_dumpSchedule *node, *parent;
252 afs_int32 expType, expDate;
253 udbClientTextP ctPtr;
254 register afs_int32 code;
256 afs_int32 bc_ParseExpiration();
258 /* if an expiration date has been specified */
259 if (as->parms[1].items) {
260 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
262 printf("Invalid expiration date syntax\n");
266 /* no expiration date specified */
268 expType = BC_NO_EXPDATE;
271 /* lock schedules and check validity */
272 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
274 code = bc_LockText(ctPtr);
278 code = bc_UpdateDumpSchedule();
280 com_err(whoami, code, "; Can't retrieve dump schedule");
284 /* process each dump name using the expiration date computed above */
285 for (ti = as->parms[0].items; ti != 0; ti = ti->next) {
286 /* get next dump name to process */
289 /* validate the name dump name length */
290 if (strlen(dname) >= BU_MAX_DUMP_PATH) {
292 com_err(whoami, 0, "Dump names must be < %d characters",
294 com_err(whoami, 0, "Dump %s not added", dname);
298 code = FindDump(bc_globalConfig, dname, &parent, &node);
300 com_err(whoami, 0, "Dump level %s not found", dname);
304 node->expDate = expDate;
305 node->expType = expType;
308 code = bc_SaveDumpSchedule();
310 com_err(whoami, code, "Cannot save dump schedule");
312 "Expiration changes effective for this session only");
316 if (ctPtr->lockHandle)
317 bc_UnlockText(ctPtr);
323 /* ------------------------------------
324 * general dump schedule handling routines
325 * ------------------------------------
328 bc_ParseDumpSchedule()
331 char dsname[256], period[64];
334 udbClientTextP ctPtr;
335 register struct bc_dumpSchedule *tds;
336 struct bc_dumpSchedule **ppds, *pds;
337 afs_int32 expDate, expType;
339 register FILE *stream;
341 /* initialize locally used variables */
342 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
343 stream = ctPtr->textStream;
345 if (ctPtr->textSize == 0) /* nothing defined yet */
349 return (BC_INTERNALERROR);
353 /* check the magic number and version */
354 tp = fgets(tbuffer, sizeof(tbuffer), stream);
356 /* can't read first line - error */
357 return (BC_INTERNALERROR);
359 afs_int32 dsmagic, dsversion;
361 /* read the first line, and then check magic # and version */
363 code = sscanf(tbuffer, "%d %d", &dsmagic, &dsversion);
365 || (dsmagic != BC_SCHEDULE_MAGIC)
366 || (dsversion != BC_SCHEDULE_VERSION)
368 /* invalid or unexpected header - error */
369 com_err(whoami, 0, "Unable to understand dump schedule file");
370 return (BC_INTERNALERROR);
375 /* read all of the lines out */
376 tp = fgets(tbuffer, sizeof(tbuffer), stream);
378 break; /* hit eof? */
380 sscanf(tbuffer, "%s %s %d %d", dsname, period, &expDate,
384 "Syntax error in dump schedule file, line is: %s",
386 return (BC_INTERNALERROR);
389 (struct bc_dumpSchedule *)malloc(sizeof(struct bc_dumpSchedule));
390 memset(tds, 0, sizeof(*tds));
392 tds->next = (struct bc_dumpSchedule *)0;
393 tds->name = (char *)malloc(strlen(dsname) + 1);
394 strcpy(tds->name, dsname);
396 tds->expDate = expDate;
397 tds->expType = expType;
399 /* find the end of the schedule list, and append the new item to it */
400 ppds = &bc_globalConfig->dsched;
412 bc_SaveDumpSchedule()
414 struct bc_dumpSchedule *tdump;
415 udbClientTextP ctPtr;
418 extern struct bc_config *bc_globalConfig;
419 extern afs_int32 filesize();
421 /* setup the right ptr */
422 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
425 if (ctPtr->lockHandle == 0)
426 return (BC_INTERNALERROR);
428 /* truncate the file */
429 code = ftruncate(fileno(ctPtr->textStream), 0);
433 rewind(ctPtr->textStream);
435 /* write the new information */
436 fprintf(ctPtr->textStream, "%d %d\n", BC_SCHEDULE_MAGIC,
437 BC_SCHEDULE_VERSION);
439 for (tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next) {
440 fprintf(ctPtr->textStream, "%s %s %d %d\n", tdump->name, "any",
441 tdump->expDate, tdump->expType);
444 if (ferror(ctPtr->textStream))
445 return (BC_INTERNALERROR);
447 fflush(ctPtr->textStream); /* debug */
450 code = bcdb_SaveTextFile(ctPtr);
454 /* increment local version number */
455 ctPtr->textVersion++;
457 /* update locally stored file size */
458 ctPtr->textSize = filesize(ctPtr->textStream);
464 /* ------------------------------------
465 * misc. support routines - specific to dump schedules
466 * ------------------------------------
470 bc_UpdateDumpSchedule()
472 struct bc_dumpSchedule *dumpPtr, *nextDumpPtr;
473 struct udbHandleS *uhptr = &udbHandle;
474 udbClientTextP ctPtr;
478 /* lock schedules and check validity */
479 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
481 code = bc_CheckTextVersion(ctPtr);
482 if (code != BC_VERSIONMISMATCH) {
483 ERROR(code); /* Version matches or some other error */
486 /* Must update the dump schedules */
487 /* If we are not already locked, then lock it now */
488 if (!ctPtr->lockHandle) {
489 code = bc_LockText(ctPtr);
495 if (ctPtr->textVersion != -1) {
496 printf("backup: obsolete dump schedule - updating\n");
498 /* clear all old schedule information */
499 dumpPtr = bc_globalConfig->dsched;
501 nextDumpPtr = dumpPtr->next;
503 dumpPtr = nextDumpPtr;
505 bc_globalConfig->dsched = 0;;
508 /* open a temp file to store the config text received from buserver *
509 * The open file stream is stored in ctPtr->textStream */
511 bc_openTextFile(ctPtr,
513 tmpTextFileNames[TB_DUMPSCHEDULE][0]);
516 /* now get a fresh set of information from the database */
517 code = bcdb_GetTextFile(ctPtr);
521 /* fetch the version number */
523 ubik_Call(BUDB_GetTextVersion, uhptr->uh_client, 0, ctPtr->textType,
524 &ctPtr->textVersion);
529 code = bc_ParseDumpSchedule();
533 /* rebuild the tree */
534 code = bc_ProcessDumpSchedule(bc_globalConfig);
539 if (lock && ctPtr->lockHandle)
540 bc_UnlockText(ctPtr);
545 * Print out the dump schedule tree whose root is adump. Alevel should
546 * be passed in as 0, and is incremented for the recursive calls
548 * adump - ptr to the root node of a dump schedule
553 ListDumpSchedule(adump, alevel)
555 register struct bc_dumpSchedule *adump;
558 register struct bc_dumpSchedule *child;
562 /* sanity check for loops */
564 printf("backup: recursing listing dump schedule\n");
568 /* move to appropriate indentation level */
569 for (i = 0; i < alevel; i++)
572 /* name is a pathname style name, determine trailing name and only print
576 printf("/%s ", tailCompPtr(adump->name));
579 /* list expiration time */
580 switch (adump->expType) {
582 /* absolute expiration date. Never expires if date is 0 */
583 if (adump->expDate) {
584 printf("expires at %.24s", cTIME(&adump->expDate));
590 struct ktime_date kt;
592 /* expiration date relative to the time that the dump is done */
593 LongTo_ktimeRelDate(adump->expDate, &kt);
594 printf(" expires in %s", RelDatetoString(&kt));
602 for (child = adump->firstChild; child; child = child->nextSibling)
603 ListDumpSchedule(child, alevel + 1);