Bug Summary

File:butc/tcmain.c
Location:line 291, column 2
Description:Value stored to 'mvFlag' is never read

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#include <afsconfig.h>
11#include <afs/param.h>
12
13#include <afs/procmgmt.h>
14#include <roken.h>
15
16#ifdef IGNORE_SOME_GCC_WARNINGS
17# pragma GCC diagnostic warning "-Wimplicit-function-declaration"
18#endif
19
20#ifdef AFS_NT40_ENV
21#include <WINNT/afsevent.h>
22#endif
23
24#include <ctype.h>
25
26#include <rx/rx.h>
27#include <rx/rx_globals.h>
28#include <rx/rxkad.h>
29#include <rx/xdr.h>
30
31#include <afs/afsint.h>
32#include <afs/afs_assert.h>
33#include <afs/prs_fs.h>
34#include <afs/nfs.h>
35#include <afs/vlserver.h>
36#include <lwp.h>
37#include <lock.h>
38#include <afs/afsutil.h>
39#include <afs/cellconfig.h>
40#include <afs/keys.h>
41#include <afs/volser.h>
42#include <ubik.h>
43#include <afs/com_err.h>
44#include <afs/cmd.h>
45#include <afs/tcdata.h>
46#include <afs/bubasics.h>
47#include <afs/budb_errs.h>
48#include <afs/budb_client.h>
49#include <afs/bucoord_prototypes.h>
50#include <afs/butx.h>
51#include <afs/kautils.h>
52#include <afs/bc.h>
53
54#include "error_macros.h"
55#define XBSA_TCMAIN
56#include "butc_xbsa.h"
57#include "butc_prototypes.h"
58
59#define N_SECURITY_OBJECTS3 3
60#define ERRCODE_RANGE8 8 /* from error_table.h */
61
62#define TE_PREFIX"TE" "TE"
63#define TL_PREFIX"TL" "TL"
64#define CFG_PREFIX"CFG" "CFG"
65
66struct ubik_client *cstruct;
67FILE *logIO, *ErrorlogIO, *centralLogIO, *lastLogIO;
68char lFile[AFSDIR_PATH_MAX256];
69char logFile[256];
70char ErrorlogFile[256];
71char lastLogFile[256];
72char eFile[AFSDIR_PATH_MAX256];
73char tapeConfigFile[AFSDIR_PATH_MAX256];
74char pFile[AFSDIR_PATH_MAX256];
75int debugLevel = 0;
76struct tapeConfig globalTapeConfig;
77struct deviceSyncNode *deviceLatch;
78char globalCellName[64];
79char *whoami = "butc";
80
81/* GLOBAL CONFIGURATION PARAMETERS */
82int dump_namecheck;
83int queryoperator;
84int autoQuery;
85int isafile;
86int tapemounted;
87char *opencallout;
88char *closecallout;
89char *restoretofile;
90int forcemultiple;
91
92int maxpass;
93#define PASSESMIN1 1
94#define PASSESMAX10 10
95#define PASSESDFLT2 2
96afs_int32 groupId;
97#define MINGROUPID0x1 0x1
98#define MAXGROUPID0x7FFFFFFF 0x7FFFFFFF
99afs_int32 statusSize;
100#define MINSTATUS1 1
101#define MAXSTATUS0x7fffffff 0x7fffffff
102afs_int32 BufferSize; /* Size in B stored for data */
103char *centralLogFile;
104afs_int32 lastLog; /* Log last pass info */
105int rxBind = 0;
106
107#define ADDRSPERSITE16 16 /* Same global is in rx/rx_user.c */
108afs_uint32 SHostAddrs[ADDRSPERSITE16];
109
110/* dummy routine for the audit work. It should do nothing since audits */
111/* occur at the server level and bos is not a server. */
112int
113osi_audit(void)
114{
115 return 0;
116}
117
118static afs_int32
119SafeATOL(char *anum)
120{
121 afs_int32 total;
122 int tc;
123
124 total = 0;
125 while ((tc = *anum)) {
126 if (tc < '0' || tc > '9')
127 return -1;
128 total *= 10;
129 total += (tc - '0');
130 anum++;
131 }
132 return total;
133}
134
135/* atocl
136 * Convert a string into an afs_int32.
137 * Returned afs_int32 is in Bytes, Kb, Mb, Gb, or Tb. Based on crunit char.
138 * This routine only converts unsigned float values.
139 * The returned value is a whole number.
140 * entry:
141 * numstring - text string to be converted.
142 * crunit - value returned in 'B', 'K', 'M', 'G', 'T'.
143 * ' ' or NULL ==> 'B' (bytes).
144 * exit:
145 * number - returned value in requested crunit - rounded
146 * to nearest whole number.
147 * fn return value:
148 * 0 - conversion ok
149 * -1 - error in conversion
150 * notes:
151 * should deal with signed numbers. Should signal error if no digits
152 * seen.
153 */
154int
155atocl(char *numstring, char crunit, afs_int32 *number)
156{
157 float total;
158 afs_int32 runits;
159 char cunit;
160 afs_int32 units;
161 afs_int32 count;
162 char rest[256];
163
164 /* Determine which units to report in */
165 switch (crunit) {
166 case 't':
167 case 'T':
168 runits = 12;
169 break;
170
171 case 'g':
172 case 'G':
173 runits = 9;
174 break;
175
176 case 'm':
177 case 'M':
178 runits = 6;
179 break;
180
181 case 'k':
182 case 'K':
183 runits = 3;
184 break;
185
186 case 'b':
187 case 'B':
188 case ' ':
189 case 0:
190 runits = 0;
191 break;
192
193 default:
194 return (-1);
195 }
196
197 count =
198 sscanf(numstring, "%f%c%s", &total, &cunit, rest);
199 if ((count > 2) || (count <= 0))
200 return -1;
201 if (count == 1)
202 cunit = 'B'; /* bytes */
203
204 switch (cunit) {
205 case 't':
206 case 'T':
207 units = 12;
208 break;
209
210 case 'g':
211 case 'G':
212 units = 9;
213 break;
214
215 case 'm':
216 case 'M':
217 units = 6;
218 break;
219
220 case 'k':
221 case 'K':
222 units = 3;
223 break;
224
225 case 'b':
226 case 'B':
227 case ' ':
228 case 0:
229 units = 0;
230 break;
231
232 default:
233 return (-1);
234 }
235
236 /* Go to correct unit */
237 for (; units < runits; units += 3)
238 total /= 1024.0;
239 for (; units > runits; units -= 3)
240 total *= 1024.0;
241
242 total += 0.5; /* Round up */
243 if ((total > 0x7fffffff) || (total < 0)) /* Don't go over 2G */
244 total = 0x7fffffff;
245
246 *number = total;
247 return (0);
248}
249
250/* replace last two ocurrences of / by _ */
251#if 0
252static int
253stringReplace(char *name)
254{
255 char *pos;
256 char buffer[256];
257
258 pos = strrchr(name, '/');
259 *pos = '_';
260 strcpy(buffer, pos);
261 pos = strrchr(name, '/');
262 *pos = '\0';
263 strcat(name, buffer);
264 return 0;
265}
266#endif
267
268static int
269stringNowReplace(char *logFile, char *deviceName)
270{
271 char *pos = 0;
272 char storeDevice[256];
273 int mvFlag = 0, devPrefLen;
274#ifdef AFS_NT40_ENV
275 char devPrefix[] = "\\\\.";
276#else
277 char devPrefix[] = "/dev";
278#endif
279
280 devPrefLen = strlen(devPrefix);
281 strcpy(storeDevice, deviceName);
282 if (strncmp(deviceName, devPrefix, devPrefLen) == 0) {
283 deviceName += devPrefLen;
284 mvFlag++;
285 }
286 while ((pos = strchr(deviceName, devPrefix[0]))) /* look for / or \ */
287 *pos = '_';
288 strcat(logFile, deviceName);
289 /* now put back deviceName to the way it was */
290 if (mvFlag) {
291 mvFlag = 0;
Value stored to 'mvFlag' is never read
292 deviceName -= devPrefLen;
293 }
294 strcpy(deviceName, storeDevice);
295
296 return (0);
297}
298
299
300/* GetDeviceConfig
301 * get the configuration information for a particular tape device
302 * as specified by the portoffset
303 * entry:
304 * filename - full pathname of file containing the tape device
305 * configuration information
306 * config - for return results
307 * portOffset - for which configuration is required
308 * notes:
309 * logging not available when this routine is called
310 * caller return value checks
311 * exit:
312 * 0 => Found entry with same port, return info in config.
313 * -1 => Error encountered trying to read the file.
314 * 1 => Desired entry does not exist or file does not exist.
315 */
316
317#define LINESIZE256 256
318static afs_int32
319GetDeviceConfig(char *filename, struct tapeConfig *config, afs_int32 portOffset)
320{
321 FILE *devFile = 0;
322 char line[LINESIZE256];
323 char devName[LINESIZE256], tcapacity[LINESIZE256], tfmsize[LINESIZE256],
324 trest[LINESIZE256];
325 afs_int32 aport;
326 afs_int32 capacity;
327 afs_int32 fmSize;
328 afs_int32 code = 0, count;
329
330 /* Initialize the config struct */
331 config->capacity = 0;
332 config->fileMarkSize = 0;
333 config->portOffset = portOffset;
334 strcpy(config->device, "");
335
336 devFile = fopen(filename, "r");
337 if (!devFile) {
338 if (errno(* __error()) == ENOENT2)
339 ERROR_EXIT(1)do { code = 1; goto error_exit; } while (0);
340 fprintf(stderr__stderrp, "Error %d: Can't open %s\n", errno(* __error()), filename);
341 ERROR_EXIT(-1)do { code = -1; goto error_exit; } while (0);
342 }
343
344 while (fgets(line, LINESIZE256 - 1, devFile)) {
345 count =
346 sscanf(line, "%s %s %s %u%s\n", tcapacity, tfmsize, devName,
347 &aport, trest);
348
349 if (count == 4 || count == 5) {
350 if (atocl(tcapacity, 'K', &capacity)) {
351 fprintf(stderr__stderrp,
352 "tapeconfig: Tape capacity parse error in: %s\n",
353 line);
354 ERROR_EXIT(-1)do { code = -1; goto error_exit; } while (0);
355 }
356 if (atocl(tfmsize, 'B', &fmSize)) {
357 fprintf(stderr__stderrp,
358 "tapeconfig: File-mark size parse error in: %s\n",
359 line);
360 ERROR_EXIT(-1)do { code = -1; goto error_exit; } while (0);
361 }
362 } else {
363 count = sscanf(line, "%s %u%s\n", devName, &aport, trest);
364 if (count == 2 || count == 3) {
365 capacity = 0x7fffffff;
366 fmSize = 0;
367 } else {
368 fprintf(stderr__stderrp, "tapeconfig: Parse error in: %s\n", line);
369 ERROR_EXIT(-1)do { code = -1; goto error_exit; } while (0);
370 }
371 }
372
373 if ((aport < 0) || (aport > BC_MAXPORTOFFSET58510)) {
374 fprintf(stderr__stderrp, "tapeconfig: Port offset parse error in: %s\n",
375 line);
376 ERROR_EXIT(-1)do { code = -1; goto error_exit; } while (0);
377 }
378
379 if (aport != portOffset)
380 continue;
381
382 if (fmSize < 0) {
383 fprintf(stderr__stderrp, "Invalid file mark size, %d, in: %s\n", fmSize,
384 line);
385 ERROR_EXIT(-1)do { code = -1; goto error_exit; } while (0);
386 }
387
388 config->capacity = capacity;
389 config->fileMarkSize = fmSize;
390 config->portOffset = aport;
391 strncpy(config->device, devName, 100);
392
393 ERROR_EXIT(0)do { code = 0; goto error_exit; } while (0);
394 }
395
396 /* fprintf(stderr, "Can't find tapeconfig entry for port offset %d\n", portOffset); */
397 ERROR_EXIT(1)do { code = 1; goto error_exit; } while (0);
398
399 error_exit:
400 if (devFile)
401 fclose(devFile);
402 return (code);
403}
404
405/* GetConfigParams
406 */
407static afs_int32
408GetConfigParams(char *filename, afs_int32 port)
409{
410 char paramFile[256];
411 FILE *devFile = 0;
412 char line[LINESIZE256], cmd[LINESIZE256], value[LINESIZE256];
413 afs_int32 code = 0;
414 int cnt;
415
416 /* DEFAULT SETTINGS FOR GLOBAL PARAMETERS */
417 dump_namecheck = 1; /* check tape name on dumps */
418 queryoperator = 1; /* can question operator */
419 autoQuery = 1; /* prompt for first tape */
420 isafile = 0; /* Do not dump to a file */
421 opencallout = NULL((void *)0); /* open callout routine */
422 closecallout = NULL((void *)0); /* close callout routine */
423 tapemounted = 0; /* tape is not mounted */
424#ifdef xbsa
425 BufferSize = (CONF_XBSA0 ? XBSADFLTBUFFER : BUTM_BLOCKSIZE16384);
426 dumpRestAuthnLevel = rpc_c_protect_level_default;
427 xbsaObjectOwner = NULL((void *)0); /* bsaObjectOwner */
428 appObjectOwner = NULL((void *)0); /* appObjectOwner */
429 adsmServerName = NULL((void *)0); /* TSM server name - same as ADSM */
430 xbsaSecToken = NULL((void *)0); /* XBSA sercurity token */
431 xbsalGName = NULL((void *)0); /* XBSA IGName */
432#else
433 BufferSize = BUTM_BLOCKSIZE16384;
434#endif /*xbsa */
435 centralLogFile = NULL((void *)0); /* Log for all butcs */
436 centralLogIO = 0; /* Log for all butcs */
437 statusSize = 0; /* size before status message */
438 maxpass = PASSESDFLT2; /* dump passes */
439 lastLog = 0; /* separate log for last pass */
440 lastLogIO = 0; /* separate log for last pass */
441 groupId = 0; /* Group id for multiple dumps */
442
443 /* Try opening the CFG_<port> file */
444 sprintf(paramFile, "%s_%d", filename, port);
445 devFile = fopen(paramFile, "r");
446 if (devFile) {
447 /* Set log names to TL_<port>, TL_<port>.lp and TE_<port> */
448 sprintf(logFile, "%s_%d", lFile, port);
449 sprintf(lastLogFile, "%s_%d.lp", lFile, port);
450 sprintf(ErrorlogFile, "%s_%d", eFile, port);
451 } else if (CONF_XBSA0) {
452 /* If configured as XBSA, a configuration file CFG_<port> must exist */
453 printf("Cannot open configuration file %s", paramFile);
454 ERROR_EXIT(1)do { code = 1; goto error_exit; } while (0);
455 } else {
456 /* Try the CFG_<device> name as the device file */
457 strcpy(paramFile, filename);
458 stringNowReplace(paramFile, globalTapeConfig.device);
459 /* Set log names to TL_<device>, TL_<device> and TE_<device> */
460 strcpy(logFile, lFile);
461 stringNowReplace(logFile, globalTapeConfig.device);
462 strcpy(lastLogFile, lFile);
463 stringNowReplace(lastLogFile, globalTapeConfig.device);
464 strcat(lastLogFile, ".lp");
465 strcpy(ErrorlogFile, eFile);
466 stringNowReplace(ErrorlogFile, globalTapeConfig.device);
467
468 /* Now open the device file */
469 devFile = fopen(paramFile, "r");
470 if (!devFile)
471 ERROR_EXIT(0)do { code = 0; goto error_exit; } while (0); /* CFG file doesn't exist for non-XBSA and that's ok */
472 }
473
474 /* Read each line of the Configuration file */
475 while (fgets(line, LINESIZE256 - 1, devFile)) {
476 cnt = sscanf(line, "%s %s", cmd, value);
477 if (cnt != 2) {
478 if (cnt > 0)
479 printf("Bad line in %s: %s\n", paramFile, line);
480 continue;
481 }
482
483 for (cnt = 0; cnt < strlen(cmd); cnt++)
484 if (islower(cmd[cnt])__sbistype((cmd[cnt]), 0x00001000L))
485 cmd[cnt] = toupper(cmd[cnt])__sbtoupper(cmd[cnt]);
486
487 if (!strcmp(cmd, "NAME_CHECK")) {
488 if (CONF_XBSA0) {
489 printf
490 ("Warning: The %s parameter is ignored with a Backup Service\n",
491 cmd);
492 continue;
493 }
494
495 for (cnt = 0; cnt < strlen(value); cnt++)
496 if (islower(value[cnt])__sbistype((value[cnt]), 0x00001000L))
497 value[cnt] = toupper(value[cnt])__sbtoupper(value[cnt]);
498
499 if (!strcmp(value, "NO")) {
500 printf("Dump tape name check is disabled\n");
501 dump_namecheck = 0;
502 } else {
503 printf("Dump tape name check is enabled\n");
504 dump_namecheck = 1;
505 }
506 }
507
508 else if (!strcmp(cmd, "MOUNT")) {
509 if (CONF_XBSA0) {
510 printf
511 ("Warning: The %s parameter is ignored with a Backup Service\n",
512 cmd);
513 continue;
514 }
515
516 opencallout = (char *)malloc(strlen(value) + 1);
517 strcpy(opencallout, value);
518 printf("Tape mount callout routine is %s\n", opencallout);
519 }
520
521 else if (!strcmp(cmd, "UNMOUNT")) {
522 if (CONF_XBSA0) {
523 printf
524 ("Warning: The %s parameter is ignored with a Backup Service\n",
525 cmd);
526 continue;
527 }
528
529 closecallout = (char *)malloc(strlen(value) + 1);
530 strcpy(closecallout, value);
531 printf("Tape unmount callout routine is %s\n", closecallout);
532 }
533
534 else if (!strcmp(cmd, "ASK")) {
535 for (cnt = 0; cnt < strlen(value); cnt++)
536 if (islower(value[cnt])__sbistype((value[cnt]), 0x00001000L))
537 value[cnt] = toupper(value[cnt])__sbtoupper(value[cnt]);
538
539 if (!strcmp(value, "NO")) {
540 printf("Operator queries are disabled\n");
541 queryoperator = 0;
542 } else {
543 printf("Operator queries are enabled\n");
544 queryoperator = 1;
545 }
546 }
547
548 else if (!strcmp(cmd, "FILE")) {
549 if (CONF_XBSA0) {
550 printf
551 ("Warning: The %s parameter is ignored with a Backup Service\n",
552 cmd);
553 continue;
554 }
555
556 for (cnt = 0; cnt < strlen(value); cnt++)
557 if (islower(value[cnt])__sbistype((value[cnt]), 0x00001000L))
558 value[cnt] = toupper(value[cnt])__sbtoupper(value[cnt]);
559
560 if (!strcmp(value, "YES")) {
561 printf("Will dump to a file\n");
562 isafile = 1;
563 } else {
564 printf("Will not dump to a file\n");
565 isafile = 0;
566 }
567 }
568
569 else if (!strcmp(cmd, "AUTOQUERY")) {
570 if (CONF_XBSA0) {
571 printf
572 ("Warning: The %s parameter is ignored with a Backup Service\n",
573 cmd);
574 continue;
575 }
576
577 for (cnt = 0; cnt < strlen(value); cnt++)
578 if (islower(value[cnt])__sbistype((value[cnt]), 0x00001000L))
579 value[cnt] = toupper(value[cnt])__sbtoupper(value[cnt]);
580
581 if (!strcmp(value, "NO")) {
582 printf("Auto query is disabled\n");
583 autoQuery = 0;
584 } else {
585 printf("Auto query is enabled\n");
586 autoQuery = 1;
587 }
588 }
589
590 else if (!strcmp(cmd, "BUFFERSIZE")) {
591 afs_int32 size;
592 afs_int32 tapeblocks;
593
594 if (!CONF_XBSA0) {
595 if (atocl(value, 'K', &size)) {
596 fprintf(stderr__stderrp, "BUFFERSIZE parse error\n");
597 size = 0;
598 }
599
600 /* A tapeblock is 16KB. Determine # of tapeblocks. Then
601 * determine BufferSize needed for that many tapeblocks.
602 */
603 tapeblocks = size / 16;
604 if (tapeblocks <= 0)
605 tapeblocks = 1;
606 printf("BUFFERSIZE is %u KBytes\n", (tapeblocks * 16));
607 BufferSize = tapeblocks * BUTM_BLOCKSIZE16384;
608 } else {
609#ifdef xbsa
610 if (atocl(value, 'B', &size)) {
611 fprintf(stderr__stderrp, "BUFFERSIZE parse error\n");
612 size = 0;
613 }
614 if (size < XBSAMINBUFFER)
615 size = XBSAMINBUFFER;
616 if (size > XBSAMAXBUFFER)
617 size = XBSAMAXBUFFER;
618 printf("XBSA buffer size is %u Bytes\n", size);
619 BufferSize = size;
620#endif
621 }
622 }
623#ifndef xbsa
624 /* All the xbsa spacific parameters */
625 else if (!strcmp(cmd, "TYPE") || !strcmp(cmd, "NODE")
626 || !strcmp(cmd, "SERVER") || !strcmp(cmd, "PASSWORD")
627 || !strcmp(cmd, "PASSFILE") || !strcmp(cmd, "MGMTCLASS")) {
628 printf("This binary does not have XBSA support\n");
629 return 1;
630 }
631#else
632 else if (!strcmp(cmd, "TYPE")) { /* required for XBSA */
633 if (!CONF_XBSA0) {
634 printf
635 ("Warning: The %s parameter is ignored with a tape drive\n",
636 cmd);
637 continue;
638 }
639
640 for (cnt = 0; (size_t) cnt < strlen(value); cnt++)
641 if (islower(value[cnt])__sbistype((value[cnt]), 0x00001000L))
642 value[cnt] = toupper(value[cnt])__sbtoupper(value[cnt]);
643
644 if (strcmp(value, "TSM") == 0) {
645 xbsaType = XBSA_SERVER_TYPE_ADSM0x02; /* Known XBSA server type */
646 } else {
647 printf("Configuration file error, %s %s is not recognized\n",
648 cmd, value);
649 xbsaType = XBSA_SERVER_TYPE_UNKNOWN0x01;
650 }
651 printf("XBSA type is %s\n",
652 ((xbsaType ==
653 XBSA_SERVER_TYPE_UNKNOWN0x01) ? "Unknown" : value));
654 }
655
656 else if (!strcmp(cmd, "NODE")) {
657 if (!CONF_XBSA0) {
658 printf
659 ("Warning: The %s parameter is ignored with a tape drive\n",
660 cmd);
661 continue;
662 }
663 xbsaObjectOwner = malloc(strlen(value) + 1);
664 strcpy(xbsaObjectOwner, value);
665 printf("XBSA node is %s\n", xbsaObjectOwner);
666 }
667
668 else if (!strcmp(cmd, "SERVER")) { /* required for XBSA */
669 if (!CONF_XBSA0) {
670 printf
671 ("Warning: The %s parameter is ignored with a tape drive\n",
672 cmd);
673 continue;
674 }
675 adsmServerName = malloc(strlen(value) + 1);
676 strcpy(adsmServerName, value);
677 printf("XBSA server is %s\n", adsmServerName);
678 }
679
680 else if (!strcmp(cmd, "PASSWORD")) { /* This or PASSFILE required for XBSA */
681 if (!CONF_XBSA0) {
682 printf
683 ("Warning: The %s parameter is ignored with a tape drive\n",
684 cmd);
685 continue;
686 }
687 if (xbsaSecToken) {
688 printf
689 ("Warning: The %s parameter is ignored. Already read password\n",
690 cmd);
691 continue;
692 }
693
694 xbsaSecToken = malloc(strlen(value) + 1);
695 strcpy(xbsaSecToken, value);
696 printf("XBSA Password has been read\n");
697 }
698
699 else if (!strcmp(cmd, "PASSFILE")) { /* This or PASSWORD required for XBSA */
700 FILE *pwdFile;
701 if (!CONF_XBSA0) {
702 printf
703 ("Warning: The %s parameter is ignored with a tape drive\n",
704 cmd);
705 continue;
706 }
707 if (xbsaSecToken) {
708 printf
709 ("Warning: The %s parameter is ignored. Already read password\n",
710 cmd);
711 continue;
712 }
713
714 pwdFile = fopen(value, "r");
715 if (!pwdFile) {
716 printf
717 ("Configuration file error, cannot open password file %s\n",
718 value);
719 ERROR_EXIT(1)do { code = 1; goto error_exit; } while (0);
720 }
721 xbsaSecToken = malloc(LINESIZE256);
722 if (!fscanf(pwdFile, "%s", xbsaSecToken)) {
723 printf
724 ("Configuration file error, cannot read password file %s\n",
725 value);
726 ERROR_EXIT(1)do { code = 1; goto error_exit; } while (0);
727 }
728 printf("XBSA password retrieved from password file\n");
729 }
730
731 else if (!strcmp(cmd, "MGMTCLASS")) { /* XBSA */
732 if (!CONF_XBSA0) {
733 printf
734 ("Warning: The %s parameter is ignored with a tape drive\n",
735 cmd);
736 continue;
737 }
738 xbsalGName = malloc(strlen(value) + 1);
739 strcpy(xbsalGName, value);
740 printf("XBSA management class is %s\n", xbsalGName);
741 }
742#endif
743
744 else if (!strcmp(cmd, "MAXPASS")) {
745 maxpass = SafeATOL(value);
746 if (maxpass < PASSESMIN1)
747 maxpass = PASSESMIN1;
748 if (maxpass > PASSESMAX10)
749 maxpass = PASSESMAX10;
750 printf("MAXPASS is %d\n", maxpass);
751 }
752
753 else if (!strcmp(cmd, "GROUPID")) {
754 groupId = SafeATOL(value);
755 if ((groupId < MINGROUPID0x1) || (groupId > MAXGROUPID0x7FFFFFFF)) {
756 printf("Configuration file error, %s %s is invalid\n", cmd,
757 value);
758 ERROR_EXIT(1)do { code = 1; goto error_exit; } while (0);
759 }
760 printf("Group Id is %d\n", groupId);
761 }
762
763 else if (!strcmp(cmd, "LASTLOG")) {
764 for (cnt = 0; (size_t) cnt < strlen(value); cnt++)
765 if (islower(value[cnt])__sbistype((value[cnt]), 0x00001000L))
766 value[cnt] = toupper(value[cnt])__sbtoupper(value[cnt]);
767
768 lastLog = (strcmp(value, "YES") == 0);
769 printf("Will %sgenerate a last log\n", (lastLog ? "" : "not "));
770 }
771
772 else if (!strcmp(cmd, "CENTRALLOG")) {
773 centralLogFile = malloc(strlen(value) + 1);
774 strcpy(centralLogFile, value);
775 printf("Central log file is %s\n", centralLogFile);
776 }
777
778 else if (!strcmp(cmd, "STATUS")) {
779 if (atocl(value, 'B', &statusSize)) {
780 fprintf(stderr__stderrp, "STATUS parse error\n");
781 statusSize = 0;
782 }
783 if (statusSize < MINSTATUS1)
784 statusSize = MINSTATUS1;
785 if (statusSize > MAXSTATUS0x7fffffff)
786 statusSize = MAXSTATUS0x7fffffff;
787 }
788
789 else {
790 printf("Warning: Unrecognized configuration parameter: %s", line);
791 }
792 } /*fgets */
793
794 if (statusSize) {
795 /* Statussize is in bytes and requires that BufferSize be set first */
796 statusSize *= BufferSize;
797 if (statusSize < 0)
798 statusSize = 0x7fffffff; /*max size */
799 printf("Status every %ld Bytes\n", afs_printable_int32_ld(statusSize));
800 }
801
802 error_exit:
803 if (devFile)
804 fclose(devFile);
805
806 /* If the butc is configured as XBSA, check for required parameters */
807#ifdef xbsa
808 if (!code && CONF_XBSA0) {
809 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN0x01) {
810 printf
811 ("Configuration file error, the TYPE parameter must be specified, or\n");
812 printf("an entry must exist in %s for port %d\n", tapeConfigFile,
813 port);
814 code = 1;
815 }
816 if (!adsmServerName) {
817 printf
818 ("Configuration file error, the SERVER parameter must be specified\n");
819 code = 1;
820 }
821 if (!xbsaSecToken) {
822 printf
823 ("Configuration file error, the PASSWORD or PASSFILE parameter must be specified\n");
824 code = 1;
825 }
826 }
827#endif /*xbsa */
828 return (code);
829}
830
831static int
832WorkerBee(struct cmd_syndesc *as, void *arock)
833{
834 afs_int32 code;
835 struct rx_securityClass *(securityObjects[3]);
836 struct rx_service *service;
837 time_t tokenExpires;
838 char cellName[64];
839 int localauth;
840 /*process arguments */
841 afs_int32 portOffset = 0;
842#ifdef AFS_PTHREAD_ENV
843 pthread_t dbWatcherPid;
844 pthread_attr_t tattr;
845 AFS_SIGSET_DECL;
846#else
847 PROCESS dbWatcherPid;
848#endif
849 afs_uint32 host = htonl(INADDR_ANY)(__builtin_constant_p((u_int32_t)0x00000000) ? ((((__uint32_t
)((u_int32_t)0x00000000)) >> 24) | ((((__uint32_t)((u_int32_t
)0x00000000)) & (0xff << 16)) >> 8) | ((((__uint32_t
)((u_int32_t)0x00000000)) & (0xff << 8)) << 8
) | (((__uint32_t)((u_int32_t)0x00000000)) << 24)) : __bswap32_var
((u_int32_t)0x00000000))
;
850
851 debugLevel = 0;
852
853 /*initialize the error tables */
854 initialize_KA_error_table();
855 initialize_RXK_error_table();
856 initialize_KTC_error_table();
857 initialize_ACFG_error_table();
858 initialize_CMD_error_table();
859 initialize_VL_error_table();
860 initialize_BUTM_error_table();
861 initialize_BUTC_error_table();
862#ifdef xbsa
863 initialize_BUTX_error_table();
864#endif /*xbs */
865 initialize_VOLS_error_table();
866 initialize_BUDB_error_table();
867 initialize_BUCD_error_table();
868
869 if (as->parms[0].items) {
870 portOffset = SafeATOL(as->parms[0].items->data);
871 if (portOffset == -1) {
872 fprintf(stderr__stderrp, "Illegal port offset '%s'\n",
873 as->parms[0].items->data);
874 exit(1);
875 } else if (portOffset > BC_MAXPORTOFFSET58510) {
876 fprintf(stderr__stderrp, "%u exceeds max port offset %u\n", portOffset,
877 BC_MAXPORTOFFSET58510);
878 exit(1);
879 }
880 }
881
882 xbsaType = XBSA_SERVER_TYPE_NONE0x00; /* default */
883 if (as->parms[3].items) { /* -device */
884 globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */
885 globalTapeConfig.fileMarkSize = 0;
886 globalTapeConfig.portOffset = portOffset;
887 strncpy(globalTapeConfig.device, as->parms[3].items->data, 100);
888 xbsaType = XBSA_SERVER_TYPE_NONE0x00; /* Not XBSA */
889 } else {
890 /* Search for an entry in tapeconfig file */
891 code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset);
892 if (code == -1) {
893 fprintf(stderr__stderrp, "Problem in reading config file %s\n",
894 tapeConfigFile);
895 exit(1);
896 }
897 /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so
898 * it's an XBSA server. Don't know if its ADSM or not so its unknown.
899 */
900 xbsaType =
901 ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN0x01 : XBSA_SERVER_TYPE_NONE0x00);
902 }
903
904 if (as->parms[6].items) { /* -restoretofile */
905 int s = strlen(as->parms[6].items->data);
906 restoretofile = malloc(s + 1);
907 strncpy(restoretofile, as->parms[6].items->data, s + 1);
908 printf("Restore to file '%s'\n", restoretofile);
909 }
910
911 /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set
912 * the exact xbsaType within the call (won't be unknown) - double check.
913 */
914 code = GetConfigParams(pFile, portOffset);
915 if (code)
916 exit(code);
917#ifdef xbsa
918 if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN0x01) {
919 printf
920 ("\nConfiguration file error, the TYPE parameter must be specified, or\n");
921 printf("an entry must exist in %s for port %d\n", tapeConfigFile,
922 portOffset);
923 exit(1);
924 }
925#else
926 /* Not compiled for XBSA code so we can't support it */
927 if (CONF_XBSA0) {
928 printf("\nNo entry found in %s for port %d\n", tapeConfigFile,
929 portOffset);
930 printf("This binary does not have XBSA support\n");
931 exit(1);
932 }
933#endif
934
935 /* Open the log files. The pathnames were set in GetConfigParams() */
936 logIO = fopen(logFile, "a");
937 if (!logIO) {
938 fprintf(stderr__stderrp, "Failed to open %s\n", logFile);
939 exit(1);
940 }
941 ErrorlogIO = fopen(ErrorlogFile, "a");
942 if (!ErrorlogIO) {
943 fprintf(stderr__stderrp, "Failed to open %s\n", ErrorlogFile);
944 exit(1);
945 }
946 if (lastLog) {
947 lastLogIO = fopen(lastLogFile, "a");
948 if (!lastLogIO) {
949 fprintf(stderr__stderrp, "Failed to open %s\n", lastLogFile);
950 exit(1);
951 }
952 }
953 if (centralLogFile) {
954 struct stat sbuf;
955 afs_int32 statcode;
956#ifndef AFS_NT40_ENV
957 char path[AFSDIR_PATH_MAX256];
958#endif
959
960 statcode = stat(centralLogFile, &sbuf);
961 centralLogIO = fopen(centralLogFile, "a");
962 if (!centralLogIO) {
963 fprintf(stderr__stderrp, "Failed to open %s; error %d\n", centralLogFile,
964 errno(* __error()));
965 exit(1);
966 }
967#ifndef AFS_NT40_ENV
968 /* Make sure it is not in AFS, has to have been created first */
969 if (!realpath(centralLogFile, path)) {
970 fprintf(stderr__stderrp,
971 "Warning: can't determine real path of '%s' (%d)\n",
972 centralLogFile, errno(* __error()));
973 } else {
974 if (strncmp(path, "/afs/", 5) == 0) {
975 fprintf(stderr__stderrp, "The central log '%s' should not be in AFS\n",
976 centralLogFile);
977 exit(1);
978 }
979 }
980#endif
981
982 /* Write header if created it */
983 if (statcode) {
984 char *h1 =
985 "TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n";
986 char *h2 =
987 "----- ------------------- ------------------- -------- ---------\n";
988 /* File didn't exist before so write the header lines */
989 fwrite(h1, strlen(h1), 1, centralLogIO);
990 fwrite(h2, strlen(h2), 1, centralLogIO);
991 fflush(centralLogIO);
992 }
993 }
994
995 if (as->parms[1].items) {
996 debugLevel = SafeATOL(as->parms[1].items->data);
997 if (debugLevel == -1) {
998 TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data);
999 exit(1);
1000 }
1001 }
1002#ifdef xbsa
1003 /* Setup XBSA library interface */
1004 if (CONF_XBSA0) {
1005 afs_int32 rc;
1006 rc = xbsa_MountLibrary(&butxInfo, xbsaType);
1007 if (rc != XBSA_SUCCESS) {
1008 TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n");
1009 return (1);
1010 }
1011
1012 forcemultiple = (as->parms[7].items ? 1 : 0);/*-xbsaforcemultiple */
1013 if (forcemultiple)
1014 printf("Force XBSA multiple server support\n");
1015
1016 rc = InitToServer(0 /*taskid */ , &butxInfo, adsmServerName);
1017 if (rc != XBSA_SUCCESS)
1018 return (1);
1019 }
1020#endif /*xbsa */
1021
1022 /* cell switch */
1023 if (as->parms[2].items)
1024 strncpy(cellName, as->parms[2].items->data, sizeof(cellName));
1025 else
1026 cellName[0] = '\0';
1027
1028 if (as->parms[4].items)
1029 autoQuery = 0;
1030
1031 localauth = (as->parms[5].items ? 1 : 0);
1032 rxBind = (as->parms[8].items ? 1 : 0);
1033
1034 if (rxBind) {
1035 afs_int32 ccode;
1036 if (AFSDIR_SERVER_NETRESTRICT_FILEPATHgetDirPath(AFSDIR_SERVER_NETRESTRICT_FILEPATH_ID) ||
1037 AFSDIR_SERVER_NETINFO_FILEPATHgetDirPath(AFSDIR_SERVER_NETINFO_FILEPATH_ID)) {
1038 char reason[1024];
1039 ccode = parseNetFiles(SHostAddrs, NULL((void *)0), NULL((void *)0),
1040 ADDRSPERSITE16, reason,
1041 AFSDIR_SERVER_NETINFO_FILEPATHgetDirPath(AFSDIR_SERVER_NETINFO_FILEPATH_ID),
1042 AFSDIR_SERVER_NETRESTRICT_FILEPATHgetDirPath(AFSDIR_SERVER_NETRESTRICT_FILEPATH_ID));
1043 } else
1044 {
1045 ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE16);
1046 }
1047 if (ccode == 1)
1048 host = SHostAddrs[0];
1049 }
1050
1051 code = rx_InitHost(host, htons(BC_TAPEPORT + portOffset)(__builtin_constant_p(7025 + portOffset) ? (__uint16_t)(((__uint16_t
)(7025 + portOffset)) << 8 | ((__uint16_t)(7025 + portOffset
)) >> 8) : __bswap16_var(7025 + portOffset))
);
1052 if (code) {
1053 TapeLog(0, 0, code, 0, "rx init failed on port %u\n",
1054 BC_TAPEPORT7025 + portOffset);
1055 exit(1);
1056 }
1057 rx_SetRxDeadTime(150)(rx_connDeadTime = (150));
1058
1059 /* Establish connection with the vldb server */
1060 code = vldbClientInit(0, localauth, cellName, &cstruct, &tokenExpires);
1061 if (code) {
1062 TapeLog(0, 0, code, 0, "Can't access vldb\n");
1063 return code;
1064 }
1065
1066 strcpy(globalCellName, cellName);
1067
1068 /*initialize the dumpNode list */
1069 InitNodeList(portOffset);
1070
1071 deviceLatch =
1072 (struct deviceSyncNode *)(malloc(sizeof(struct deviceSyncNode)));
1073 Lock_Init(&(deviceLatch->lock));
1074 deviceLatch->flags = 0;
1075
1076 /* initialize database support, volume support, and logs */
1077
1078 /* Create a single security object, in this case the null security
1079 * object, for unauthenticated connections, which will be used to control
1080 * security on connections made to this server
1081 */
1082
1083 securityObjects[0] = rxnull_NewServerSecurityObject();
1084 securityObjects[1] = (struct rx_securityClass *)0; /* don't bother with rxvab */
1085 if (!securityObjects[0]) {
1086 TLog(0, "rxnull_NewServerSecurityObject");
1087 exit(1);
1088 }
1089
1090 service =
1091 rx_NewServiceHost(host, 0, 1, "BUTC", securityObjects, 3, TC_ExecuteRequest);
1092 if (!service) {
1093 TLog(0, "rx_NewService");
1094 exit(1);
1095 }
1096 rx_SetMaxProcs(service, 4)((service)->maxProcs = (4));
1097
1098 /* Establish connection to the backup database */
1099 code = udbClientInit(0, localauth, cellName);
1100 if (code) {
1101 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1102 exit(1);
1103 }
1104 /* This call is here to verify that we are authentiated.
1105 * The call does nothing and will return BUDB_NOTPERMITTED
1106 * if we don't belong.
1107 */
1108 code = bcdb_deleteDump(0, 0, 0, 0);
1109 if (code == BUDB_NOTPERMITTED(156303880L)) {
1110 TapeLog(0, 0, code, 0, "Can't access backup database\n");
1111 exit(1);
1112 }
1113
1114 initStatus();
1115#ifdef AFS_PTHREAD_ENV
1116 code = pthread_attr_init(&tattr);
1117 if (code) {
1118 TapeLog(0, 0, code, 0,
1119 "Can't pthread_attr_init database monitor task");
1120 exit(1);
1121 }
1122 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
1123 if (code) {
1124 TapeLog(0, 0, code, 0,
1125 "Can't pthread_attr_setdetachstate database monitor task");
1126 exit(1);
1127 }
1128 AFS_SIGSET_CLEAR();
1129 code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2);
1130 AFS_SIGSET_RESTORE();
1131#else
1132 code =
1133 LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY(4 -2), (void *)2,
1134 "dbWatcher", &dbWatcherPid);
1135#endif
1136 if (code) {
1137 TapeLog(0, 0, code, 0, "Can't create database monitor task");
1138 exit(1);
1139 }
1140
1141 TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n",
1142 portOffset, debugLevel);
1143 TLog(0, "Token expires: %s\n", cTIME(&tokenExpires)( (*(&tokenExpires) == 0xffffffff) ? (char *)"NEVER \n"
: (char *)ctime(&tokenExpires) )
);
1144
1145 rx_StartServer(1); /* Donate this process to the server process pool */
1146 TLog(0, "Error: StartServer returned");
1147 exit(1);
1148}
1149
1150#ifndef AFS_NT40_ENV
1151#include "AFS_component_version_number.c"
1152#endif
1153
1154int
1155main(int argc, char **argv)
1156{
1157 struct cmd_syndesc *ts;
1158 struct cmd_item *ti;
1159
1160#ifdef AFS_AIX32_ENV
1161 /*
1162 * The following signal action for AIX is necessary so that in case of a
1163 * crash (i.e. core is generated) we can include the user's data section
1164 * in the core dump. Unfortunately, by default, only a partial core is
1165 * generated which, in many cases, isn't too useful.
1166 */
1167 struct sigaction nsa;
1168
1169 sigemptyset(&nsa.sa_mask);
1170 nsa.sa_handler__sigaction_u.__sa_handler = SIG_DFL((__sighandler_t *)0);
1171 nsa.sa_flags = SA_FULLDUMP;
1172 sigaction(SIGSEGV11, &nsa, NULL((void *)0));
1173 sigaction(SIGABRT6, &nsa, NULL((void *)0));
1174#endif
1175
1176 setlinebuf(stdout__stdoutp);
1177
1178 ts = cmd_CreateSyntax(NULL((void *)0), WorkerBee, NULL((void *)0), "tape coordinator");
1179 cmd_AddParm(ts, "-port", CMD_SINGLE2, CMD_OPTIONAL1, "port offset");
1180 cmd_AddParm(ts, "-debuglevel", CMD_SINGLE2, CMD_OPTIONAL1, "0 | 1 | 2");
1181 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cell name");
1182 cmd_AddParm(ts, "-device", CMD_SINGLE2, (CMD_OPTIONAL1 | CMD_HIDE4),
1183 "tape device path");
1184 cmd_AddParm(ts, "-noautoquery", CMD_FLAG1, CMD_OPTIONAL1,
1185 "do not query operator for first tape");
1186 cmd_AddParm(ts, "-localauth", CMD_FLAG1, CMD_OPTIONAL1,
1187 "create tickets from KeyFile");
1188 cmd_AddParm(ts, "-restoretofile", CMD_SINGLE2, (CMD_OPTIONAL1 | CMD_HIDE4),
1189 "file to restore to");
1190 cmd_AddParm(ts, "-xbsaforcemultiple", CMD_FLAG1, (CMD_OPTIONAL1 | CMD_HIDE4),
1191 "Force multiple XBSA server support");
1192 cmd_AddParm(ts, "-rxbind", CMD_FLAG1, CMD_OPTIONAL1,
1193 "bind Rx socket");
1194
1195 /* Initialize dirpaths */
1196 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK0x2)) {
1197#ifdef AFS_NT40_ENV
1198 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
1199#endif
1200 fprintf(stderr__stderrp, "Unable to obtain AFS server directory.\n");
1201 exit(2);
1202 }
1203
1204 /* setup the file paths */
1205 strcompose(eFile, AFSDIR_PATH_MAX256, AFSDIR_SERVER_BACKUP_DIRPATHgetDirPath(AFSDIR_SERVER_BACKUP_DIRPATH_ID), "/",
1206 TE_PREFIX"TE", NULL((void *)0));
1207 strcompose(lFile, AFSDIR_PATH_MAX256, AFSDIR_SERVER_BACKUP_DIRPATHgetDirPath(AFSDIR_SERVER_BACKUP_DIRPATH_ID), "/",
1208 TL_PREFIX"TL", NULL((void *)0));
1209 strcompose(pFile, AFSDIR_PATH_MAX256, AFSDIR_SERVER_BACKUP_DIRPATHgetDirPath(AFSDIR_SERVER_BACKUP_DIRPATH_ID), "/",
1210 CFG_PREFIX"CFG", NULL((void *)0));
1211 strcpy(tapeConfigFile, AFSDIR_SERVER_TAPECONFIG_FILEPATHgetDirPath(AFSDIR_SERVER_TAPECONFIG_FILEPATH_ID));
1212
1213 /* special case "no args" case since cmd_dispatch gives help message
1214 * instead
1215 */
1216 if (argc == 1) {
1217 ts = (struct cmd_syndesc *)malloc(sizeof(struct cmd_syndesc));
1218 memset(ts, 0, sizeof(*ts));
1219
1220 ti = (struct cmd_item *)malloc(sizeof(struct cmd_item));
1221 ti->next = 0;
1222 ti->data = "0";
1223 ts->parms[0].items = ti;
1224 ti = (struct cmd_item *)malloc(sizeof(struct cmd_item));
1225 ti->next = 0;
1226 ti->data = "0";
1227 ts->parms[1].items = ti;
1228 ts->parms[2].items = (struct cmd_item *)NULL((void *)0);
1229 ts->parms[3].items = (struct cmd_item *)NULL((void *)0);
1230 ts->parms[4].items = (struct cmd_item *)NULL((void *)0);
1231 ts->parms[5].items = (struct cmd_item *)NULL((void *)0);
1232 return WorkerBee(ts, NULL((void *)0));
1233 } else
1234 return cmd_Dispatch(argc, argv);
1235}