📄 amidxtaped.c
字号:
/* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1998 University of Maryland at College Park * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of U.M. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. U.M. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Authors: the Amanda Development Team. Its members are listed in a * file named AUTHORS, in the root directory of this distribution. *//* $Id: amidxtaped.c,v 1.73 2006/07/25 19:06:46 martinea Exp $ * * This daemon extracts a dump image off a tape for amrecover and * returns it over the network. It basically, reads a number of * arguments from stdin (it is invoked via inet), one per line, * preceeded by the number of them, and forms them into an argv * structure, then execs amrestore */#include "amanda.h"#include "version.h"#include "clock.h"#include "restore.h"#include "cmdline.h"#include "changer.h"#include "conffile.h"#include "logfile.h"#include "amfeatures.h"#include "stream.h"#include "amandad.h"#define amidxtaped_debug(i,x) do { \ if ((i) <= debug_amidxtaped) { \ dbprintf(x); \ } \} while (0)#define TIMEOUT 30static char *pgm = "amidxtaped"; /* in case argv[0] is not set */extern char *rst_conf_logfile;static int get_lock = 0;static int from_amandad;static am_feature_t *our_features = NULL;static am_feature_t *their_features = NULL;static g_option_t *g_options = NULL;static int ctlfdin, ctlfdout, datafdout;static char *amandad_auth = NULL;static FILE *cmdin, *cmdout;static char *get_client_line(FILE *in);static void check_security_buffer(char *);static char *get_client_line_fd(int);/* exit routine */static pid_t parent_pid = -1;static void cleanup(void);int main(int argc, char **argv);/* get a line from client - line terminated by \r\n */static char *get_client_line(FILE *in){ static char *line = NULL; char *part = NULL; size_t len; amfree(line); while(1) { if((part = agets(in)) == NULL) { if(errno != 0) { dbprintf(_("read error: %s\n"), strerror(errno)); } else { dbprintf(_("EOF reached\n")); } if(line) { dbprintf(_("s: unprocessed input:\n")); dbprintf("-----\n"); dbprintf("%s\n", line); dbprintf("-----\n"); } amfree(line); amfree(part); dbclose(); exit(1); /*NOTREACHED*/ } if(line) { strappend(line, part); amfree(part); } else { line = part; part = NULL; } if((len = strlen(line)) > 0 && line[len-1] == '\r') { line[len-1] = '\0'; /* zap the '\r' */ break; } /* * Hmmm. We got a "line" from agets(), which means it saw * a '\n' (or EOF, etc), but there was not a '\r' before it. * Put a '\n' back in the buffer and loop for more. */ strappend(line, "\n"); } dbprintf("> %s\n", line); return line;}/* get a line from client - line terminated by \r\n */static char *get_client_line_fd( int fd){ static char *line = NULL; static size_t line_size = 0; char *s = line; size_t len = 0; char c; ssize_t nb; if(line == NULL) { /* first time only, allocate initial buffer */ s = line = alloc(128); line_size = 128; } while(1) { nb = read(fd, &c, 1); if (nb <= 0) { /* EOF or error */ if ((nb <= 0) && ((errno == EINTR) || (errno == EAGAIN))) { /* Keep looping if failure is temporary */ continue; } dbprintf(_("%s: Control pipe read error - %s\n"), pgm, strerror(errno)); break; } if(len >= line_size-1) { /* increase buffer size */ line_size *= 2; line = realloc(line, line_size); if (line == NULL) { error(_("Memory reallocation failure")); /*NOTREACHED*/ } s = &line[len]; } *s = c; if(c == '\n') { if(len > 0 && *(s-1) == '\r') { /* remove '\r' */ s--; len--; } *s = '\0'; return line; } s++; len++; } line[len] = '\0'; return line;}voidcheck_security_buffer( char * buffer){ socklen_t i; struct sockaddr_in addr; char *s, *fp, ch; char *errstr = NULL; dbprintf(_("check_security_buffer(buffer='%s')\n"), buffer); i = SIZEOF(addr); if (getpeername(0, (struct sockaddr *)&addr, &i) == -1) { error(_("getpeername: %s"), strerror(errno)); /*NOTREACHED*/ } if ((addr.sin_family != (sa_family_t)AF_INET) || (ntohs(addr.sin_port) == 20)) { error(_("connection rejected from %s family %d port %d"), inet_ntoa(addr.sin_addr), addr.sin_family, htons(addr.sin_port)); /*NOTREACHED*/ } /* do the security thing */ s = buffer; ch = *s++; skip_whitespace(s, ch); if (ch == '\0') { error(_("cannot parse SECURITY line")); /*NOTREACHED*/ } fp = s-1; skip_non_whitespace(s, ch); s[-1] = '\0'; if (strcmp(fp, "SECURITY") != 0) { error(_("cannot parse SECURITY line")); /*NOTREACHED*/ } skip_whitespace(s, ch); if (!check_security((struct sockaddr_storage *)&addr, s-1, 0, &errstr)) { error(_("security check failed: %s"), errstr); /*NOTREACHED*/ }}intmain( int argc, char ** argv){ char *buf = NULL; int data_sock = -1; in_port_t data_port = (in_port_t)-1; socklen_t socklen; struct sockaddr_in addr; GSList *dumpspecs; tapelist_t *tapes = NULL; char *their_feature_string = NULL; rst_flags_t *rst_flags; int use_changer = 0; int re_end; char *re_config = NULL; char *conf_tapetype; tapetype_t *tape; char *line; char *tapedev; dumpspec_t *ds; /* * 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, 4); safe_cd(); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); rst_flags = new_rst_flags(); rst_flags->mask_splits = 1; /* for older clients */ rst_flags->amidxtaped = 1; our_features = am_init_feature_set(); their_features = am_set_default_feature_set(); /* * 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); if(argv && argv[1] && strcmp(argv[1], "amandad") == 0) { from_amandad = 1; if(argv[2]) amandad_auth = argv[2]; } else { from_amandad = 0; safe_fd(-1, 0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -