📄 mserver.c
字号:
return(0);}static voidtoomany_func(int fd, void * data, void * tcpmux_status){ authenticate_client(fd, fd, unsecure, VERSION_MESSAGE GREETING_MESSAGE, TOO_MANY_CLIENTS, AUTHENTICATION,#ifdef HAVE_DES_ENCRYPTION AUTH_USE_DES#else 0#endif , 0);}static Int32flush_pending_ops( ConnStatus *connstat, void *user_data, int fromfd, int tofd, void *tcpmux_status){ return(0);}static Int32handle_pending( ConnStatus **csp, int fromfd, int tofd, void *user_data, void *tcpmux_status){ ConnStatus **cs, *connstat; Int32 idx, r = 0; for(cs = csp, idx = 0; *cs; cs++, idx++){ connstat = *cs; if(connstat->pending && connstat->pending_cmd){ connstat->pending = NO; r = handle_prot_func(connstat->fd, cs, idx, user_data, NULL, tcpmux_status); break; } } return(r);}static Int32handle_mserver_prot( Uns32 command, int fd, ConnStatus **csp, Int32 idx, void *user_data, int fromfd, int tofd, void *tcpmux_status){ Int32 i, n, st = COMMAND_OK; ConnStatus *connstat, **allconns; UChar cmd, *cptr; cmd = (UChar) command; connstat = *csp; if(raw_mode && cmd != CLOSETAPE && cmd != CLOSETAPEN && cmd != GOODBYE && cmd != SETCOMMBUFSIZ) return(PROC_DEFAULT_PROC); allconns = csp - idx; connstat->outbuf[0] = COMMAND_OK; if(isspace(cmd)) cmd = NOOPERATION; switch(cmd){ case WRITETOTAPE: i = (connstat->tape_status & MODE_MASK); if(i != OPENED_FOR_WRITE && i != OPENED_WRITING){ connstat->outbuf[0] = DEVNOTOPENWR; break; } i = (server_status & MODE_MASK); if(i != OPENED_FOR_WRITE && i != OPENED_WRITING) return(PROC_DEFAULT_PROC); /* should never happen */ i = writetotape(connstat, fromfd, tofd, tcpmux_status); tapepos_valid = wrtapepos_valid = rdtapepos_valid = NO; break; case READFROMTAPE: i = (connstat->tape_status & MODE_MASK); if(i != OPENED_FOR_READ && i != OPENED_READING){ connstat->outbuf[0] = DEVNOTOPENRD; break; } i = (server_status & MODE_MASK); if(i != OPENED_FOR_READ && i != OPENED_READING) return(PROC_DEFAULT_PROC); /* should never happen */ i = readfromtape(csp, idx, fromfd, tofd, tcpmux_status); if(i) connstat->outbuf[connstat->commbufsiz] = i; tapepos_valid = NO; break; case SETCOMMBUFSIZ: xref_to_Uns32(&(connstat->commbufsiz), connstat->inbuf + 1); i = connstat->commbufsiz + 4; if(i > connstat->inbuf_allocated){ connstat->inbuf = RENEWP(connstat->inbuf, UChar, i); connstat->inbuf_allocated = i; if(!connstat->inbuf){ connstat->outbuf[0] = FATAL_ERROR; break; } } if(i > connstat->outbuf_allocated){ cptr = RENEWP(connstat->outbuf, UChar, i); connstat->outbuf_allocated = i; if(!cptr) connstat->outbuf[0] = FATAL_ERROR; else connstat->outbuf = cptr; } if(resize_tapebuf(connstat, i)){ connstat->outbuf[0] = FATAL_ERROR; break; } if(raw_mode) return(PROC_DEFAULT_PROC); break; case QUERYPOSITION: if(tapepos_valid){ UnsN_to_xref(connstat->outbuf, cartnum, 24); Uns32_to_xref(connstat->outbuf + 3, filenum); connstat->outbuf[7] = COMMAND_OK; break; } return(PROC_DEFAULT_PROC | PROC_POST_PROC); break; case QUERYWRPOSITION: if(wrtapepos_valid){ UnsN_to_xref(connstat->outbuf, wrcartnum, 24); Uns32_to_xref(connstat->outbuf + 3, wrfilenum); connstat->outbuf[7] = COMMAND_OK; break; } return(PROC_DEFAULT_PROC | PROC_POST_PROC); break; case QUERYRDPOSITION: if(rdtapepos_valid){ UnsN_to_xref(connstat->outbuf, rdcartnum, 24); Uns32_to_xref(connstat->outbuf + 3, rdfilenum); connstat->outbuf[7] = COMMAND_OK; break; } return(PROC_DEFAULT_PROC | PROC_POST_PROC); break; case OQUERYPOSITION: if(tapepos_valid){ connstat->outbuf[0] = (UChar) cartnum; UnsN_to_xref(connstat->outbuf + 1, filenum, 24); connstat->outbuf[4] = COMMAND_OK; break; } return(PROC_DEFAULT_PROC | PROC_POST_PROC); break; case OQUERYWRPOSITION: if(wrtapepos_valid){ connstat->outbuf[0] = (UChar) wrcartnum; UnsN_to_xref(connstat->outbuf + 1, wrfilenum, 24); connstat->outbuf[4] = COMMAND_OK; break; } return(PROC_DEFAULT_PROC | PROC_POST_PROC); break; case QUERYNUMCARTS: if(numcarts > 0){ UnsN_to_xref(connstat->outbuf, numcarts, 24); connstat->outbuf[4] = COMMAND_OK; break; } return(PROC_DEFAULT_PROC | PROC_POST_PROC); break; case QUERYCARTSET: case QUERYRDYFORSERV: return(PROC_DEFAULT_PROC | PROC_POST_PROC); case OPENFORWRITE: connstat->req_cart = connstat->req_filenum = 0; /* discard silently */ wrtapepos_valid = rdtapepos_valid = tapepos_valid = NO; switch(server_status){ case OPENED_FOR_WRITE: /* note: raw access is special case */ case OPENED_WRITING: if(cartset != connstat->req_cartset){ /* wrong cartset */ connstat->pending_cmd = cmd; /* -> must wait */ connstat->pending = 1; break; } i = num_conns(csp, idx); for(i--; i >= 0; i--){ if(i == idx) continue; if(! strcmp(connstat->clientid, allconns[i]->clientid)){ connstat->outbuf[0] = CLIENT_NOT_UNIQUE; break; } } if(i >= 0) break; if( (i = getpos(fromfd, tofd, tcpmux_status, QUERYWRPOSITION)) ) break; if(need_new_tapefile_for_wrclient(connstat->clientid, cartnum, filenum)) if(request_new_file(fromfd, tofd, tcpmux_status)) break; case NOT_OPEN: if( (i = getpos(fromfd, tofd, tcpmux_status, QUERYWRPOSITION)) ) break; i = check_access(fromfd, tofd, tcpmux_status, SETCARTRIDGE, wrcartnum, connstat->peername); if(i){ connstat->outbuf[0] = (UChar) i; break; } connstat->tapebuf[0] = (UChar) 0xff; /* start of header */ strcpy(connstat->tapebuf + 1, connstat->clientid); connstat->tapebufptr = connstat->headerlen; /* header is: 0xff clientid 0x00 */ if(server_status == NOT_OPEN){ tapebuf[0] = '\0'; tapebuf[1] = WRITETOTAPE; tapebufptr = 2; ER__(set_req_streamermode(connstat, fromfd, tofd, tcpmux_status), i); return(PROC_DEFAULT_PROC | PROC_POST_PROC); } connstat->tape_status = OPENED_FOR_WRITE; numwrclients++; break; default: connstat->pending_cmd = cmd; connstat->pending = 1; } break; case OPENFORREAD: switch(server_status){/* multi-read not implemented, then must change MAXINT to OPENED_FOR_READ */ case MAXINT: /* this never happens */ if(connstat->req_cart == cartnum && connstat->req_filenum == filenum){ i = num_conns(csp, idx); for(i--; i >= 0; i--){ if(i == idx) continue; if(! strcmp(connstat->clientid, allconns[i]->clientid)){ connstat->outbuf[0] = CLIENT_NOT_UNIQUE; break; } } if(i >= 0) break; connstat->tape_status = OPENED_FOR_READ; connstat->tapebufptr = 0; numrdclients++; break; } case OPENED_FOR_READ: case OPENED_READING: connstat->tapebufptr = 0; connstat->pending = 1; connstat->pending_cmd = cmd; break; case NOT_OPEN: if(! connstat->req_cart){ i = getpos(fromfd, tofd, tcpmux_status, QUERYPOSITION); if(i){ connstat->outbuf[0] = (UChar) i; break; } } i = check_access(fromfd, tofd, tcpmux_status, SETCARTRIDGE, connstat->req_cart ? connstat->req_cart : cartnum, connstat->peername); if(i){ connstat->outbuf[0] = (UChar) i; break; } i = set_pos_if_req(connstat, fromfd, tofd, tcpmux_status); ER__(set_req_streamermode(connstat, fromfd, tofd, tcpmux_status), i); return(PROC_DEFAULT_PROC | PROC_POST_PROC); break; default: connstat->pending_cmd = cmd; connstat->pending = 1; } break; case CLOSETAPE: case CLOSETAPEN: ER__(closetape(cmd, fd, csp, idx, user_data, fromfd, tofd, tcpmux_status), i); break; case OPENFORRAWWRITE: case OPENFORRAWREAD: if(server_status != NOT_OPEN){ connstat->pending = YES; connstat->pending_cmd = cmd; break; } if(! connstat->req_cart){ i = getpos(fromfd, tofd, tcpmux_status, QUERYPOSITION); if(i){ connstat->outbuf[0] = (UChar) i; break; } } i = check_access(fromfd, tofd, tcpmux_status, SETCARTRIDGE, connstat->req_cart ? connstat->req_cart : cartnum, connstat->peername); if(i){ connstat->outbuf[0] = (UChar) i; break; } ER__(set_req_streamermode(connstat, fromfd, tofd, tcpmux_status), i); ER__(set_pos_if_req(connstat, fromfd, tofd, tcpmux_status), i); ER__(set_commbufsiz(connstat->commbufsiz, fromfd, tofd, tcpmux_status), i); return(PROC_DEFAULT_PROC | PROC_POST_PROC); break; case REQUESTNEWFILE: connstat->newfilerequested = YES; break; case SETCARTSET: xref_to_UnsN(&n, connstat->inbuf + 1, 24); if( (i = check_access(fromfd, tofd, tcpmux_status, SETCARTSET, n, connstat->peername)) ){ connstat->outbuf[0] = (UChar) i; break; } connstat->req_cartset = n; switch(server_status){ case NOT_OPEN: return(PROC_POST_PROC | PROC_DEFAULT_PROC); break; /* no obstacle to set it */ default: if(connstat->req_cartset == cartset) return(0); /* cartset already correct */ connstat->pending = 1; /* device open -> must wait */ connstat->pending_cmd = cmd; } break; /* that's it. No further actions here */ case SETCARTRIDGE: case SETRAWCARTRIDGE: case OSETCARTRIDGE: i = (cmd != OSETCARTRIDGE ? 24 : 8); xref_to_UnsN(&n, connstat->inbuf + 1, i); if( (i = check_access(fromfd, tofd, tcpmux_status, SETCARTRIDGE, n, connstat->peername)) ){ connstat->outbuf[0] = (UChar) i; break; } connstat->req_cart = n; connstat->outbuf[0] = COMMAND_OK; if(cmd == SETRAWCARTRIDGE) connstat->req_cart = - connstat->req_cart; break; /* that's it. Request will be serviced on an OPEN... command */ case SETFILE: case OSETFILE: case SETRAWFILE: i = (cmd != OSETFILE ? 32 : 24); xref_to_UnsN(&(connstat->req_filenum), connstat->inbuf + 1, i); connstat->outbuf[0] = COMMAND_OK; if(cmd == SETRAWFILE) connstat->req_filenum = - connstat->req_filenum; break; /* that's it. Request will be serviced on an OPEN... command */ case CLIENTIDENT: if(!set_client_id(connstat, connstat->inbuf + 1)) return(PROC_ERROR(ENOMEM)); return(PROC_DEFAULT_PROC); /* there's nothing, that could fail */ break; case GOODBYE: st = flush_pending_ops(connstat, user_data, fromfd, tofd, tcpmux_status); connstat->outbuf[0] = (UChar) st; raw_mode = NO; return(PROC_FINISH_CONN); break; case SKIPFILES: case ERASETAPE: tapepos_valid = NO; case CLIENTBACKUP: case OCLIENTBACKUP: case GETNUMREADVALID: case SETNUMWRITEVALID: case QUERYTAPEBLOCKSIZE: case MESSAGETEXT: case REQUESTNEWCART: case QUERYWRITTENTAPES: case SERVERIDENT: case USERIDENT: case QUERYNEEDEDTAPES: case GETCURMSG: return(PROC_DEFAULT_PROC); case NOOPERATION: break; case SETBUFFEREDOP: connstat->req_streamermode |= BUFFERED_OPERATION; break; case SETSERIALOP: connstat->req_streamermode &= (~BUFFERED_OPERATION); break; case SETCHCARTONEOT: connstat->req_streamermode |= CHANGE_CART_ON_EOT; break; case SETERRORONEOT: connstat->req_streamermode &= (~CHANGE_CART_ON_EOT); break; default: return(PROC_DEFAULT_PROC); } return(0);}static Int32handle_mserver_prot_post( Uns32 cmd, int fd, ConnStatus **csp, Int32 idx, void *user_data, int fromfd, int tofd, void *tcpmux_status){ ConnStatus *connstat, **cs; Int32 i; connstat = *csp; if(isspace(cmd)) cmd = NOOPERATION; switch(cmd){ case OPENFORWRITE: if(connstat->outbuf[0] == COMMAND_OK){ server_status = connstat->tape_status = OPENED_FOR_WRITE; numwrclients++; } break; case OPENFORREAD: if(connstat->outbuf[0] == COMMAND_OK){ server_status = connstat->tape_status = OPENED_FOR_READ; numrdclients++; reading_in_sync = NO; connstat->tapebufptr = 0; tapebufptr = 0; } break; case SETCARTSET: if(connstat->outbuf[0] == COMMAND_OK) cartset = connstat->req_cartset; break; case SETCARTRIDGE: case SETRAWCARTRIDGE: case OSETCARTRIDGE: if(connstat->outbuf[0] == COMMAND_OK) getpos(fromfd, tofd, tcpmux_status, QUERYPOSITION); break; case SETFILE: case SETRAWFILE: case OSETFILE: if(connstat->outbuf[0] == COMMAND_OK) getpos(fromfd, tofd, tcpmux_status, QUERYPOSITION); break; case QUERYPOSITION: if(connstat->outbuf[7] == COMMAND_OK){ xref_to_UnsN(&cartnum, connstat->outbuf, 24);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -