[171] | 1 | /* |
---|
| 2 | * |
---|
[1939] | 3 | * Copyright (C) 1988, 1989 by the Massachusetts Institute of Technology |
---|
| 4 | * Developed by the MIT Student Information Processing Board (SIPB). |
---|
| 5 | * For copying information, see the file mit-copyright.h in this release. |
---|
| 6 | * |
---|
| 7 | */ |
---|
| 8 | /* |
---|
| 9 | * |
---|
[171] | 10 | * rpproc.c -- Procedures to implement a simple (perhaps brain-asleep) RPC |
---|
| 11 | * protocol over a TCP connection. |
---|
| 12 | * This file handles the server's side of the connection. |
---|
| 13 | * |
---|
| 14 | */ |
---|
| 15 | |
---|
[357] | 16 | /* |
---|
| 17 | * |
---|
[22658] | 18 | * $Id: rpproc.c,v 1.23 2007-08-09 20:41:33 amb Exp $ |
---|
[357] | 19 | * |
---|
| 20 | */ |
---|
| 21 | |
---|
| 22 | |
---|
[23920] | 23 | #ifdef NOKERBEROS |
---|
| 24 | #undef HAVE_KRB4 |
---|
| 25 | #undef HAVE_KRB5 |
---|
| 26 | #endif /* NOKERBEROS */ |
---|
| 27 | |
---|
[171] | 28 | #ifdef INETD |
---|
| 29 | #define ASSOC 1 |
---|
| 30 | #endif |
---|
| 31 | |
---|
| 32 | #ifdef SUBPROC |
---|
| 33 | #define ASSOC 1 |
---|
| 34 | #endif |
---|
| 35 | |
---|
| 36 | /* Includes */ |
---|
| 37 | |
---|
[357] | 38 | #include <sys/ioctl.h> |
---|
[12439] | 39 | #if HAVE_FCNTL_H |
---|
[357] | 40 | #include <fcntl.h> |
---|
[12439] | 41 | #endif |
---|
[171] | 42 | #include <sys/types.h> |
---|
| 43 | #include <sys/socket.h> |
---|
| 44 | #include <stdio.h> |
---|
[22404] | 45 | #include <stdlib.h> |
---|
[171] | 46 | #include <netinet/in.h> |
---|
| 47 | #include <sys/stat.h> |
---|
| 48 | #include <netdb.h> |
---|
| 49 | #include <errno.h> |
---|
| 50 | #include <pwd.h> |
---|
[1721] | 51 | #include <string.h> |
---|
[23807] | 52 | #ifdef HAVE_KRB4 |
---|
[171] | 53 | #include <krb.h> |
---|
| 54 | #endif |
---|
[23807] | 55 | #ifdef HAVE_KRB5 |
---|
[22658] | 56 | #include <krb5.h> |
---|
| 57 | #endif |
---|
[1721] | 58 | #include <discuss/tfile.h> |
---|
| 59 | #include "rpc.h" |
---|
| 60 | #include <discuss/types.h> |
---|
| 61 | #include "config.h" |
---|
[171] | 62 | |
---|
| 63 | #define SUCCESS 1 |
---|
| 64 | #define ERROR -1 |
---|
| 65 | #define min(a, b) (a < b ? a : b) |
---|
| 66 | |
---|
[23922] | 67 | /* When both krb4 and krb5 are available, the server will try to |
---|
| 68 | * authenticate clients with krb5 and then fall back to krb4. To |
---|
| 69 | * avoid writing entirely separate code for the case where krb4 is |
---|
| 70 | * not available, we fake some of the constants and data structures. |
---|
| 71 | */ |
---|
| 72 | #ifndef HAVE_KRB4 |
---|
| 73 | #define ANAME_SZ 40 |
---|
| 74 | #define REALM_SZ 40 |
---|
| 75 | #define INST_SZ 40 |
---|
| 76 | #define MAX_KTXT_LEN 1250 |
---|
| 77 | #define MAX_K_NAME_SZ (ANAME_SZ + INST_SZ + REALM_SZ + 2) |
---|
| 78 | struct ktext { |
---|
| 79 | int length; |
---|
| 80 | unsigned char dat[MAX_KTXT_LEN]; |
---|
| 81 | unsigned long mbz; |
---|
| 82 | }; |
---|
| 83 | typedef struct ktext KTEXT_ST; |
---|
| 84 | struct partial_auth_dat { /* Just enough of the struct for our purposes */ |
---|
| 85 | char pname[ANAME_SZ]; |
---|
| 86 | char pinst[INST_SZ]; |
---|
| 87 | char prealm[REALM_SZ]; |
---|
| 88 | }; |
---|
| 89 | typedef struct partial_auth_dat AUTH_DAT; |
---|
| 90 | #endif /* HAVE_KRB4 */ |
---|
| 91 | |
---|
[171] | 92 | /* global */ |
---|
[23922] | 93 | #if defined(HAVE_KRB4) || defined(HAVE_KRB5) |
---|
[10115] | 94 | char rpc_caller[MAX_K_NAME_SZ + 1]; |
---|
| 95 | #else |
---|
[171] | 96 | char rpc_caller[50]; |
---|
[23922] | 97 | #endif /* HAVE_KRB4 || HAVE_KRB5 */ |
---|
[1728] | 98 | static long hostaddr; |
---|
[171] | 99 | |
---|
| 100 | extern int numprocs; |
---|
[1509] | 101 | extern struct proc_table procs []; |
---|
[23922] | 102 | #if defined(HAVE_KRB4) || defined(HAVE_KRB5) |
---|
[1728] | 103 | static char serv_name[20]; |
---|
[23922] | 104 | #endif /* HAVE_KRB4 || HAVE_KRB5 */ |
---|
[171] | 105 | short recvshort(); |
---|
| 106 | int rpc_err; |
---|
| 107 | extern tfile net_tfile (); |
---|
| 108 | |
---|
| 109 | /* Static variables */ |
---|
| 110 | |
---|
| 111 | /* connections & socket info */ |
---|
| 112 | static USPStream *us = NULL; |
---|
| 113 | |
---|
| 114 | /* |
---|
| 115 | * |
---|
| 116 | * init_rpc () -- Initialize the RPC mechanism |
---|
| 117 | * |
---|
| 118 | */ |
---|
| 119 | init_rpc (service,code) |
---|
[1509] | 120 | char *service; |
---|
| 121 | int *code; |
---|
[171] | 122 | { |
---|
| 123 | #ifdef INETD |
---|
[1509] | 124 | int d; |
---|
[171] | 125 | #endif |
---|
[1509] | 126 | int snew; /* socket we're reading from */ |
---|
| 127 | |
---|
[171] | 128 | #ifdef SUBPROC |
---|
[1509] | 129 | int uid; |
---|
| 130 | struct passwd *pwent; |
---|
[171] | 131 | #endif |
---|
[1509] | 132 | |
---|
[171] | 133 | #ifndef ASSOC |
---|
[1509] | 134 | struct protoent *pe; |
---|
| 135 | struct servent *se; |
---|
| 136 | struct sockaddr_in sai; |
---|
| 137 | int sock_len = sizeof (sai); |
---|
| 138 | int s; |
---|
[171] | 139 | #endif |
---|
[1509] | 140 | |
---|
[23922] | 141 | #if defined(HAVE_KRB4) || defined(HAVE_KRB5) |
---|
[1509] | 142 | int fromlen,i; |
---|
| 143 | struct sockaddr_in from; |
---|
| 144 | char hostname[50]; |
---|
| 145 | struct hostent *hp; |
---|
| 146 | USPCardinal bt; |
---|
[23922] | 147 | #endif /* HAVE_KRB4 || HAVE_KRB5 */ |
---|
[171] | 148 | |
---|
[23271] | 149 | #if defined(__APPLE__) && defined(__MACH__) |
---|
| 150 | add_error_table(&et_rpc_error_table); |
---|
| 151 | #else |
---|
[22864] | 152 | initialize_rpc_error_table(); |
---|
[23271] | 153 | #endif |
---|
[1509] | 154 | |
---|
[171] | 155 | #ifdef INETD |
---|
[1509] | 156 | d = open ("/dev/null", 2); |
---|
| 157 | dup2(d, 1); |
---|
| 158 | dup2(d, 2); |
---|
| 159 | close(d); |
---|
| 160 | if (geteuid() == 0) |
---|
| 161 | panic ("Can't run as root."); /* just in case setuid bit off */ |
---|
[171] | 162 | #endif |
---|
[1509] | 163 | |
---|
[171] | 164 | #ifdef ASSOC |
---|
[1509] | 165 | /* safety check -- 0 better be a socket, not a pipe or file */ |
---|
| 166 | { |
---|
| 167 | if (isatty (0)) { |
---|
| 168 | *code = RPC_NOT_SUBPROC; |
---|
| 169 | return; |
---|
| 170 | } |
---|
| 171 | } |
---|
[171] | 172 | |
---|
[357] | 173 | #ifdef SUBPROC |
---|
[1509] | 174 | { |
---|
| 175 | int s; |
---|
| 176 | for (s = 1; s < 10; s++) |
---|
| 177 | (void) close (s); |
---|
| 178 | } |
---|
| 179 | { |
---|
| 180 | int fd; |
---|
| 181 | fd = open("/dev/null", 2); |
---|
| 182 | if (fd != 1) { |
---|
| 183 | (void) dup2 (fd, 1); |
---|
| 184 | (void) close (fd); |
---|
| 185 | } |
---|
| 186 | (void) dup2(1, 2); |
---|
| 187 | } |
---|
| 188 | { |
---|
[3078] | 189 | setpgrp(0, getpid()); /* So we don't get tty signals */ |
---|
[1509] | 190 | } |
---|
[357] | 191 | #endif |
---|
[1509] | 192 | |
---|
| 193 | snew = 0; |
---|
| 194 | us = USP_associate (snew); |
---|
[171] | 195 | #else |
---|
[1509] | 196 | /* to be added */ |
---|
| 197 | setprotoent(0); /* get protocol information */ |
---|
| 198 | pe = getprotobyname("tcp"); |
---|
| 199 | setservent(0); /* get service information */ |
---|
| 200 | |
---|
[22713] | 201 | se = getservbyname(SERVICE_NAME, "tcp"); |
---|
[1509] | 202 | sai.sin_addr.s_addr = INADDR_ANY; |
---|
[22713] | 203 | sai.sin_port = (se) ? se->s_port : htons(DISCUSS_FALLBACK_PORT); |
---|
| 204 | /* set up socket */ |
---|
[1509] | 205 | if((s = socket(AF_INET, SOCK_STREAM, pe->p_proto)) < 0) { |
---|
| 206 | *code = errno; |
---|
| 207 | return; |
---|
| 208 | } |
---|
[12439] | 209 | if(bind(s, (struct sockaddr *)&sai, sizeof(sai))) { /* bind service name */ |
---|
[1509] | 210 | *code = errno; |
---|
| 211 | return; |
---|
| 212 | } |
---|
| 213 | listen(s, SOMAXCONN); /* listen for connection */ |
---|
[12439] | 214 | if((snew = accept(s, (struct sockaddr *)&sai, &sock_len)) < 0) { |
---|
| 215 | /* accept connection */ |
---|
[1509] | 216 | *code = errno; |
---|
| 217 | return; |
---|
| 218 | } |
---|
| 219 | |
---|
| 220 | us = USP_associate (snew); |
---|
| 221 | if (us == NULL) { |
---|
| 222 | *code = errno; |
---|
| 223 | return; |
---|
| 224 | } |
---|
[171] | 225 | #endif |
---|
[1509] | 226 | |
---|
| 227 | strcpy (rpc_caller, "???"); /* safety drop */ |
---|
| 228 | |
---|
[171] | 229 | #ifdef SUBPROC |
---|
[1509] | 230 | uid = getuid (); |
---|
| 231 | pwent = getpwuid(uid); |
---|
| 232 | if (pwent != 0) { |
---|
| 233 | strcpy (rpc_caller, pwent -> pw_name); |
---|
| 234 | } |
---|
[171] | 235 | #endif |
---|
[1509] | 236 | strcat (rpc_caller, "@"); |
---|
| 237 | strcat (rpc_caller, REALM); |
---|
| 238 | |
---|
[23922] | 239 | #if defined(HAVE_KRB4) || defined(HAVE_KRB5) |
---|
[1728] | 240 | |
---|
| 241 | strcpy(serv_name, service); |
---|
[1509] | 242 | fromlen = sizeof (from); |
---|
[12439] | 243 | if (getpeername (snew, (struct sockaddr *)&from, &fromlen) < 0) { |
---|
[1509] | 244 | *code = errno; |
---|
| 245 | return; |
---|
| 246 | } |
---|
| 247 | if (fromlen == 0) { /* no len, UNIX domain = me */ |
---|
| 248 | gethostname(hostname, sizeof(hostname)); |
---|
| 249 | hp = gethostbyname(hostname); |
---|
[8855] | 250 | memcpy(&hostaddr, hp -> h_addr, 4); |
---|
[1509] | 251 | } else { |
---|
[8855] | 252 | memcpy(&hostaddr, &from.sin_addr, 4); |
---|
[1509] | 253 | } |
---|
[7186] | 254 | |
---|
[1509] | 255 | |
---|
[1728] | 256 | if ((USP_rcv_blk(us, &bt) != SUCCESS) || (bt != KRB_TICKET && |
---|
| 257 | bt != KRB_TICKET2)) { |
---|
[1509] | 258 | *code = RPC_PROTOCOL; |
---|
| 259 | return; |
---|
| 260 | } |
---|
| 261 | |
---|
[1728] | 262 | handle_kerberos(bt,serv_name,hostaddr); |
---|
[23922] | 263 | #endif /* HAVE_KRB4 || HAVE_KRB5 */ |
---|
[1728] | 264 | *code = 0; |
---|
| 265 | return; |
---|
| 266 | } |
---|
| 267 | |
---|
[23922] | 268 | #if defined(HAVE_KRB4) || defined(HAVE_KRB5) |
---|
[1728] | 269 | handle_kerberos(bt,service,haddr) |
---|
| 270 | USPCardinal bt; |
---|
| 271 | char *service; |
---|
| 272 | long haddr; |
---|
| 273 | { |
---|
| 274 | int i,result; |
---|
| 275 | char hostname[50]; |
---|
| 276 | char filename[50]; |
---|
| 277 | char instance[INST_SZ]; |
---|
| 278 | AUTH_DAT kdata; |
---|
| 279 | KTEXT_ST ticket; |
---|
| 280 | |
---|
[23807] | 281 | #ifdef HAVE_KRB5 |
---|
[22658] | 282 | char *envvar; |
---|
| 283 | krb5_context context; |
---|
| 284 | krb5_auth_context auth_context = NULL; |
---|
| 285 | krb5_data packet; |
---|
| 286 | krb5_principal sprinc; |
---|
| 287 | krb5_keytab keytab = NULL; |
---|
| 288 | krb5_ticket *processed_ticket = NULL; |
---|
[23807] | 289 | #endif /* HAVE_KRB5 */ |
---|
[22658] | 290 | |
---|
[1728] | 291 | strcpy (rpc_caller, "???@"); /* safety drop */ |
---|
| 292 | strcat (rpc_caller, REALM); |
---|
| 293 | |
---|
[1509] | 294 | /* read authenticator off net */ |
---|
| 295 | ticket.length = recvshort(); |
---|
| 296 | if ((ticket.length<=0) || (ticket.length>MAX_KTXT_LEN)) { |
---|
[1728] | 297 | result = RPC_PROTOCOL; |
---|
[1509] | 298 | goto punt_kerberos; |
---|
| 299 | } |
---|
| 300 | for (i=0; i<ticket.length; i++) { |
---|
| 301 | ticket.dat[i] = recvshort(); |
---|
| 302 | } |
---|
[23807] | 303 | #ifdef HAVE_KRB5 |
---|
[22658] | 304 | packet.length = ticket.length; |
---|
| 305 | packet.data = (krb5_pointer) ticket.dat; |
---|
[1509] | 306 | |
---|
[11388] | 307 | envvar = malloc(strlen(service) + 50); |
---|
| 308 | if (envvar) { |
---|
| 309 | sprintf(envvar, "KRB5_KTNAME=/var/spool/%s/krb5.keytab", service); |
---|
| 310 | putenv(envvar); |
---|
| 311 | } |
---|
[23807] | 312 | #endif /* HAVE_KRB5 */ |
---|
[1509] | 313 | /* make filename from service */ |
---|
[11295] | 314 | strcpy (filename, "/var/spool/"); |
---|
[1509] | 315 | strcat (filename, service); |
---|
| 316 | strcat (filename, "/srvtab"); |
---|
[22658] | 317 | |
---|
| 318 | strcpy(instance, "*"); |
---|
| 319 | |
---|
[23807] | 320 | #ifdef HAVE_KRB5 |
---|
[22658] | 321 | result = krb5_init_context(&context); |
---|
| 322 | if (result) { |
---|
| 323 | com_err(service, result, "while initializing krb5"); |
---|
| 324 | goto punt_kerberos; |
---|
[1509] | 325 | } |
---|
[22658] | 326 | result = krb5_sname_to_principal(context, NULL, service, KRB5_NT_SRV_HST, |
---|
| 327 | &sprinc); |
---|
| 328 | if (result) { |
---|
| 329 | com_err(service, result, "while generating srv name %s", service); |
---|
[1509] | 330 | goto punt_kerberos; |
---|
| 331 | } |
---|
[22658] | 332 | result = krb5_rd_req(context, &auth_context, &packet, sprinc, keytab, |
---|
| 333 | NULL, &processed_ticket); |
---|
| 334 | if (result == 0) { /* It's a valid krb5 request */ |
---|
| 335 | result = krb5_524_conv_principal(context, |
---|
| 336 | processed_ticket->enc_part2->client, |
---|
| 337 | kdata.pname, kdata.pinst, |
---|
| 338 | kdata.prealm); |
---|
| 339 | if (result) { |
---|
| 340 | com_err(service, result, "while converting principal to krb4"); |
---|
| 341 | goto punt_kerberos; |
---|
| 342 | } |
---|
| 343 | } |
---|
| 344 | else { /* Let's try krb4 */ |
---|
| 345 | /* First, log the krb5 error. */ |
---|
| 346 | com_err(service, result, "while reading request"); |
---|
[23807] | 347 | #endif /* HAVE_KRB5 */ |
---|
[23922] | 348 | #ifdef HAVE_KRB4 |
---|
[22658] | 349 | result = krb_rd_req (&ticket, service, instance, haddr, &kdata, |
---|
| 350 | filename); |
---|
| 351 | if (result) { |
---|
[22864] | 352 | result += ERROR_TABLE_BASE_krb; |
---|
[22658] | 353 | goto punt_kerberos; |
---|
| 354 | } |
---|
[23922] | 355 | #endif /* HAVE_KRB4 */ |
---|
[23807] | 356 | #ifdef HAVE_KRB5 |
---|
[22658] | 357 | } |
---|
[23807] | 358 | #endif /* HAVE_KRB5 */ |
---|
[22658] | 359 | |
---|
| 360 | strcpy(rpc_caller, kdata.pname); |
---|
| 361 | if (kdata.pinst[0] != '\0') { |
---|
| 362 | strcat(rpc_caller, "."); |
---|
| 363 | strcat(rpc_caller, kdata.pinst); |
---|
| 364 | } |
---|
| 365 | strcat(rpc_caller, "@"); |
---|
| 366 | strcat(rpc_caller, kdata.prealm); |
---|
| 367 | |
---|
[171] | 368 | punt_kerberos: |
---|
[1509] | 369 | USP_flush_block(us); |
---|
[1728] | 370 | if (bt == KRB_TICKET2) { |
---|
| 371 | USP_begin_block(us,TICKET_REPLY); |
---|
| 372 | USP_put_long_integer(us, i); |
---|
| 373 | USP_end_block(us); |
---|
| 374 | } |
---|
[171] | 375 | } |
---|
[23922] | 376 | #endif /* HAVE_KRB4 || HAVE_KRB5 */ |
---|
[171] | 377 | |
---|
| 378 | /* |
---|
| 379 | * |
---|
| 380 | * recvit () -- Routine to accept an RPC call. |
---|
| 381 | * |
---|
| 382 | */ |
---|
| 383 | recvit (code) |
---|
[1509] | 384 | int *code; |
---|
[171] | 385 | { |
---|
[1509] | 386 | USPCardinal bt; |
---|
| 387 | int procno; |
---|
[1721] | 388 | |
---|
[1509] | 389 | if (USP_rcv_blk(us, &bt) != SUCCESS) { |
---|
[23149] | 390 | if (errno == ECONNRESET) { /* he went away, so do we */ |
---|
[1509] | 391 | *code = errno; |
---|
| 392 | } |
---|
| 393 | *code = errno; |
---|
| 394 | return; |
---|
| 395 | } |
---|
[1721] | 396 | |
---|
[23922] | 397 | #if defined(HAVE_KRB4) || defined(HAVE_KRB5) |
---|
[1728] | 398 | if (bt == KRB_TICKET || bt == KRB_TICKET2) { |
---|
| 399 | handle_kerberos(bt, serv_name, hostaddr); |
---|
| 400 | *code = 0; |
---|
| 401 | return; |
---|
| 402 | } |
---|
[23922] | 403 | #endif /* HAVE_KRB4 || HAVE_KRB5 */ |
---|
[1728] | 404 | |
---|
[1509] | 405 | procno = bt - PROC_BASE; |
---|
[1721] | 406 | |
---|
[1509] | 407 | if (procno == 0) { |
---|
| 408 | *code = RPC_PROTOCOL; |
---|
| 409 | return; |
---|
| 410 | } |
---|
| 411 | if (procno > numprocs) { |
---|
| 412 | USP_flush_block(us); |
---|
| 413 | senddunno(); |
---|
| 414 | *code = 0; |
---|
| 415 | return; |
---|
| 416 | } |
---|
[1721] | 417 | |
---|
[1509] | 418 | rpc_err = 0; |
---|
| 419 | dispatch (procno); |
---|
| 420 | *code = rpc_err; |
---|
| 421 | return; |
---|
[171] | 422 | } |
---|
| 423 | |
---|
| 424 | int recvint () |
---|
| 425 | { |
---|
[1509] | 426 | USPLong_integer li; |
---|
| 427 | |
---|
| 428 | if (USP_get_long_integer(us, &li) != SUCCESS) { |
---|
| 429 | rpc_err = errno; |
---|
| 430 | return(0); |
---|
| 431 | } |
---|
| 432 | |
---|
| 433 | return (li); |
---|
[171] | 434 | } |
---|
| 435 | short recvshort () |
---|
| 436 | { |
---|
[1509] | 437 | USPInteger li; |
---|
| 438 | |
---|
| 439 | if (USP_get_integer(us, &li) != SUCCESS) { |
---|
| 440 | rpc_err = errno; |
---|
| 441 | return(0); |
---|
| 442 | } |
---|
| 443 | |
---|
| 444 | return (li); |
---|
[171] | 445 | } |
---|
| 446 | |
---|
| 447 | /* |
---|
| 448 | * |
---|
| 449 | * recvstr () -- Receive a string from an RPC call |
---|
| 450 | * |
---|
| 451 | */ |
---|
| 452 | char *recvstr () |
---|
| 453 | { |
---|
[1509] | 454 | USPString str; |
---|
| 455 | |
---|
| 456 | if (USP_get_string(us, &str) != SUCCESS) { |
---|
| 457 | rpc_err = errno; |
---|
| 458 | return(""); |
---|
| 459 | } |
---|
| 460 | |
---|
| 461 | return (str); |
---|
[171] | 462 | } |
---|
| 463 | |
---|
| 464 | /* |
---|
| 465 | * |
---|
| 466 | * recvbool () -- Receive a boolean in an RPC call. |
---|
| 467 | * |
---|
| 468 | */ |
---|
| 469 | bool recvbool() |
---|
| 470 | { |
---|
[1509] | 471 | USPBoolean flag; |
---|
| 472 | |
---|
| 473 | if (USP_get_boolean(us, &flag) != SUCCESS) { |
---|
| 474 | rpc_err = errno; |
---|
| 475 | return(0); |
---|
| 476 | } |
---|
| 477 | |
---|
| 478 | return ((bool)flag); |
---|
[171] | 479 | } |
---|
| 480 | |
---|
| 481 | /* |
---|
| 482 | * |
---|
| 483 | * recvfile() -- Receive a file in an RPC call. |
---|
| 484 | * |
---|
| 485 | */ |
---|
| 486 | tfile recvfile () |
---|
| 487 | { |
---|
[1509] | 488 | USPLong_integer tfs; |
---|
| 489 | tfile tf; |
---|
| 490 | |
---|
| 491 | if (USP_get_long_integer(us, &tfs) != SUCCESS) { |
---|
| 492 | rpc_err = errno; |
---|
| 493 | return(0); |
---|
| 494 | } |
---|
| 495 | |
---|
| 496 | tf = net_tfile (tfs,us); |
---|
| 497 | |
---|
| 498 | return (tf); |
---|
[171] | 499 | } |
---|
| 500 | |
---|
| 501 | /* |
---|
| 502 | * |
---|
| 503 | * startreply() -- Get ready to send reply of an RPC call. |
---|
| 504 | * |
---|
| 505 | */ |
---|
| 506 | startreply() |
---|
| 507 | { |
---|
[1509] | 508 | USP_begin_block(us,REPLY_TYPE); |
---|
| 509 | |
---|
| 510 | return; |
---|
[171] | 511 | } |
---|
| 512 | |
---|
| 513 | /* |
---|
| 514 | * |
---|
| 515 | * sendint(i) -- Send an integer in an RPC return. |
---|
| 516 | * |
---|
| 517 | */ |
---|
| 518 | sendint(i) |
---|
[1509] | 519 | int i; |
---|
[171] | 520 | { |
---|
[1509] | 521 | if (USP_put_long_integer(us, i) != SUCCESS) { |
---|
[22864] | 522 | rpc_err = errno + ERROR_TABLE_BASE_rpc; |
---|
[1509] | 523 | } |
---|
[171] | 524 | } |
---|
| 525 | |
---|
| 526 | /* |
---|
| 527 | * |
---|
| 528 | * sendstr(i) -- Send a string in an RPC return. |
---|
| 529 | * |
---|
| 530 | */ |
---|
| 531 | sendstr(str) |
---|
[1509] | 532 | char *str; |
---|
[171] | 533 | { |
---|
[15187] | 534 | if (str == NULL) |
---|
[15171] | 535 | str = ""; |
---|
[1509] | 536 | if (USP_put_string(us, str) != SUCCESS) { |
---|
[22864] | 537 | rpc_err = ERROR_TABLE_BASE_rpc + errno; |
---|
[1509] | 538 | return; |
---|
| 539 | } |
---|
[171] | 540 | } |
---|
| 541 | |
---|
| 542 | /* |
---|
| 543 | * |
---|
| 544 | * sendbool(b) -- Send a boolean in an RPC return. |
---|
| 545 | * |
---|
| 546 | */ |
---|
| 547 | sendbool(b) |
---|
[1509] | 548 | bool b; |
---|
[171] | 549 | { |
---|
[1509] | 550 | if (USP_put_boolean(us, (USPBoolean)b) != SUCCESS) { |
---|
[22864] | 551 | rpc_err = ERROR_TABLE_BASE_rpc + errno; |
---|
[1509] | 552 | return; |
---|
| 553 | } |
---|
[171] | 554 | } |
---|
| 555 | |
---|
| 556 | /* |
---|
| 557 | * |
---|
| 558 | * sendreply () -- Make the final call. |
---|
| 559 | * |
---|
| 560 | */ |
---|
| 561 | sendreply() |
---|
| 562 | { |
---|
[1509] | 563 | if (USP_end_block(us) != SUCCESS) { |
---|
[22864] | 564 | rpc_err = ERROR_TABLE_BASE_rpc + errno; |
---|
[1509] | 565 | return; |
---|
| 566 | } |
---|
| 567 | return; |
---|
[171] | 568 | } |
---|
[261] | 569 | |
---|
| 570 | /* |
---|
| 571 | * |
---|
| 572 | * senddunno () -- Send a 'I don't know this call' reply |
---|
| 573 | * |
---|
| 574 | */ |
---|
| 575 | senddunno() |
---|
| 576 | { |
---|
[1509] | 577 | USP_begin_block(us,UNKNOWN_CALL); |
---|
| 578 | if (USP_end_block(us) != SUCCESS) { |
---|
[22864] | 579 | rpc_err = ERROR_TABLE_BASE_rpc + errno; |
---|
[1509] | 580 | return; |
---|
| 581 | } |
---|
| 582 | return; |
---|
[261] | 583 | } |
---|