📄 client.c
字号:
/****************** Start of $RCSfile: client.c,v $ ****************** $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/client.c,v $* $Id: client.c,v 1.6 2005/01/15 08:49:21 alb Exp alb $* $Date: 2005/01/15 08:49:21 $* $Author: alb $********* description *********************************************************************************************************************/#include <conf.h>#include <version.h> static char * fileversion = "$RCSfile: client.c,v $ $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/client.c,v $ $Id: client.c,v 1.6 2005/01/15 08:49:21 alb Exp alb $ " PACKAGE " " VERSION_STRING;#include <stdio.h>#include <string.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <signal.h>#include <sys/types.h>#include <sys/utsname.h>#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifdef HAVE_SYS_RESOURCE_H#include <sys/resource.h>#endif#ifdef HAVE_SYS_PARAM_H#include <sys/param.h>#endif#ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#ifdef HAVE_NETINET_IN_SYSTM_H#include <netinet/in_systm.h>#endif#ifdef HAVE_NETINET_IP_H#include <netinet/ip.h>#endif#include <x_types.h>#include <x_errno.h>#include <genutils.h>#include <sysutils.h>#include <netutils.h>#include <fileutil.h>#include <packer.h>#include "server.h"#include "cryptkey.h"#include "backup.h"#define GETOUT { goto getout; }#define CLEANUP { goto cleanup; }#define CLEANUPR(ret) { r = ret; goto cleanup; }#define SERIAL_OPERATION 1#define QUEUED_OPERATION 2#define MAX_QUEUE_MEMORY 10485760 /* 10 MB */typedef struct _queueentry_ { UChar *inmem; UChar *outmem; Uns32 num_in; Uns32 num_out; Uns16 instruction; Uns16 processed; Uns32 req_queue_cbs;} QueueEntry;#define NOT_PROCESSED 0#define PROCESSED_OK RESERVED_ERROR_CODEFlag noqueued = NO;UChar comm_mode = QUEUED_OPERATION;Uns32 queuelen = 512;QueueEntry *queue_entries = NULL;Uns32 max_queuelen = 0;UChar *outbufmem = NULL;UChar *inbufmem = NULL;Uns32 allocated_outmem = 0;Uns32 allocated_inmem = 0;Uns32 queueent_done_idx = 0;Uns32 queueent_requested_idx = 0;Uns32 queueent_processed_idx = 0;Uns32 queue_insert_idx = 0;Uns32 cur_num_entries_in_queue = 0;Int32 queue_commbufsiz = 0;Flag std_io = NO;#define QUEUEDOP (queue_entries != NULL)#define num_entries_in_queue (cur_num_entries_in_queue = \ (queue_insert_idx >= queueent_done_idx ? \ queue_insert_idx - queueent_done_idx : \ queuelen - queueent_done_idx + queue_insert_idx))UChar *servername = NULL;short unsigned portnum = DEFAULT_PORT;UChar *cryptfile = NULL;Int32 commbufsiz = DEFCOMMBUFSIZ;Int32 max_outarglen;Int32 max_inresultlen;UChar scbuf[MAXCOMMBUFSIZ + 8];UChar *cbuf = &(scbuf[1]);Int32 cbufptr = 0; /* pointer into send/receive-buffer */Int32 bytes_transferred = 0;Int32 bytes_wr_unkn_pos = 0;#define reset_data_buffer { cbufptr = 0; }#define reset_tape_io { endofrec = 0; }int commfd = -1;int commfd_socktype = -1;struct timeval null_timeval;Int32 cart = 0;Int32 filenum = 0;Int32 wrcart = 0;Int32 wrfilenum = 0;Int32 rdcart = 0;Int32 rdfilenum = 0;Int32 cartset = 0;Int32 numcarts = 0;Int32 tapeblocksize = 0;UChar *infoheader = NULL;UChar *identitystr = NULL;Flag filenum_valid = NO;Flag wrfilenum_valid = NO;Flag rdfilenum_valid = NO;Int32 endofrec = 0;AarParams params;Flag bu_create = NO;Flag bu_extract = NO;Flag bu_contents = NO;Flag bu_verify = NO;Flag bu_index = NO;Flag bu_ready = NO;Flag bu_duptape = NO;UChar *bu_duptapeargs = NULL;Flag bu_junction = NO;Flag bu_msg_itv = 0;Flag allfiles = NO;Uns8 verbose = 0;Flag c_f_verbose = NO;Flag l_verbose = NO;Flag o_verbose = NO;Flag u_verbose = NO;Flag bu_request = NO;Flag bu_svrmsg = NO;UChar *servermsg = NULL;Flag req_newfile = NO;Flag req_newcart = NO;UChar *clientprog = NULL;UChar *serverversion = NULL;Flag server_can_sendtbufsiz = NO;Flag server_can_setcbufsiz = NO;Flag server_can_sendid = NO;Flag server_can_sendutapes = NO;Flag server_can_userid = NO;Flag server_can_auth = NO;Flag server_can_sendrdpos = NO;Flag server_can_sendmsgs = NO;UChar **filelist = NULL;char *toextractfilename = NULL;char *errorlogfile = NULL;char *savefile = NULL;Flag save_stdio = NO;char username[128] = "";Int32 num_errors = 0;UChar long_errmsgs = 0;UChar **gargv;void (*cleanup_proc)(void *) = NULL;void *cleanup_arg = NULL;#define MAX_NUM_ERRORS 20#define ESTIM_PROT_OVERHEAD 50#define MAX_NUM_WRITE_WITHOUT_POS_UPDATE 5000000struct fault_msgs fault_messages[] = FAULT_MESSAGES;Int32 delete_command_queue();Int32 queued_read(int, UChar *, Int32);Int32 queued_write(int, UChar *, Int32);Int32 post_process_entry(Int32);Int32 post_process_rest_of_queue(Int32);Int32 append_to_queue(Uns16, UChar *, Uns32, UChar *, Uns32);Int32 simple_command(UChar);Int32 setnumbytesvalid(Int32);Int32 getnumbytesvalid(Int32 *);Int32 getcartandfile(AarParams *);Int32 getwrcartandfile(AarParams *);Int32 getrdcartandfile(AarParams *);Int32 send_commbufsiz(Int32);Int32 duplicate_tape(UChar *, AarParams *);Int32 copytaperemote(UChar *, Int32, Int32, UChar *);Int32 copytapelocally(Int32);#define set_server_serial simple_command(SETSERIALOP)#define set_server_buffering simple_command(SETBUFFEREDOP)#define set_server_erroneot simple_command(SETERRORONEOT)#define set_server_chcartoneot simple_command(SETCHCARTONEOT)#define getserverstate(ptr, w) getbufferwithcmd(ptr, 512, QUERYRDYFORSERV, w)#define getserverid(ptr, w) getbufferwithcmd(ptr, 256, SERVERIDENT, w)#define ER__(cmd, lerrfl) { if( (lerrfl = cmd) ) return(lerrfl); }UChar * fetch_tape_contents(AarParams * params);UChar * put_tape_contents(AarParams * params);static voiderrmsg(UChar * msg, ...){ va_list args; va_start(args, msg); if(long_errmsgs) fprintf(stderr, "%s, ", actimestr()); vfprintf(stderr, msg, args); va_end(args); if(msg[strlen(msg) - 1] != '\n') fprintf(stderr, ".\n"); fflush(stderr);}static Int32E__(Int32 e){ if(e) errmsg(T_("%sError: %s"), (e > 0 ? T_("Server ") : ""), (e > 0 ? fault_string(e) : (UChar *) strerror(-e))); return(e);}#define OK__(func) (! E__(func))voidsignal_handler(int s){ if(long_errmsgs || s == SIGTERM || s == SIGINT) fprintf(stderr, T_("%s got signal %d, exiting.\n"), FN_BASENAME(gargv[0]), s); if(cleanup_proc) (*cleanup_proc)(cleanup_arg); exit(128 | s);}Int32send_cmd(UChar cmd) /* utility */{ if(write_forced(commfd, &cmd, 1) != 1) return(errno ? - errno : EOF); bytes_transferred += ESTIM_PROT_OVERHEAD + 1; return(0);}UCharresult(){ UChar c; Int32 i; if(savefile) return(0); i = (read_forced(commfd, &c, 1) != 1); bytes_transferred += ESTIM_PROT_OVERHEAD + 1; if(i){ return(errno ? - errno : EOF); } if(! c) return(0); return(c);}Int32 /* This function assumes, that we can do it. It is sure, that no data */change_queue_bufsiz(Int32 newsize) /* will be lost */{ Int32 new_queuelen, new_max_outarglen, new_max_inresultlen; Int32 i, n, upper_part_size, prev_qcbs; UChar *new_outbufmem, *new_inbufmem, *scptr, *dcptr, *mcptr; QueueEntry *new_queue_entries; if(! queue_entries) /* no queue currently present */ return(0); if(newsize == queue_commbufsiz) return(0); new_max_outarglen = new_max_inresultlen = newsize + 4; new_queuelen = allocated_outmem / new_max_outarglen; if(new_queuelen > max_queuelen){ queue_entries = RENEWP(queue_entries, QueueEntry, new_queuelen); if(!queue_entries) return(FATAL_ERROR); memset(queue_entries + max_queuelen, 0, (new_queuelen - max_queuelen) * sizeof(QueueEntry)); max_queuelen = new_queuelen; } if(newsize > queue_commbufsiz){ /* if there's size-change-requests */ for(i = queueent_done_idx; i != queue_insert_idx; i = (i + 1) % queuelen){ n = queue_entries[i].req_queue_cbs; /* in queue to size smaller */ if(n > 0 && n < newsize){ /* then current request */ queue_entries[i].req_queue_cbs = newsize; /* change them */ } } } if(new_queuelen < 2){ /* it's rediculuous, if we have that few */ new_queuelen = 2; /* memory, nonetheless we catch this case */ allocated_outmem = new_max_outarglen * new_queuelen; allocated_inmem = new_max_inresultlen * new_queuelen; new_outbufmem = RENEWP(outbufmem, UChar, allocated_outmem); new_inbufmem = RENEWP(inbufmem, UChar, allocated_inmem); new_queue_entries = RENEWP(queue_entries, QueueEntry, new_queuelen); if(!new_outbufmem || !new_inbufmem || !new_queue_entries){ ZFREE(new_outbufmem); ZFREE(new_inbufmem); ZFREE(new_queue_entries); return(delete_command_queue()); } outbufmem = new_outbufmem; inbufmem = new_inbufmem; queue_entries = new_queue_entries; } do{ prev_qcbs = queue_commbufsiz; if(newsize > queue_commbufsiz){ /* wait for space */ i = post_process_rest_of_queue(new_queuelen - 1); if(i) /* to move stuff around and to pack */ return(i); /* the queue entry data wider */ } }while(prev_qcbs != queue_commbufsiz); if(newsize > queue_commbufsiz){ if(queue_insert_idx > queueent_done_idx){ n = queue_insert_idx - queueent_done_idx; if(queueent_done_idx > 0){ memmove(outbufmem, outbufmem + max_outarglen * queueent_done_idx, max_outarglen * n); memmove(inbufmem, inbufmem + max_inresultlen * queueent_done_idx, max_inresultlen * n); memmove(queue_entries, queue_entries + queueent_done_idx, sizeof(queue_entries[0]) * n); } n--; scptr = outbufmem + max_outarglen * n; dcptr = outbufmem + new_max_outarglen * n; for(i = n; i > 0; i--){ memmove(dcptr, scptr, max_outarglen); scptr -= max_outarglen; dcptr -= new_max_outarglen; } scptr = inbufmem + max_inresultlen * n; dcptr = inbufmem + new_max_inresultlen * n; for(i = n; i > 0; i--){ memmove(dcptr, scptr, max_inresultlen); scptr -= max_inresultlen; dcptr -= new_max_inresultlen; } queueent_requested_idx -= queueent_done_idx; queueent_processed_idx -= queueent_done_idx; queue_insert_idx -= queueent_done_idx; queueent_done_idx = 0; } if(queue_insert_idx < queueent_done_idx){ n = queuelen - new_queuelen; i = queuelen - queueent_done_idx; if(i > 0){ i *= max_outarglen; scptr = outbufmem + allocated_outmem - i; memmove(scptr, outbufmem + max_outarglen * queueent_done_idx, i); dcptr = outbufmem + (queueent_done_idx - n) * new_max_outarglen; for(i = queueent_done_idx; i < queuelen; i++){ memmove(dcptr, scptr, max_outarglen); scptr += max_outarglen; dcptr += new_max_outarglen; } i = (queuelen - queueent_done_idx) * max_inresultlen; scptr = inbufmem + allocated_inmem - i; memmove(scptr, inbufmem + max_inresultlen * queueent_done_idx, i); dcptr = inbufmem + (queueent_done_idx - n) * new_max_inresultlen; for(i = queueent_done_idx; i < queuelen; i++){ memmove(dcptr, scptr, max_inresultlen); scptr += max_inresultlen; dcptr += new_max_inresultlen; } } if(queue_insert_idx > 0){ scptr = outbufmem + max_outarglen * (queue_insert_idx - 1); dcptr = outbufmem + new_max_outarglen * (queue_insert_idx - 1); for(i = queue_insert_idx - 1; i > 0; i--){ memmove(dcptr, scptr, max_outarglen); scptr -= max_outarglen; dcptr -= new_max_outarglen; } scptr = inbufmem + max_inresultlen * (queue_insert_idx - 1); dcptr = inbufmem + new_max_inresultlen * (queue_insert_idx - 1); for(i = queue_insert_idx - 1; i > 0; i--){ memmove(dcptr, scptr, max_inresultlen); scptr -= max_inresultlen; dcptr -= new_max_inresultlen; } } memmove(queue_entries + queueent_done_idx - n, queue_entries + queueent_done_idx, sizeof(queue_entries[0]) * (queuelen - queueent_done_idx)); if(queueent_requested_idx >= queueent_done_idx) queueent_requested_idx -= n; if(queueent_processed_idx >= queueent_done_idx) queueent_processed_idx -= n; queueent_done_idx -= n; } } if(newsize < queue_commbufsiz){ if(queue_insert_idx > queueent_done_idx){ scptr = outbufmem + max_outarglen * queueent_done_idx; dcptr = outbufmem + new_max_outarglen * queueent_done_idx; for(i = queueent_done_idx; i < queue_insert_idx; i++){ memmove(dcptr, scptr, new_max_outarglen); scptr += max_outarglen; dcptr += new_max_outarglen; } scptr = inbufmem + max_inresultlen * queueent_done_idx; dcptr = inbufmem + new_max_inresultlen * queueent_done_idx; for(i = queueent_done_idx; i < queue_insert_idx; i++){ memmove(dcptr, scptr, new_max_inresultlen); scptr += max_inresultlen; dcptr += new_max_inresultlen; } } if(queue_insert_idx < queueent_done_idx){ n = new_queuelen - queuelen; if(queue_insert_idx > 0){ scptr = outbufmem + max_outarglen; dcptr = outbufmem + new_max_outarglen; for(i = 1; i < queue_insert_idx; i++){ memmove(dcptr, scptr, new_max_outarglen); scptr += max_outarglen; dcptr += new_max_outarglen; } scptr = inbufmem + max_inresultlen; dcptr = inbufmem + new_max_inresultlen; for(i = 1; i < queue_insert_idx; i++){ memmove(dcptr, scptr, new_max_inresultlen); scptr += max_inresultlen; dcptr += new_max_inresultlen; } } upper_part_size = queuelen - queueent_done_idx; if(upper_part_size > 0){ scptr = dcptr = mcptr = outbufmem + queueent_done_idx * max_outarglen; scptr += max_outarglen; dcptr += new_max_outarglen; for(i = 1; i < upper_part_size; i++){ memmove(dcptr, scptr, new_max_outarglen); scptr += max_outarglen; dcptr += new_max_outarglen; } i = upper_part_size * new_max_outarglen; dcptr = outbufmem + new_queuelen * new_max_outarglen - i; memmove(dcptr, mcptr, i); scptr = dcptr = mcptr = inbufmem + queueent_done_idx * max_inresultlen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -