📄 amindexd.c
字号:
static char *emsg = NULL; am_feature_e marshall_feature; if (recursive) { marshall_feature = fe_amindexd_marshall_in_ORLD; } else { marshall_feature = fe_amindexd_marshall_in_OLSD; } clear_dir_list(); if (config_name == NULL) { reply(502, _("Must set config,host,disk before listing a directory")); return -1; } else if (dump_hostname == NULL) { reply(502, _("Must set host,disk before listing a directory")); return -1; } else if (disk_name == NULL) { reply(502, _("Must set disk before listing a directory")); return -1; } else if (target_date == NULL) { reply(502, _("Must set date before listing a directory")); return -1; } /* scan through till we find first dump on or before date */ for (dump_item=first_dump(); dump_item!=NULL; dump_item=next_dump(dump_item)) if (cmp_date(dump_item->date, target_date) <= 0) break; if (dump_item == NULL) { /* no dump for given date */ reply(500, _("No dumps available on or before date \"%s\""), target_date); return -1; } /* get data from that dump */ if (process_ls_dump(dir, dump_item, recursive, &emsg) == -1) { reply(599, _("System error %s"), emsg); amfree(emsg); return -1; } /* go back processing higher level dumps till we hit a level 0 dump */ last_level = dump_item->level; while ((last_level != 0) && ((dump_item=next_dump(dump_item)) != NULL)) { if (dump_item->level < last_level) { last_level = dump_item->level; if (process_ls_dump(dir, dump_item, recursive, &emsg) == -1) { reply(599, _("System error %s"), emsg); amfree(emsg); return -1; } } } /* return the information to the caller */ lreply(200, _(" Opaque list of %s"), dir); for(level=0; level<=9; level++) { for (dir_item = get_dir_list(); dir_item != NULL; dir_item = dir_item->next) { if(dir_item->dump->level == level) { if (!am_has_feature(their_features, marshall_feature) && (num_entries(dir_item->dump->tapes) > 1 || dir_item->dump->tapes->numfiles > 1)) { fast_lreply(501, _(" ERROR: Split dumps not supported" " with old version of amrecover.")); break; } else { opaque_ls_one(dir_item, marshall_feature, recursive); } } } } reply(200, _(" Opaque list of %s"), dir); clear_dir_list(); return 0;}void opaque_ls_one( DIR_ITEM * dir_item, am_feature_e marshall_feature, int recursive){ char date[20]; char *tapelist_str; char *qpath; if (am_has_feature(their_features, marshall_feature)) { tapelist_str = marshal_tapelist(dir_item->dump->tapes, 1); } else { tapelist_str = dir_item->dump->tapes->label; } strncpy(date, dir_item->dump->date, 20); date[19] = '\0'; if(!am_has_feature(their_features,fe_amrecover_timestamp)) date[10] = '\0'; qpath = quote_string(dir_item->path); if((!recursive && am_has_feature(their_features, fe_amindexd_fileno_in_OLSD)) || (recursive && am_has_feature(their_features, fe_amindexd_fileno_in_ORLD))) { fast_lreply(201, " %s %d %s %lld %s", date, dir_item->dump->level, tapelist_str, (long long)dir_item->dump->file, qpath); } else { fast_lreply(201, " %s %d %s %s", date, dir_item->dump->level, tapelist_str, qpath); } amfree(qpath); if(am_has_feature(their_features, marshall_feature)) { amfree(tapelist_str); }}/* * returns the value of changer or tapedev from the amanda.conf file if set, * otherwise reports an error */static inttapedev_is(void){ char *result; /* check state okay to do this */ if (config_name == NULL) { reply(501, _("Must set config before asking about tapedev.")); return -1; } /* use amrecover_changer if possible */ if ((result = getconf_str(CNF_AMRECOVER_CHANGER)) != NULL && *result != '\0') { dbprintf(_("tapedev_is amrecover_changer: %s\n"), result); reply(200, result); return 0; } /* use changer if possible */ if ((result = getconf_str(CNF_TPCHANGER)) != NULL && *result != '\0') { dbprintf(_("tapedev_is tpchanger: %s\n"), result); reply(200, result); return 0; } /* get tapedev value */ if ((result = getconf_str(CNF_TAPEDEV)) != NULL && *result != '\0') { dbprintf(_("tapedev_is tapedev: %s\n"), result); reply(200, result); return 0; } dbprintf(_("No tapedev or tpchanger in config site.\n")); reply(501, _("Tapedev or tpchanger not set in config file.")); return -1;}/* returns YES if dumps for disk are compressed, NO if not */static intare_dumps_compressed(void){ disk_t *diskp; /* check state okay to do this */ if (config_name == NULL) { reply(501, _("Must set config,host,disk name before asking about dumps.")); return -1; } else if (dump_hostname == NULL) { reply(501, _("Must set host,disk name before asking about dumps.")); return -1; } else if (disk_name == NULL) { reply(501, _("Must set disk name before asking about dumps.")); return -1; } /* now go through the list of disks and find which have indexes */ for (diskp = disk_list.head; diskp != NULL; diskp = diskp->next) { if ((strcasecmp(diskp->host->hostname, dump_hostname) == 0) && (strcmp(diskp->name, disk_name) == 0)) { break; } } if (diskp == NULL) { reply(501, _("Couldn't find host/disk in disk file.")); return -1; } /* send data to caller */ if (diskp->compress == COMP_NONE) reply(200, "NO"); else reply(200, "YES"); return 0;}intmain( int argc, char ** argv){ char *line = NULL, *part = NULL; char *s; int ch; char *cmd_undo, cmd_undo_ch; socklen_t socklen; struct sockaddr_storage his_addr; char *arg = NULL; char *cmd; size_t len; int user_validated = 0; char *errstr = NULL; char *pgm = "amindexd"; /* in case argv[0] is not set */ char his_hostname[MAX_HOSTNAME_LENGTH]; char *cfg_opt = NULL; /* * Configure program for internationalization: * 1) Only set the message locale for now. * 2) Set textdomain for all amanda related programs to "amanda" * We don't want to be forced to support dozens of message catalogs. */ setlocale(LC_MESSAGES, "C"); textdomain("amanda"); safe_fd(DATA_FD_OFFSET, 2); safe_cd(); /* * When called via inetd, it is not uncommon to forget to put the * argv[0] value on the config line. On some systems (e.g. Solaris) * this causes argv and/or argv[0] to be NULL, so we have to be * careful getting our name. */ if (argc >= 1 && argv != NULL && argv[0] != NULL) { if((pgm = strrchr(argv[0], '/')) != NULL) { pgm++; } else { pgm = argv[0]; } } set_pname(pgm); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); dbopen(DBG_SUBDIR_SERVER); dbprintf(_("version %s\n"), version()); if(argv == NULL) { error("argv == NULL\n"); } if (! (argc >= 1 && argv[0] != NULL)) { dbprintf(_("WARNING: argv[0] not defined: check inetd.conf\n")); } debug_dup_stderr_to_debug(); /* initialize */ argc--; argv++; if(argc > 0 && strcmp(*argv, "-t") == 0) { amindexd_debug = 1; argc--; argv++; } if(argc > 0 && strcmp(*argv, "amandad") == 0) { from_amandad = 1; argc--; argv++; if(argc > 0) { amandad_auth = *argv; argc--; argv++; } } else { from_amandad = 0; safe_fd(dbfd(), 1); } if (argc > 0) { cfg_opt = *argv; argc--; argv++; } if(gethostname(local_hostname, SIZEOF(local_hostname)-1) == -1) { error(_("gethostname: %s"), strerror(errno)); /*NOTREACHED*/ } local_hostname[SIZEOF(local_hostname)-1] = '\0'; /* now trim domain off name */ s = local_hostname; ch = *s++; while(ch && ch != '.') ch = *s++; s[-1] = '\0'; if(from_amandad == 0) { if(!amindexd_debug) { /* who are we talking to? */ socklen = sizeof (his_addr); if (getpeername(0, (struct sockaddr *)&his_addr, &socklen) == -1) error(_("getpeername: %s"), strerror(errno)); /* Try a reverse (IP->hostname) resolution, and fail if it does * not work -- this is a basic security check */ if (getnameinfo((struct sockaddr *)&his_addr, SS_LEN(&his_addr), his_hostname, sizeof(his_hostname), NULL, 0, 0)) { error(_("getnameinfo(%s): hostname lookup failed"), str_sockaddr(&his_addr)); /*NOTREACHED*/ } } /* Set up the input and output FILEs */ cmdout = stdout; cmdin = stdin; } else { /* read the REQ packet */ for(; (line = agets(stdin)) != NULL; free(line)) { if(strncmp_const(line, "OPTIONS ") == 0) { g_options = parse_g_options(line+8, 1); if(!g_options->hostname) { g_options->hostname = alloc(MAX_HOSTNAME_LENGTH+1); gethostname(g_options->hostname, MAX_HOSTNAME_LENGTH); g_options->hostname[MAX_HOSTNAME_LENGTH] = '\0'; } } } amfree(line); if(amandad_auth && g_options->auth) { if(strcasecmp(amandad_auth, g_options->auth) != 0) { g_printf(_("ERROR recover program ask for auth=%s while amindexd is configured for '%s'\n"), g_options->auth, amandad_auth); error(_("amindexd: ERROR recover program ask for auth=%s while amindexd is configured for '%s'"), g_options->auth, amandad_auth); /*NOTREACHED*/ } } /* send the REP packet */ g_printf("CONNECT MESG %d\n", DATA_FD_OFFSET); g_printf("\n"); fflush(stdin); fflush(stdout); fclose(stdin); fclose(stdout); cmdout = fdopen(DATA_FD_OFFSET + 0, "a"); if (!cmdout) { error(_("amindexd: Can't fdopen(%d): %s"), DATA_FD_OFFSET + 0, strerror(errno)); /*NOTREACHED*/ } cmdin = fdopen(DATA_FD_OFFSET + 1, "r"); if (!cmdin) { error(_("amindexd: Can't fdopen(%d): %s"), DATA_FD_OFFSET + 1, strerror(errno)); /*NOTREACHED*/ } } /* clear these so we can detect when the have not been set by the client */ amfree(dump_hostname); amfree(qdisk_name); amfree(disk_name); amfree(target_date); our_features = am_init_feature_set(); their_features = am_set_default_feature_set(); if (cfg_opt != NULL && check_and_load_config(cfg_opt) != -1) { /* load the config */ return 1; } reply(220, _("%s AMANDA index server (%s) ready."), local_hostname, version()); user_validated = from_amandad; /* a real simple parser since there are only a few commands */ while (1) { /* get a line from the client */ while(1) { if((part = agets(cmdin)) == NULL) { if(errno != 0) { dbprintf(_("? read error: %s\n"), strerror(errno)); } else { dbprintf(_("? unexpected EOF\n")); } if(line) { dbprintf(_("? unprocessed input:\n")); dbprintf("-----\n"); dbprintf("? %s\n", line); dbprintf("-----\n"); } amfree(line); amfree(part); uncompress_remove = remove_files(uncompress_remove); dbclose(); return 1; /* they hung up? */ } strappend(line, part); /* Macro: line can be null */ amfree(part); if(amindexd_debug) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -