📄 sel_common.c
字号:
saved_fdset = svc_fdset; FD_ZERO(&getreq_mask); FD_SET(fd, &getreq_mask); svc_getreqset(&getreq_mask); /* it calls the rpc dispatcher */ if (fd == seln_my_tcp_socket || FD_ISSET(fd, &seln_my_open_tcps)) seln_adjust_fds(&saved_fdset); return NOTIFY_DONE;}/* * Call from service to tell us a function needs to be executed */voidseln_do_function(transport) SVCXPRT *transport;{ Seln_function_buffer buffer; register Seln_client_node *client; if (!svc_getargs(transport, xdr_seln_function, &buffer)) { svcerr_decode(transport); return; } switch (buffer.addressee_rank) { case SELN_CARET: client = (Seln_client_node *) (LINT_CAST(buffer.caret.access.client)); break; case SELN_PRIMARY: client = (Seln_client_node *) (LINT_CAST(buffer.primary.access.client)); break; case SELN_SECONDARY: client = (Seln_client_node *) (LINT_CAST(buffer.secondary.access.client)); break; case SELN_SHELF: client = (Seln_client_node *) (LINT_CAST(buffer.shelf.access.client)); break; default: svcerr_decode(transport); return; } if (seln_verify_clnt_alive(client) == 0) { /* the client is destroyed already, so just register error */ svcerr_auth(transport,AUTH_REJECTEDCRED); return; } client->ops.do_function(client->client_data, &buffer);}/* * Respond to a request from another process */voidseln_do_reply(transport) SVCXPRT *transport;{ Seln_request request; Seln_request reply; Seln_replier_data replier; if (!svc_getargs(transport, xdr_seln_request, &request)) { svcerr_decode(transport); return; } (void)seln_init_reply(&request, &reply, &replier); if (seln_verify_clnt_alive(request.addressee) == 0) { /* the client is destroyed already, so just regiester error */ svcerr_auth(transport,AUTH_REJECTEDCRED); return; } if (!svc_sendreply(transport, xdr_seln_reply, (char *)(LINT_CAST(&reply)))) { /* failure usually is refusal of requester to accept continuation */ *replier.response_pointer = (char *)SELN_REQ_END_REQUEST; ((Seln_client_node *) (LINT_CAST((request.addressee))))->ops.do_request( SELN_REQ_END_REQUEST, &replier, 0); }}Seln_resultseln_init_reply(request, reply, replier) Seln_request *request; Seln_request *reply; Seln_replier_data *replier;{ *reply = *request; reply->status = SELN_SUCCESS; reply->requester = request->requester; reply->replier = replier; replier->client_data = ((Seln_client_node *) (LINT_CAST((request->addressee))))->client_data; replier->rank = request->rank; replier->context = 0; replier->request_pointer = (char **)(LINT_CAST(request->data)); }Seln_resultseln_get_reply_buffer(buffer) Seln_request *buffer;{ Seln_client_node *client; int buf_len; char *request; char *limit; client = (Seln_client_node *) (LINT_CAST(buffer->addressee)); limit = buffer->data + SELN_BUFSIZE - 2*sizeof(Seln_attribute); buffer->replier->response_pointer = (char **)(LINT_CAST(buffer->data)); while ((request = *buffer->replier->request_pointer++) != 0) { if (buffer->status != SELN_CONTINUED) { *buffer->replier->response_pointer++ = request; } buf_len = limit - (char *) buffer->replier->response_pointer; switch (client->ops.do_request(request, buffer->replier, buf_len)) { case SELN_SUCCESS: /* go round again */ buffer->status = SELN_SUCCESS; break; case SELN_CONTINUED: /* 1 buffer filled */ buffer->buf_size = (char *) buffer->replier->response_pointer - buffer->data; *buffer->replier->response_pointer++ = 0; buffer->replier->response_pointer = (char **) (LINT_CAST(buffer->data)); buffer->replier->request_pointer -= 1; buffer->status = SELN_CONTINUED; return SELN_SUCCESS; case SELN_UNRECOGNIZED: buffer->replier->response_pointer[-1] = (char *) SELN_REQ_UNKNOWN; *buffer->replier->response_pointer++ = request; buffer->status = SELN_SUCCESS; break; case SELN_DIDNT_HAVE: buffer->replier->response_pointer[-1] = 0; buffer->status = SELN_DIDNT_HAVE; return SELN_SUCCESS; default: /* failure - quit */ buffer->replier->response_pointer[-1] = 0; buffer->status = SELN_FAILED; return SELN_FAILED; } buffer->replier->request_pointer = attr_skip_value((unsigned)request, buffer->replier->request_pointer); } (void)client->ops.do_request(SELN_REQ_END_REQUEST, buffer->replier, 0); buffer->status = SELN_SUCCESS; *buffer->replier->response_pointer++ = 0; buffer->buf_size = (char *) buffer->replier->response_pointer - buffer->data; return SELN_SUCCESS;}/* * Package-internal utilities * * Return TRUE if two sockaddr_in structs agree in all elements */intseln_equal_addrs(a, b) struct sockaddr_in *a, *b;{ return (a->sin_family == b->sin_family && a->sin_port == b->sin_port && bcmp((char *)(LINT_CAST(&a->sin_addr)), (char *)(LINT_CAST(&b->sin_addr)), sizeof(a->sin_addr)) == 0);}/* * Initialize the TCP connection (used fro requests by any holder * (includes service, for file-selections). */Seln_resultseln_get_tcp(prognum, dispatcher) int prognum; void (*dispatcher)();{ if ((seln_my_tcp_transport = svctcp_create(RPC_ANYSOCK, sizeof(Seln_request), sizeof(Seln_request))) == (SVCXPRT *) NULL) { complain("Couldn't get a TCP transport for requesters to talk to us"); return SELN_FAILED; } seln_my_tcp_socket = seln_my_tcp_transport->xp_sock; get_myaddress(&seln_my_access.tcp_address); seln_my_access.tcp_address.sin_port = htons(seln_my_tcp_transport->xp_port); if (!svc_register(seln_my_tcp_transport, prognum, SELN_VERSION, dispatcher, NO_PMAP)) { complain("Couldn't register transport for requesters to talk to us"); svc_destroy(seln_my_tcp_transport); (void)close(seln_my_tcp_socket); return SELN_FAILED; } (void) notify_set_input_func((Notify_client) seln_my_tcp_transport, seln_listener, seln_my_tcp_socket); return SELN_SUCCESS;}/* * routines & data for keeping track of the state of the function keys */ Seln_functions_state functions;voidseln_function_clear(function) register Seln_function function;{ register u_int i, j; i = (u_int)function / (sizeof(functions.data[0]) * 8); if (i < SELN_FUNCTION_WORD_COUNT) { j = (u_int)function % (sizeof(functions.data[0]) * 8); functions.data[i] &= ~(1 << j); }}voidseln_function_set(function) register Seln_function function;{ register u_int i, j; i = (u_int)function / (sizeof(functions.data[0]) * 8); if (i < SELN_FUNCTION_WORD_COUNT) { j = (u_int)function % (sizeof(functions.data[0]) * 8); functions.data[i] |= (1 << j); }}intseln_function_state(function) register Seln_function function;{ register u_int i, j; i = (u_int)function / (sizeof(functions.data[0]) * 8); if (i < SELN_FUNCTION_WORD_COUNT) { j = (u_int)function % (sizeof(functions.data[0]) * 8); return ((functions.data[i] & (1 << j)) != 0); } else { return 0; }}intseln_function_pending(){ register u_int i; for (i = 0; i < SELN_FUNCTION_WORD_COUNT; i++) { if (functions.data[i] != 0) return TRUE; } return FALSE;}voidseln_function_reset(){ register u_int i; for (i = 0; i < SELN_FUNCTION_WORD_COUNT; i++) { functions.data[i] = 0; }}Seln_functions_stateseln_functions_all(){ return functions;}/* Given client, seln_verify_clnt_alive returns 1 if the client is alive * 0 if dead. */static seln_verify_clnt_alive(client)Seln_client_node *client;{ Seln_client_node *temp; for (temp = &clients; temp != NULL; temp=temp->next){ /* first check if the client address is the same */ if (temp == client) { /* now check if the serial id number is the same. * if so, then it's the same client; otherwise, the original * client is probably dead, and a new client owns the same * vm address */ if (temp->client_num == client->client_num) { return(1); } else { return(0); } } } return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -