📄 sel_svc.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)sel_svc.c 1.1 92/07/30 SMI";#endif#endif/* * Copyright 1985, 1988, 1989 Sun Microsystems Inc. */#include <suntool/selection_impl.h>#include <sunwindow/rect.h> /* LINT_CAST definition */#include <sys/stat.h>#include <sys/file.h>#include <net/if.h>#include <sys/ioctl.h>static Seln_holder holder[SELN_RANKS];static int held_file[SELN_RANKS]; /* fds of held files */static int full_notifications, trace_acquire, trace_done, trace_hold_file, trace_inform, trace_inquire, trace_stop, trace_yield;static void seln_svc_acquire(), seln_svc_dispatch(), seln_svc_done(), seln_svc_functions_all(), seln_svc_function_one(), seln_svc_give_holder(), seln_svc_hold_file(), seln_svc_inform(), seln_svc_init_access(), seln_svc_inquire(), seln_svc_inquire_all(), seln_svc_clear_functions(), seln_svc_do_function();static Seln_result seln_svc_do_reply(), seln_svc_do_yield(), seln_send_msg();static Seln_function_buffer seln_execute_fn();static char *seln_svc_debug(), *seln_svc_notify_suppression();static Notify_func old_func;/* * Start the service */voidseln_init_service(debugging) int debugging;{ int i; for (i = 0; i < SELN_RANKS; i++) { bzero((char *)(LINT_CAST(&holder[i])), sizeof (Seln_holder)); holder[i].state = SELN_NONE; holder[i].rank = (Seln_rank) i; } if (debugging) {seln_svc_program |= SELN_SVC_TEST; } seln_svc_init_access(&seln_my_access); clients.client_num = 1; clients.ops.do_function = seln_svc_do_function; clients.ops.do_request = seln_svc_do_reply; clients.access = seln_my_access; clients.access.client = (char *)&clients; clients.client_data = (char *) &seln_my_access; seln_std_timeout.tv_sec = 0; seln_std_timeout.tv_usec = 0; return;}/* * Destroy portmap mapping */intseln_svc_unmap(){ return pmap_unset(seln_svc_program, SELN_VERSION);}/* * Stop the service */voidseln_svc_stop(){ (void) seln_svc_unmap(); (void)notify_remove_input_func((char *) seln_my_udp_transport, seln_listener, seln_my_udp_socket); svc_destroy(seln_my_udp_transport); (void)close(seln_my_udp_socket); (void)notify_remove_input_func((char *) seln_my_tcp_transport, seln_listener, seln_my_tcp_socket); svc_destroy(seln_my_tcp_transport); (void)close(seln_my_tcp_socket); (void)fprintf(stderr, "Selection service terminated normally\n");}/* * dispatch is called by rpc dispatcher, and in turn calls * the appropriate response function below; */static voidseln_svc_dispatch(request, transport) struct svc_req *request; SVCXPRT *transport;{ struct sockaddr_in *who; if(request->rq_proc == SELN_SVC_NULLPROC) { if (!svc_sendreply(transport, xdr_void, (char *)0)) { clnt_perror((CLIENT *)(LINT_CAST(transport)), "Couldn't reply to null RPC call"); } return; } who = svc_getcaller(transport); if (chklocal(ntohl(who->sin_addr)) == FALSE) { /* NOT a local call - ERROR */ svcerr_auth(transport,AUTH_REJECTEDCRED); return; } switch (request->rq_proc) { case SELN_SVC_ACQUIRE: seln_svc_acquire(transport); return; case SELN_SVC_DONE: seln_svc_done(transport); return; case SELN_SVC_HOLD_FILE: seln_svc_hold_file(transport); return; case SELN_SVC_INFORM: seln_svc_inform(transport); return; case SELN_SVC_INQUIRE: seln_svc_inquire(transport); return; case SELN_SVC_INQUIRE_ALL: seln_svc_inquire_all(transport); return; case SELN_SVC_CLEAR_FUNCTIONS: seln_svc_clear_functions(transport); return; case SELN_SVC_GET_HOLDER: seln_svc_give_holder(transport); return; case SELN_SVC_STOP: (void)svc_sendreply(transport, xdr_void, (char *)0); if (trace_stop) { (void)fprintf(stderr, "Selection services halted by remote request.\n"); } seln_svc_stop(); return; case SELN_SVC_FUNCTION_ONE: seln_svc_function_one(transport); return; case SELN_SVC_FUNCTIONS_ALL: seln_svc_functions_all(transport); return; case SELN_CLNT_DO_FUNCTION: seln_do_function(transport); return; case SELN_CLNT_REQUEST: seln_do_reply(transport); return; default: svcerr_noproc(transport); return; }}/* * Caller will become holder of a selection. */static voidseln_svc_acquire(transport) SVCXPRT *transport;{ Seln_holder input; Seln_result result; if (!svc_getargs(transport, xdr_seln_holder, &input)) { svcerr_decode(transport); (void) svc_sendreply(transport, xdr_enum, (char *)(LINT_CAST(SELN_FAILED))); return; } if (trace_acquire) { (void)fprintf(stderr, "Service entered at Acquire with holder:\n"); seln_dump_holder(stderr, &input); } if (ord(input.rank) >= ord(SELN_CARET) && ord(input.rank) <= ord(SELN_SHELF)) { if (held_file[ord(input.rank)] != 0) { (void)close(held_file[ord(input.rank)]); held_file[ord(input.rank)] = 0; } holder[ord(input.rank)] = input; result = SELN_SUCCESS; } else { result = SELN_FAILED; } (void) svc_sendreply(transport, xdr_enum, (char *)(LINT_CAST(&result))); if (trace_acquire) { (void)fprintf(stderr, "Acquire returned "); seln_dump_result(stderr, &result); (void)fprintf(stderr, "\n"); }}/* * Tell service to hold a selection stored in a file. */static voidseln_svc_hold_file(transport) SVCXPRT *transport;{ Seln_file_info input; int fd; Seln_result result; input.pathname = NULL; if (!svc_getargs(transport, xdr_seln_file_info, &input)) { svcerr_decode(transport); result = SELN_FAILED; (void) svc_sendreply(transport, xdr_enum, (char *)(LINT_CAST(&result))); return; } if (trace_hold_file) { (void)fprintf(stderr, "Service entered at Hold File with args:\n"); seln_dump_file_args(stderr, &input); } if (ord(input.rank) < ord(SELN_PRIMARY) || ord(input.rank) > ord(SELN_SHELF)) { complain("Selection service can't hold file"); (void)fprintf(stderr, "selection # %d\n", ord(input.rank)); result = SELN_FAILED; (void) svc_sendreply(transport, xdr_enum, (char *)(LINT_CAST(&result))); } if ((fd = open(input.pathname, O_RDONLY, 0)) == -1) { perror("Selection service couldn't open selection file"); (void)fprintf(stderr, "filename: \"%s\"\n", input.pathname); result = SELN_FAILED; (void) svc_sendreply(transport, xdr_enum, (char *)(LINT_CAST(&result))); return; } if (held_file[ord(input.rank)] != 0) { (void)close(held_file[ord(input.rank)]); held_file[ord(input.rank)] = 0; } else { if (holder[ord(input.rank)].state == SELN_EXISTS) { (void)seln_send_yield(input.rank, &holder[ord(input.rank)], TRUE); holder[ord(input.rank)].state = SELN_NONE; } } held_file[ord(input.rank)] = fd; holder[ord(input.rank)].state = SELN_FILE; holder[ord(input.rank)].access = clients.access; result = SELN_SUCCESS; (void) svc_sendreply(transport, xdr_enum, (char *)(LINT_CAST(&result))); if (trace_hold_file) { (void)fprintf(stderr, "Hold File returned "); seln_dump_result(stderr, &result); (void)fprintf(stderr, "\n"); }}/* * Caller is yielding control of the indicated selection */static voidseln_svc_done(transport) SVCXPRT *transport;{ Seln_holder input; Seln_result result; if (!svc_getargs(transport, xdr_seln_holder, &input)) { svcerr_decode(transport); (void) svc_sendreply(transport, xdr_enum, (char *)(LINT_CAST(SELN_FAILED))); return; } if (trace_done) { (void)fprintf(stderr, "Service entered at Done with args:\n"); seln_dump_holder(stderr, &input); } if (ord(input.rank) >= ord(SELN_CARET) && ord(input.rank) <= ord(SELN_SHELF) && seln_equal_access(&holder[ord(input.rank)].access, &input.access)) { if (holder[ord(input.rank)].state == SELN_FILE) { (void)close(held_file[ord(input.rank)]); held_file[ord(input.rank)] = 0; } /* preserve the fact that this selection was made * by resetting state, but not access */ holder[ord(input.rank)].state = SELN_NONE; result = SELN_SUCCESS; } else { result = SELN_FAILED; } (void) svc_sendreply(transport, xdr_enum, (char *)(LINT_CAST(&result))); if (trace_done) { (void)fprintf(stderr, "Done returned "); seln_dump_result(stderr, &result); (void)fprintf(stderr, "\n"); }}/* * Caller has seen a function-key transition which it believes * to be of interest to the selection manager. */static voidseln_svc_inform(transport) SVCXPRT *transport;{ Seln_inform_args input; Seln_function_buffer result; if (!svc_getargs(transport, xdr_seln_inform_args, &input)) { svcerr_decode(transport); (void) svc_sendreply(transport, xdr_enum, (char *)(LINT_CAST(SELN_FAILED))); return; } if (trace_inform) { (void)fprintf(stderr, "Service entered at Inform with args:\n"); seln_dump_inform_args(stderr, &input); } if (input.down) { /* button-down: note status */ if (!seln_function_pending()) { if (holder[ord(SELN_SECONDARY)].state == SELN_EXISTS) {#ifdef SEND_YIELD (void)seln_send_yield(SELN_SECONDARY, &holder[ord(SELN_SECONDARY)], TRUE);#endif holder[ord(SELN_SECONDARY)].state = SELN_NONE; } holder[ord(SELN_SECONDARY)].access = seln_null_holder.access; } seln_function_set(input.function); result = seln_null_function; } else { /* button-up */ seln_function_clear(input.function); if (!seln_function_pending()) {/* invoke transfer */ result = seln_execute_fn(&input); } else { result = seln_null_function; } } (void) svc_sendreply(transport, xdr_seln_function, (char *)(LINT_CAST(&result))); if (trace_inform) { (void)fprintf(stderr, "Inform returned "); seln_dump_function_buffer(stderr, &result); (void)fprintf(stderr, "\n"); }}/* * Caller wants to know how to contact the holder of the indicated selection. * A valid indication is SELN_UNSPECIFIED, which means "you figure out * whether I mean primary or secondary according to the state of the * function keys, and tell me." */static voidseln_svc_inquire(transport) SVCXPRT *transport;{ Seln_rank input; Seln_holder result; if (!svc_getargs(transport, xdr_enum, &input)) { svcerr_decode(transport); (void) svc_sendreply(transport, xdr_seln_holder, (char *)(LINT_CAST(&seln_null_holder))); return; } if (trace_inquire) { (void)fprintf(stderr, "Service entered at Inquire with rank: "); seln_dump_rank(stderr, &input); (void)fprintf(stderr, "\n"); } switch (input) { case SELN_UNSPECIFIED: if (seln_function_pending()) { input = SELN_SECONDARY; } else { input = SELN_PRIMARY; } /* FALL THROUGH */ case SELN_CARET: case SELN_PRIMARY: case SELN_SECONDARY: case SELN_SHELF: result = holder[ord(input)]; break; default: result = seln_null_holder; } (void) svc_sendreply(transport, xdr_seln_holder, (char *)(LINT_CAST(&result))); if (trace_inquire) { (void)fprintf(stderr, "Inquire returned: "); seln_dump_holder(stderr, &result); }}/* * Caller wants to know holders of all selections */static voidseln_svc_inquire_all(transport) SVCXPRT *transport;{ Seln_holders_all result; if (trace_inquire) { (void)fprintf(stderr, "Service entered at Inquire_all\n"); } bcopy((char *) &holder[ord(SELN_CARET)], (char *) &result, sizeof (Seln_holder) * (SELN_RANKS - 1)); (void) svc_sendreply(transport, xdr_seln_holders_all, (char *)(LINT_CAST(&result))); if (trace_inquire) { (void)fprintf(stderr, "Inquire_all returned:\n"); seln_dump_holder(stderr, &result.caret); seln_dump_holder(stderr, &result.primary); seln_dump_holder(stderr, &result.secondary); seln_dump_holder(stderr, &result.shelf); }}/* * Caller is telling service all function keys are up */static voidseln_svc_clear_functions(transport) SVCXPRT *transport;{ seln_function_reset(); if (holder[ord(SELN_SECONDARY)].state == SELN_EXISTS) { (void)seln_send_yield(SELN_SECONDARY, &holder[ord(SELN_SECONDARY)], TRUE); holder[ord(SELN_SECONDARY)].state = SELN_NONE; } (void) svc_sendreply(transport, xdr_void, (char *)0);}/* * Caller wants to know the state of a function key */static voidseln_svc_function_one(transport) SVCXPRT *transport;{ Seln_function input; u_int result; if (!svc_getargs(transport, xdr_enum, &input)) { svcerr_decode(transport); (void) svc_sendreply(transport, xdr_seln_holder, (char *)(LINT_CAST(&seln_null_holder))); return; } result = seln_function_state(input); (void) svc_sendreply(transport, xdr_u_int, (char *)(LINT_CAST(&result)));}/* * Caller wants to know the state of all function keys */static voidseln_svc_functions_all(transport) SVCXPRT *transport;{ Seln_functions_state result; result = seln_functions_all(); (void) svc_sendreply(transport, xdr_seln_functions_state, (char *)(LINT_CAST(&result)));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -