📄 mserver.c
字号:
xref_to_Uns32(&filenum, connstat->outbuf + 3); } break; case QUERYWRPOSITION: if(connstat->outbuf[7] == COMMAND_OK){ xref_to_UnsN(&wrcartnum, connstat->outbuf, 24); xref_to_Uns32(&wrfilenum, connstat->outbuf + 3); } break; case QUERYRDPOSITION: if(connstat->outbuf[7] == COMMAND_OK){ xref_to_UnsN(&rdcartnum, connstat->outbuf, 24); xref_to_Uns32(&rdfilenum, connstat->outbuf + 3); } break; case OQUERYPOSITION: if(connstat->outbuf[4] == COMMAND_OK){ cartnum = (Int32) connstat->outbuf[0]; xref_to_UnsN(&filenum, connstat->outbuf + 1, 24); } break; case OQUERYWRPOSITION: if(connstat->outbuf[4] == COMMAND_OK){ wrcartnum = (Int32) connstat->outbuf[0]; xref_to_UnsN(&wrfilenum, connstat->outbuf + 1, 24); } break; case QUERYNUMCARTS: if(connstat->outbuf[3] == COMMAND_OK) xref_to_UnsN(&numcarts, connstat->outbuf, 24); break; case QUERYCARTSET: if(connstat->outbuf[3] == COMMAND_OK) xref_to_UnsN(&cartset, connstat->outbuf, 24); break; case QUERYRDYFORSERV: i = (server_status > 0 ? server_status : 0); Uns32_to_xref(connstat->outbuf + 1, i); i = server_status & MODE_MASK; if(i == OPENED_FOR_READ || i == OPENED_READING) i = numrdclients; else if(i == OPENED_FOR_WRITE || i == OPENED_WRITING) i = numwrclients; else i = 0; Uns32_to_xref(connstat->outbuf + 5, i); for(cs = csp - idx, i = 0; *cs; cs++) if((*cs)->pending && (*cs)->pending_cmd) i++; Uns32_to_xref(connstat->outbuf + 9, i); break; case OPENFORRAWWRITE: case OPENFORRAWREAD: if( (i = connstat->outbuf[0]) )#if 1 break;#else return(PROC_ERROR(i));#endif i = (cmd == OPENFORRAWWRITE ? OPENED_FOR_WRITE : OPENED_FOR_READ); server_status = connstat->tape_status = (i | OPENED_RAW_ACCESS); raw_mode = YES; break; case NOOPERATION: case WRITETOTAPE: case SKIPFILES: case ERASETAPE: case READFROMTAPE: case CLOSETAPE: case CLOSETAPEN: case CLIENTBACKUP: case OCLIENTBACKUP: case SETBUFFEREDOP: case SETSERIALOP: case SETCHCARTONEOT: case SETERRORONEOT: case GETNUMREADVALID: case SETNUMWRITEVALID: case CLIENTIDENT: case GOODBYE: break; default: return(PROC_ERROR(EINVAL)); } return(0);}static Int32handle_prot_func( int fd, void *conn_data, Int32 idx, void *user_data, TcpMuxCallbDoneActions *ret_actions, void *tcpmux_status){ ConnStatus *connstat; Uns32 cmd; Int32 i, k, n, num; Uns32 proc_mode; AFBProtocol *op; UChar *cptr; connstat = *((ConnStatus **) conn_data); if(connstat->pending && connstat->pending_cmd) return(0); cptr = connstat->inbuf; if(connstat->pending_cmd && ! connstat->pending){ *cptr = (UChar) connstat->pending_cmd; connstat->pending_cmd = NOOPERATION /* 0 */; n = 1; } else{ n = read_forced(fd, cptr, 1); if(n < 1) return(1); } op = prot_items[*cptr]; if(!op || ((cmd = op->cmd) != *cptr && op->cmd != NOOPERATION)){ logmsg(LOG_CRIT, T_("Internal Error: Protocol not properly initialized.\n")); return(2); } switch(op->cmd){ /* special cases, to be handled explicitly */ case AUTHENTICATE: ER__(set_cryptkey_for_host(cryptfile, connstat->peername), i); i = logon_to_server(fd, fd, NULL, NULL, NULL,#ifdef HAVE_DES_ENCRYPTION AUTH_USE_DES#else 0#endif | AUTH_NOCONFIRM); return(i); break; } k = n = 0; if(op->num_fix_in > 0){ num = (op->num_fix_in == VARCOMMBUFSIZ ? connstat->commbufsiz : op->num_fix_in); n = read_forced(fd, cptr + 1, num); if(n != num) return(3); if(op->pos_num_in > 0){ xref_to_UnsN(&k, cptr + op->pos_num_in, op->size_num_in << 3); if((i = n + k + 1) > connstat->inbuf_allocated){ cptr = NEWP(UChar, i); if(!cptr) return(9); memcpy(cptr, connstat->inbuf, (n + 1) * sizeof(UChar)); free(connstat->inbuf); connstat->inbuf = cptr; connstat->inbuf_allocated = i; } i = read_forced(fd, cptr + 1 + n, k); if(i != k) return(4); } } proc_mode = handle_mserver_prot(cmd, fd, conn_data, idx, user_data, fromfd, tofd, tcpmux_status); if(proc_mode & PROC_ERROR_MASK) return(- PROC_ERRVAL(proc_mode)); if(proc_mode & PROC_DEFAULT_PROC){ i = n + k + 1; i = (write_forced(tofd, cptr, i) != i); if(i) return(- errno); } n = k = 0; cptr = connstat->outbuf; if(op->num_fix_out > 0){ num = (op->num_fix_out == VARCOMMBUFSIZ ? connstat->commbufsiz : op->num_fix_out); if(proc_mode & PROC_DEFAULT_PROC){ n = tcp_mux_long_read(tcpmux_status, fromfd, cptr, num); if(n != num) return(5); } n = num; if(op->pos_num_out > 0){ xref_to_UnsN(&k, cptr + op->pos_num_out - 1, op->size_num_out << 3); if(proc_mode & PROC_DEFAULT_PROC){ if((i = n + k + 1) > connstat->outbuf_allocated){ cptr = NEWP(UChar, i); if(!cptr) return(8); memcpy(cptr, connstat->outbuf, n * sizeof(UChar)); free(connstat->outbuf); connstat->outbuf = cptr; connstat->outbuf_allocated = i; } i = tcp_mux_long_read(tcpmux_status, fromfd, cptr + n, k); if(i != k) return(6); } } } if(proc_mode & PROC_DEFAULT_PROC){ if(op->cmd != NOOPERATION){ i = tcp_mux_long_read(tcpmux_status, fromfd, cptr + n + k, 1); /* result byte */ if(i < 1) return(7); } } if(!connstat->pending){ if(proc_mode & PROC_POST_PROC){ proc_mode = handle_mserver_prot_post(cmd, fd, conn_data, idx, user_data, fromfd, tofd, tcpmux_status); if(proc_mode & PROC_ERROR_MASK) return(- PROC_ERRVAL(proc_mode)); } if(op->cmd != NOOPERATION){ i = n + k + 1; i = (write_forced(fd, cptr, i) != i); if(i) return(- errno); } } if(server_status == NOT_OPEN){ i = handle_pending(((ConnStatus **) conn_data) - idx, fromfd, tofd, user_data, tcpmux_status); } /* pending commands never lead to connection end */ return(proc_mode & PROC_FINISH_CONN);}main(int argc, char ** argv){ UChar *cptr, **cpptr = NULL, buf[200], *portname = NULL; UChar *localestr = NULL; Int32 i, k = 0, maxconns, portnum; Uns32 tcpmux_flags; char **nargv; Flag restart = NO, autodaemonize = NO; struct stat statb; prot_items = init_prot_spec(); if(goptions(argc, (UChar **) argv, "s-1:;s:l;b:D;b:s;b:d;s:p;b:b;s:L;b:@;*", &i, &configfilename, &loggingfile, &edebug, &unsecure, &daemonize, &portname, &nobuffering, &localestr, &restart, &k, &cpptr)) /* unused arguments are passed to server */ usage(argv[0]);#ifdef ENABLE_NLS setlocale(LC_ALL, localestr ? localestr : (UChar *)""); if(localestr){ /* some implementations of gettext don't honour */ set_env("LC_ALL", localestr); /* the settings done by setlocale, */ } /* but always look into the env */ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE);#endif if(isatty(0) && !daemonize){ fprintf(stderr, T_("Warning: Not started by the inetd and not with option -d for daemonize. Assuming daemon startup is desired.\n")); daemonize = autodaemonize = YES; } free_array(cpptr, k); /* don't need memory for additional args */ signal(SIGUSR1, sig_handler); while(edebug && !daemonize); /* For debugging the caught running daemon */ portnum = 0; if(daemonize){ portnum = -1; if(portname) portnum = get_tcp_portnum(portname); if(portnum < 0){ portnum = get_tcp_portnum(DEFAULT_MSERVICE); if(portnum < 0){ logmsg(LOG_WARNING, T_("Warning: Cannot resolve service name `%s' to port number, using default port %d.\n"), portname, (int) DEFAULT_MPORT); } else{ if(portname) logmsg(LOG_WARNING, T_("Warning: Cannot resolve service name `%s' to port number, using default service `%s'.\n"), portname, DEFAULT_MSERVICE); } } } progname = find_program(argv[0]); if(!progname){ EM__(progname = strapp(DEFSERVBINDIR FN_DIRSEPSTR, "afmserver")); if(access(progname, X_OK)){ logmsg(LOG_ERR, T_("Error: Could not find program file of `%s'\n"), argv[0]); do_exit(3); } } cptr = mkabspath(progname, NULL); free(progname); progname = cptr; cptr = resolve_path__(progname, NULL); if(!cptr){ logmsg(LOG_ERR, T_("Error: Could not find program file of `%s'\n"), argv[0]); do_exit(4); } free(progname); progname = cptr; EM__(backuphome = strdup(progname)); cptr = FN_LASTDIRDELIM(backuphome); if(cptr){ *cptr = '\0'; cptr = FN_LASTDIRDELIM(backuphome); if(cptr) *cptr = '\0'; } if(!configfilename){ for(cpptr = default_configfilenames; *cpptr; cpptr++); EM__(*cpptr = strapp(backuphome, FN_DIRSEPSTR "lib" FN_DIRSEPSTR DEFSERVERCONF)); for(cpptr = default_configfilenames; *cpptr; cpptr++){ configfilename = *cpptr; if(!stat(*cpptr, &statb) && access(*cpptr, R_OK)){ while(*cpptr) cpptr++; break; } if(!stat(*cpptr, &statb)) break; } configfilename = *cpptr; } i = read_param_file(configfilename, entries, sizeof(entries) / sizeof(entries[0]), NULL, NULL); if(i){ logmsg(LOG_ERR, T_("Warning: Error reading configuration file `%s'.\n"), configfilename ? configfilename : (UChar *) T_("<none found>")); } if(vardir) if(empty_string(vardir)) ZFREE(vardir); if(vardir) massage_string(vardir);#ifndef ORIG_DEFAULTS if(!vardir) vardir = strdup(DEFSERVVARDIR); if(!libdir) libdir = strdup(DEFSERVLIBDIR); if(!confdir) confdir = strdup(DEFSERVCONFDIR); if(!bindir) bindir = strdup(DEFSERVBINDIR);#else if(!vardir) vardir = strapp(backuphome, FN_DIRSEPSTR "var"); if(!libdir) libdir = strapp(backuphome, FN_DIRSEPSTR "lib"); if(!confdir) confdir = strapp(backuphome, FN_DIRSEPSTR "etc"); if(!bindir) bindir = strapp(backuphome, FN_DIRSEPSTR "bin");#endif if(!bindir || !vardir || !libdir || !confdir) ENM__; if(cryptfile) if(empty_string(cryptfile)) cryptfile = NULL; if(cryptfile){ EEM__(repl_dirs(&cryptfile)); massage_string(cryptfile); } if(loggingfile) if(empty_string(loggingfile)) loggingfile = NULL; if(loggingfile){ massage_string(loggingfile); EEM__(repl_dirs(&loggingfile)); if(loggingfile[0] == '@'){ if(isspace(loggingfile[1]) || !loggingfile[1]) syslog_ident = strdup(PACKAGE); else syslog_ident = strword(loggingfile + 1, 0); EM__(syslog_ident); cptr = first_nospace(first_space(loggingfile)); memmove(loggingfile, cptr, strlen(cptr) + 1); if(empty_string(loggingfile)) ZFREE(loggingfile); } } /* check encryption key */ i = set_cryptkey_for_host(cryptfile, ""); if(i < 0) do_exit(11); EM__(nargv = NEWP(char *, argc + 5)); nargv[0] = progname; i = 0; if(argc <= 1 || strcmp(argv[1], "-@")){ /* 1 || * => 1 implication !! */ i = 1; EM__(nargv[1] = strdup("-@")); } if(autodaemonize) EM__(nargv[++i] = strdup("-d")); memcpy(nargv + 1 + i, argv + 1, sizeof(char *) * (argc - 1)); nargv[argc + i] = NULL; if(daemonize && ! edebug && ! restart){ i = fork_forced(); if(i < 0){ fprintf(stderr, T_("Warning: cannot fork, continuing to run in foreground.\n")); } if(i == 0){ chdir("/"); setsid(); detach_from_tty(); close(0); close(1); close(2); } if(i > 0){ exit(0); } } if(!restart){ cptr = loggingfile; if(!cptr) cptr = NULLFILE; if(access(cptr, W_OK)) cptr = NULLFILE; lfd = open(cptr, O_APPEND | O_CREAT | O_WRONLY, 0644); if(lfd < 0) lfd = 2; else{ dup2(lfd, 1); dup2(lfd, 2); } } EM__(sprog = strdup(progname)); cptr = FN_LASTDIRDELIM(sprog); if(!cptr){ logmsg(LOG_ERR, T_("Error: Could not separate path of `%s'\n"), argv[0]); do_exit(5); } *cptr = '\0'; EM__(cptr = strapp(sprog, FN_DIRSEPSTR "afserver")); free(sprog); sprog = cptr; EM__(sargv = NEWP(char *, argc + 2)); memcpy(sargv + 1, argv, argc * sizeof(char *)); sargv[argc + 1] = NULL; sargv[0] = sprog; sargv[1] = "-S"; for(i = 2; i < argc + 1; i++){ if(!strcmp(sargv[i], "-d") || !strcmp(sargv[i], "-@")){ memmove(sargv + i, sargv + i + 1, sizeof(char *) * (argc - i + 1)); i--; argc--; } else if(!strcmp(sargv[i], "-p")){ memmove(sargv + i, sargv + i + 2, sizeof(char *) * (argc - i)); i -= 1; argc -= 2; } } if(!daemonize) i = start_slave_server(); maxconns = free_fds() - 10; /* safety distance 10 */ tcpmux_flags = TCPMUX_INETD_STARTED | TCPMUX_STOP_ON_LAST_CLOSE; if(daemonize) tcpmux_flags = TCPMUX_STOP_ON_LAST_CLOSE; i = tcp_mux_service(portnum, NULL, init_conn_func, handle_prot_func, close_conn_func, maxconns, toomany_func, tcpmux_flags, NULL); if(i) logmsg(LOG_ERR, T_("Warning: Service unexpectedly terminated.\n")); buf[0] = GOODBYE; k = (write_forced(tofd, buf, 1) != 1); if(k){ logmsg(LOG_ERR, T_("Warning: Cannot send command %d (%c) to slave server.\n"), buf[0], buf[0]); i = i ? i : (k ? - errno : 0); } k = result(fromfd, NULL); if(k){ logmsg(LOG_ERR, T_("Warning: Did not get success response for command %d (%c) from slave server.\n"), buf[0], buf[0]); i = i ? i : k; } waitpid_forced(pid, &pst, 0); close(fromfd); close(tofd); if(lfd != 2) close(lfd); pst = WEXITSTATUS(pst); if(daemonize){ execv(progname, nargv); } exit(pst ? pst : i);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -