⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mserver.c

📁 一套客户/服务器模式的备份系统代码,跨平台,支持linux,AIX, IRIX, FreeBSD, Digital Unix (OSF1), Solaris and HP-UX.
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************** Start of $RCSfile: mserver.c,v $  ****************** $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/mserver.c,v $* $Id: mserver.c,v 1.5 2005/01/15 08:56:22 alb Exp alb $* $Date: 2005/01/15 08:56:22 $* $Author: alb $********* description *********************************************************************************************************************/#include <conf.h>#include <version.h>  static char * fileversion = "$RCSfile: mserver.c,v $ $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/mserver.c,v $ $Id: mserver.c,v 1.5 2005/01/15 08:56:22 alb Exp alb $ " PACKAGE " " VERSION_STRING;#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <stdarg.h>#include <sys/types.h>#include <signal.h>#include <fcntl.h>#ifdef  HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#include <sys/socket.h>#include <netinet/in.h>#include <syslog.h>#include <x_types.h>#include <netutils.h>#include <genutils.h>#include <mvals.h>#include <fileutil.h>#include "cryptkey.h"#include "prot.h"#include "backup.h"#include "server.h"#define	MPX_CHUNKSIZE	1000#define	ER__(cmd, lerrfl)	{ if( (lerrfl = cmd) ) return(lerrfl); }#define	EM__(nmem)	{ nomemfatal(nmem); }#define	EEM__(st)	{ if(st) nomemfatal(NULL); }#define	ENM__		nomemfatal(NULL)typedef	struct __conn_stat__ {  Int32		status;  Int32		tape_status;  UChar		*inbuf;  UChar		*outbuf;  Int32		commbufsiz;  UChar		*tapebuf;  Int32		tapebufsiz;  Int32		tapebufptr;  Int32		headerlen;  Uns32		inbuf_allocated;  Uns32		outbuf_allocated;  UChar		*peername;  UChar		*clientid;  struct sockaddr	*peeraddr;  int		fd;  Int32		req_cartset;  Int32		req_cart;  Int32		req_filenum;  Uns32		pending_cmd;  Flag		pending;  Flag		newfilerequested;  Uns8		req_streamermode;} ConnStatus;#define	CONNSTAT_UNINITIALIZED	0#define	CONNSTAT_WAIT_AUTH	1#define	CONNSTAT_AUTHENTICATED	2#define	CONNSTAT_CONNECTED	3#define	PROC_ERROR_MASK		(0xff << 16)#define	PROC_ERROR(num)		((num << 16) & PROC_ERROR_MASK)#define	PROC_ERRVAL(val)	((val & PROC_ERROR_MASK) >> 16)#define	PROC_DEFAULT_PROC	(1 << 24)#define	PROC_POST_PROC		(PROC_DEFAULT_PROC << 1)#define	PROC_FINISH_CONN	(PROC_DEFAULT_PROC << 2)#define	PROC_PROC_MASK		(PROC_DEFAULT_PROC | PROC_POST_PROC)Int32		server_status = NOT_OPEN;ConnStatus	*connections = NULL;AFBProtocol	**prot_items;UChar		*backuphome = NULL;UChar		*default_configfilenames[] = {	\				DEFAULT_SERVER_CONFIGFILES, NULL, NULL };UChar		*configfilename = NULL;UChar		*loggingfile = NULL;UChar		*syslog_ident = NULL;UChar		*cryptfile = NULL;Flag		edebug = NO;Flag		unsecure = NO;Flag		daemonize = NO;Flag		nobuffering = NO;UChar		*progname = NULL;char		**sargv;char		*sprog;Int32		cartset = 1;Int32		cartnum = 0;Int32		filenum = 0;Int32		wrcartnum = 0;Int32		wrfilenum = 0;Int32		rdcartnum = 0;Int32		rdfilenum = 0;Int32		numcarts = 0;Int32		numwrclients = 0;Int32		numrdclients = 0;Flag		tapepos_valid = NO;Flag		wrtapepos_valid = NO;Flag		rdtapepos_valid = NO;Flag		reading_in_sync = NO;Flag		raw_mode = NO;UChar		*tapebuf = NULL;Int32		tapebuf_allocated = 0;Int32		commbufsiz = DEFCOMMBUFSIZ;Int32		tapebufptr = 0;Int32		tapeblocksize = 0;Flag		newfilerequested = NO;int		tofd = -1;int		fromfd = -1;int		pid = -1;int		pst;int		lfd = 2;Flag		interrupted = NO;UChar		*vardir = NULL;UChar		*bindir = NULL;UChar		*libdir = NULL;UChar		*confdir = NULL;ReplSpec	replacements[] = {	{ "%B",	NULL, &bindir },	{ "%L",	NULL, &libdir },	{ "%V",	NULL, &vardir },	{ "%C", NULL, &confdir },	};typedef struct __ClientPos__ {  UChar		*clientname;  Int32		cartnum;  Int32		filenum;} ClientPos;ClientPos	*prev_client_conns = NULL;ParamFileEntry	entries[] = {	{ &cryptfile, NULL,	(UChar *) "^[ \t]*\\([Ee]n\\)?[Cc]rypti?o?n?[-_ \t]*[Kk]ey[-_ \t]*[Ff]iles?:?[ \t]*",		TypeUCharPTR	},	{ &loggingfile, NULL,	(UChar *) "^[ \t]*[Ll]ogg?i?n?g?[-_ \t]*[Ff]ile:?[ \t]*",		TypeUCharPTR	},	{ &vardir, NULL,	(UChar *) "^[ \t]*[Vv][Aa][Rr][-_ \t]*[Dd]ire?c?t?o?r?y?:?[ \t]*",		TypeUCharPTR	},};#define	repl_dirs(string)	repl_substrings((string), replacements,	\		sizeof(replacements) / sizeof(replacements[0]))static Int32	handle_prot_func(int, void *, Int32, void *,					TcpMuxCallbDoneActions *, void *);static voiddo_exit(int est){  if(pid > 0){    kill(pid, SIGTERM);    if(tofd >= 0)	close(tofd);    if(fromfd >= 0)	close(fromfd);    waitpid(pid, &pst, 0);    est = WEXITSTATUS(pst);  }  exit(est);}static voidlogmsg(int prio, UChar * fmt, ...){  va_list	args;  FILE		*fp, *lfp = NULL;  va_start(args, fmt);  if(loggingfile)    lfp = fopen(loggingfile, "a");  fp = (lfp ? lfp : stderr);  fprintf(fp, "%s, ", actimestr());  vfprintf(fp, fmt, args);  fflush(fp);  if(lfp)    fclose(lfp);  if(syslog_ident)    gvsyslog(syslog_ident, LOG_CONS | LOG_PID, LOG_DAEMON, prio, fmt, args);  va_end(args);}static voidfatal(UChar * msg){  logmsg(LOG_CRIT, "%s", msg);  do_exit(1);}static voidnomemfatal(void * ptr){  if(!ptr)    fatal("Error: Cannot allocate memory.\n");}#define	request_new_file(fromfd, tofd, tcpmux_status)	\		simple_command(REQUESTNEWFILE, fromfd, tofd, tcpmux_status)static Flagneed_new_tapefile_for_wrclient(UChar * name, Int32 cartn, Int32 filen){  Flag		needit = NO;  Int32		i;  Int32		idx;	/* uninitialized OK */  if(!prev_client_conns){    EM__(prev_client_conns = NEWP(ClientPos, 2));    idx = 0;    SETZERO(prev_client_conns[1]);  }  else{    for(i = 0; prev_client_conns[i].clientname; i++){	if(!strcmp(prev_client_conns[i].clientname, name)){	  needit = YES;	  idx = i;	}    }    if(!needit){	EM__(prev_client_conns = RENEWP(prev_client_conns, ClientPos, i + 2));	idx = i;	SETZERO(prev_client_conns[idx + 1]);    }  }  if(needit){    if(filen != prev_client_conns[idx].filenum			|| cartn != prev_client_conns[idx].cartnum)	needit = NO;  }  else{    EM__(prev_client_conns[idx].clientname = strdup(name));  }  prev_client_conns[idx].cartnum = cartn;  prev_client_conns[idx].filenum = filen;  return(needit);}static voidfree_prev_wrclient_list(){  ClientPos	*poss;  if(prev_client_conns){    for(poss = prev_client_conns; poss->clientname; poss++)	free(poss->clientname);    ZFREE(prev_client_conns);  }}static voidsig_handler(int sig){  signal(sig, sig_handler);  switch(sig){    case SIGPIPE:	logmsg(LOG_ERR, T_("Error: Connection to client lost. Exiting.\n"));	do_exit(1);    case SIGUSR1:	edebug = 0;	break;  }}static Int8check_interrupted(ConnStatus * connstat){  int		i;  Int32		len[2];  nodeaddr	peeraddr;  if(interrupted){    return(1);  }  len[0] = len[1] = 0;		/* I use 32 Bit int for len. See server.c for a *comment* */  *((int *) &(len[0])) = sizeof(peeraddr);  i = getpeername(connstat->fd, (struct sockaddr *)(&peeraddr), (int *) &(len[0]));  if(i && errno == ENOTCONN){	logmsg(LOG_ERR, T_("Error: Client disconnected. Exiting.\n"));	kill(getpid(), SIGPIPE);  }  return(interrupted);}static voidusage(UChar * prnam){  logmsg(LOG_ERR, T_("Usage: %s [ -sbD ] [ <configuration-file> ] [ -l <logging-file> ] [ -L <locale> ]\n"), prnam);  do_exit(1);}static Int32send_status(int fd, UChar statusc)	/* utility */{  return(write_forced(fd, &statusc, 1) != 1 ? - errno : 0);}#define	send_cmd	send_statusstatic Int32result(int fromfd, void *tcpmux_status){  Int32		i;  UChar		c;  i = (tcp_mux_long_read(tcpmux_status, fromfd, &c, 1) != 1);  return(i ? - errno : (Int32) c);  }static Int32simple_command(UChar cmd, int fromfd, int tofd, void * tcpmux_status){  Int32		i;  ER__(send_cmd(tofd, cmd), i);  return(result(fromfd, tcpmux_status));}static Int32num_conns(void * cs, Int32 index){  ConnStatus	**csp;  csp = (ConnStatus **) cs;  csp -= index;  for(index = 0; *csp; csp++, index++);  return(index);}static Int32check_access(  int		fromfd,  int		tofd,  void		*tcpmux_status,  UChar		cmd,  Int32		n,  UChar		*client){  UChar	buf[264];  Int32	r;  n = ABS(n);			/* raw cartridge numbers (< 0) are allowed */  buf[0] = CHECKACCESS;  buf[1] = cmd;  Uns32_to_xref(buf + 1 + 1, n);  strncpy(buf + 1 + 1 + 4, client, 256);  if(write_forced(tofd, buf, 1 + 1 + 4 + 256) != 1 + 1 + 4 + 256)    return(- errno);  if( (r = result(fromfd, tcpmux_status)) )    logmsg(LOG_CRIT, T_("Warning: Client %s tried to access cartridge %s%d, denied.\n"),			client, cmd == SETCARTSET ? T_("set ") : "", (int) n);  return(r);}static Int32set_cryptkey_for_host(UChar * cryptfiles, UChar * hostname){  Int32		i;  UChar		*curkey;  curkey = NULL;  if(cryptfiles){    i = get_entry_by_host(cryptfiles, hostname, &curkey);    if(i < 0){	logmsg(LOG_ERR,		T_("Error: No authentication key file configured for %s.\n"),				hostname);	return(AUTHENTICATION);    }  }  if(curkey){    if( (i = check_cryptfile(curkey)) ){	logmsg((i > 0 ? LOG_WARNING : LOG_ERR),			T_("%s on encryption key file `%s': %s.\n"),			(i > 0 ? T_("Warning") : T_("Error")),			curkey, check_cryptfile_msg(i));	if(i < 0)	  return(AUTHENTICATION);	logmsg(LOG_WARNING, T_("Warning: Ignoring file `%s', using compiled-in key.\n"),					curkey);	ZFREE(curkey);    }  }  set_cryptkey(curkey, ACCESSKEYSTRING,#ifdef	HAVE_DES_ENCRYPTION		YES#else		NO#endif		);  ZFREE(curkey);  return(0);}static UChar *set_client_id(ConnStatus * connstat, UChar * idstr){  ZFREE(connstat->clientid);  connstat->clientid = strdup(idstr);  connstat->headerlen = 1 + strlen(idstr) + 1;  return(connstat->clientid);}static Int32resize_tapebuf(ConnStatus * connstat, Int32 newsize){  UChar		*cbuf;  if(newsize <= connstat->tapebufsiz)    return(0);  cbuf = RENEWP(connstat->tapebuf, UChar, newsize);  if(!cbuf)    return(FATAL_ERROR);  connstat->tapebuf = cbuf;  connstat->tapebufsiz = newsize;  return(0);}static Int32flush_to_server(  int		fromfd,  int		tofd,  void		*tcpmux_status){  Int32		i, e;  if(tapebufptr <= 2)    return(0);  memset(tapebuf + tapebufptr, 0, commbufsiz + 2 - tapebufptr);  i = commbufsiz + 1;  ER__((write_forced(tofd, tapebuf + 1, i) != i), e);	/* send stuff */  return(result(fromfd, tcpmux_status));}static Int32write_to_server(  UChar		*buf,  Int32		num,  int		fromfd,  int		tofd,  void		*tcpmux_status){  Int32		n, i, e;  while(num > 0){    n = commbufsiz + 2 - tapebufptr;    if(n > num){	memcpy(tapebuf + tapebufptr, buf, num);	tapebufptr += num;	return(0);    }    memcpy(tapebuf + tapebufptr, buf, n);    if(newfilerequested){	ER__(request_new_file(fromfd, tofd, NULL), i);	newfilerequested = NO;    }    i = commbufsiz + 1;				/* send stuff */    ER__((tcp_mux_long_write(tcpmux_status, tofd, tapebuf + 1, i) != i), e);    ER__(result(fromfd, tcpmux_status), e);		/* get result */    num -= n;    buf += n;    tapebufptr = 2;  }  return(0);}static Int32writetotape(  ConnStatus	*connstat,  int		fromfd,  int		tofd,  void		*tcpmux_status){  Int32		i, n, tocb, inbufptr;  tocb = connstat->commbufsiz;		/* how much do we have to copy */  inbufptr = 0;					/* where we are currently */  do{    n = MPX_CHUNKSIZE - connstat->tapebufptr;	/* space in send buffer */    if(tocb < n){				/* rest fits into buffer */	memcpy(connstat->tapebuf + connstat->tapebufptr,	/* copy it */				connstat->inbuf + 1 + inbufptr, tocb);	connstat->tapebufptr += tocb;	/* update pointer, that's it */	return(0);    }    if(n > 0)					/* fill up send buffer */	memcpy(connstat->tapebuf + connstat->tapebufptr,				connstat->inbuf + 1 + inbufptr, n);		/* + 1 cause inbuf contains command "W" in 1st position */    if(connstat->newfilerequested){	newfilerequested = YES;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -