int write_tcp_reply( struct tcp_chan *chan, int protocol, int version, int command, int exit_code) { int ret; if ((ret = diswsi(chan,protocol)) == DIS_SUCCESS) { if ((ret = diswsi(chan,version)) == DIS_SUCCESS) { if ((ret = diswsi(chan,command)) == DIS_SUCCESS) { if ((ret = diswsi(chan,exit_code)) == DIS_SUCCESS) ret = DIS_tcp_wflush(chan); return(ret); } } } /* ERROR */ return(ret); } /* END write_tcp_reply() */
int is_compose( struct tcp_chan *chan, /* I */ int command) /* I */ { int ret; ret = diswsi(chan, IS_PROTOCOL); if (ret != DIS_SUCCESS) goto done; ret = diswsi(chan, IS_PROTOCOL_VER); if (ret != DIS_SUCCESS) goto done; ret = diswsi(chan, command); if (ret != DIS_SUCCESS) goto done; return(DIS_SUCCESS); done: DBPRT(("is_compose: send error %s\n", dis_emsg[ret])) return(ret); } /* END is_compose() */
/** * @brief * vn_encode_DIS_V4 - encode version 4 vnode information, used by Mom. * * @par Functionality: * Used to encode vnode information. See vn_encode_DIS() above for a * description of the information. Supports version 4 only. * * @param[in] fd - socket descriptor to which to write the encode info. * @param[in] vnlp - structure to encode and send. * * @return int * @retval DIS_SUCCESS (0) on success * @retval DIS_* on error. * * @par Side Effects: None * * @par MT-safe: No, the structure pointed to by vnlp needs to be locked * */ static int vn_encode_DIS_V4(int fd, vnl_t *vnlp) { int rc; unsigned int i, j; if (((rc = diswui(fd, PS_DIS_V4)) != 0) || ((rc = diswsl(fd, (long) vnlp->vnl_modtime)) != 0) || ((rc = diswui(fd, vnlp->vnl_used)) != 0)) return (rc); for (i = 0; i < vnlp->vnl_used; i++) { vnal_t *curreslist = VNL_NODENUM(vnlp, i); if ((rc = diswst(fd, curreslist->vnal_id)) != 0) return (rc); if ((rc = diswui(fd, curreslist->vnal_used)) != 0) return (rc); for (j = 0; j < curreslist->vnal_used; j++) { vna_t *curres = VNAL_NODENUM(curreslist, j); if ((rc = diswst(fd, curres->vna_name)) != 0) return (rc); if ((rc = diswst(fd, curres->vna_val)) != 0) return (rc); if ((rc = diswsi(fd, curres->vna_type)) != 0) return (rc); if ((rc = diswsi(fd, curres->vna_flag)) != 0) return (rc); } } return (DIS_SUCCESS); }
int send_command_str( struct tcp_chan *chan, int cmd, char *query) /* I */ { int rc; rc = diswsi(chan, cmd); if ((rc != DIS_SUCCESS) || (cmd == RM_CMD_CLOSE)) return(rc); if (cmd == RM_CMD_CONFIG) { if((rc = diswst(chan, ConfigBuf)) != DIS_SUCCESS) return (rc); } rc = diswcs(chan, query, strlen(query)); DIS_tcp_wflush(chan); return(rc); } /* END send_command_str() */
static int encode_DIS_Resc( struct tcp_chan *chan, char **rlist, int ct, resource_t rh) { int i; int rc; if ((rc = diswsi(chan,rh)) == 0) /* resource reservation handle */ { /* next send the number of resource strings */ if ((rc = diswui(chan, ct)) == 0) { /* now send each string (if any) */ for (i = 0; i < ct; ++i) { if ((rc = diswst(chan, *(rlist + i))) != 0) break; } } } return rc; }
/** * @brief * start and compose command * * @param[in] stream - socket descriptor * @param[in] com - command * * @return int * @retval 0 success * @retval !0 error * */ static int startcom(int stream, int com) { int ret; setup_dis(stream); ret = diswsi(stream, RM_PROTOCOL); if (ret == DIS_SUCCESS) { ret = diswsi(stream, RM_PROTOCOL_VER); if (ret == DIS_SUCCESS) ret = diswsi(stream, com); } if (ret != DIS_SUCCESS) { DBPRT(("startcom: diswsi error %s\n", dis_emsg[ret])) pbs_errno = errno; } return ret; }
int start_dialogue( struct tcp_chan *chan) { int rc; rc = diswsi(chan, RM_PROTOCOL); if (rc != DIS_SUCCESS) return(rc); rc = diswsi(chan, RM_PROTOCOL_VER); if (rc != DIS_SUCCESS) return(rc); rc = diswsi(chan, QueryI); return(rc); } /* END start_dialogue() */
static int startcom( struct tcp_chan *chan, int *local_errno, /* O */ int com, /* I */ int num_requests) /* I */ { int ret; ret = diswsi(chan, RM_PROTOCOL); if (ret == DIS_SUCCESS) { ret = diswsi(chan, RM_PROTOCOL_VER); if (ret == DIS_SUCCESS) { ret = diswsi(chan, num_requests); if (ret == DIS_SUCCESS) { ret = diswsi(chan, com); } } } if (ret != DIS_SUCCESS) { /* NOTE: cannot resolve log_err */ *local_errno = errno; } return(ret); } /* END startcom() */
int send_command( struct tcp_chan *chan, int cmd) { int rc; rc = diswsi(chan,cmd); if (cmd == RM_CMD_CONFIG) { diswst(chan,ConfigBuf); } DIS_tcp_wflush(chan); if (cmd == RM_CMD_CLOSE) DIS_tcp_close(chan); return(rc); } /* END send_command() */
int encode_DIS_JobObit( int sock, /* I */ struct batch_request *preq) /* I */ { int rc; struct svrattrl *psvrl; psvrl = (struct svrattrl *)GET_NEXT(preq->rq_ind.rq_jobobit.rq_attr); if ((rc = diswst(sock, preq->rq_ind.rq_jobobit.rq_jid) != 0) || (rc = diswsi(sock, preq->rq_ind.rq_jobobit.rq_status) != 0) || (rc = encode_DIS_svrattrl(sock, psvrl) != 0)) { /* FAILURE */ return(rc); } return(0); } /* END encode_DIS_JobObit() */
int do_mom( char *HPtr, int MOMPort, int CmdIndex) { int socket; int local_errno = 0; struct tcp_chan *chan = NULL; int rc; if ((socket = openrm(HPtr, MOMPort)) < 0) { /* FAILURE */ extern char TRMEMsg[]; fprintf(stderr, "cannot connect to MOM on node '%s', errno=%d (%s)\n", HPtr, errno, strerror(errno)); if (TRMEMsg[0] != '\0') { fprintf(stderr, " %s\n", TRMEMsg); } return(socket); } else if ((chan = DIS_tcp_setup(socket)) == NULL) { fprintf(stderr, "%s: can not allocate memory of socket buffers\n", __func__); return -1; } /* send protocol and version, plus how many queries we're sending */ if (QueryI == 0) QueryI = 1; if (start_dialogue(chan) != DIS_SUCCESS) { fprintf(stderr,"ERROR: Unable to write the number of queries to %s (errno=%d-%s)\n", HPtr, errno, strerror(errno)); send_command(chan,RM_CMD_CLOSE); DIS_tcp_cleanup(chan); return(-1); } if (IsVerbose == TRUE) { fprintf(stderr, "INFO: successfully connected to %s\n", HPtr); } switch (CmdIndex) { case momClear: { char tmpLine[1024]; char *Value; snprintf(tmpLine, 1024, "clearjob=%s", (JPtr != NULL) ? JPtr : "all"); if (send_command_str(chan, RM_CMD_REQUEST, tmpLine) != 0) { /* FAILURE */ fprintf(stderr,"ERROR: cannot request job clear on %s (errno=%d-%s)\n", HPtr, errno, strerror(errno)); send_command(chan,RM_CMD_CLOSE); return(-1); } if ((Value = (char *)read_mom_reply(&local_errno, chan)) == NULL) { /* FAILURE */ fprintf(stderr,"ERROR: job clear failed on %s (errno=%d - %s: %d - %s)\n", HPtr, errno, pbs_strerror(errno), local_errno, pbs_strerror(local_errno)); send_command(chan,RM_CMD_CLOSE); return(-1); } /* job cleared */ fprintf(stdout,"job clear request successful on %s\n", HPtr); free(Value); } /* END BLOCK (case momClear) */ break; case momShutdown: { if ((send_command(chan,RM_CMD_SHUTDOWN) != PBSE_NONE) || (check_success(chan) != PBSE_NONE)) { /* FAILURE */ fprintf(stderr,"ERROR: cannot shutdown mom daemon on %s (errno=%d-%s)\n", HPtr, errno, pbs_strerror(errno)); send_command(chan,RM_CMD_CLOSE); exit(EXIT_FAILURE); } fprintf(stdout, "shutdown request successful on %s\n", HPtr); } /* END BLOCK */ break; case momReconfig: { if ((send_command(chan,RM_CMD_CONFIG) != PBSE_NONE) || (check_success(chan) != PBSE_NONE)) { /* FAILURE */ fprintf(stderr,"ERROR: cannot reconfigure mom on %s (errno=%d-%s)\n", HPtr, errno, pbs_strerror(errno)); send_command(chan,RM_CMD_CLOSE); return(-1); } fprintf(stdout, "reconfig successful on %s\n", HPtr); } /* END BLOCK (case momReconfig) */ break; case momLayout: char *value; if (send_command(chan, RM_CMD_LAYOUT) != PBSE_NONE) { fprintf(stdout, "Layout command failed to send to mom\n"); return(-1); } if ((value = read_mom_reply(&local_errno, chan)) == NULL) { fprintf(stdout, "Could not read a layout reply from the mom\n"); return(-1); } else { fprintf(stdout, "%s", value); free(value); } break; case momQuery: default: { char *ptr; int rindex; char *Value; for (rindex = 0; rindex < QueryI; rindex++) { if (send_command_str(chan, RM_CMD_REQUEST, Query[rindex]) != 0) { fprintf(stderr,"ERROR: cannot add query for '%s' on %s (errno=%d-%s)\n", Query[rindex], HPtr, errno, pbs_strerror(errno)); } } for (rindex = 0;rindex < QueryI;rindex++) { if ((ptr = strchr(Query[rindex],'=')) != NULL) { *ptr = '\0'; } if ((Value = (char *)read_mom_reply(&local_errno, chan)) == NULL) { fprintf(stderr, "ERROR: query[%d] '%s' failed on %s (errno=%d - %s : %d - %s)\n", rindex, Query[rindex], HPtr, errno, pbs_strerror(errno), local_errno, pbs_strerror(local_errno)); return(-1); } else { if (!strncmp(Query[rindex], "diag", strlen("diag"))) { fprintf(stdout, "%s\n", Value); } else if (!strncmp(Query[rindex], "cycle", strlen("cycle"))) { fprintf(stdout, "mom %s successfully cycled %s\n", HPtr, Value); } else { fprintf(stdout, "%12s: %12s = '%s'\n", HPtr, Query[rindex], Value); } } free(Value); if (ptr != NULL) { *ptr = '='; } } /* END for (rindex) */ } /* END BLOCK (case momQuery) */ break; } /* END switch(CmdIndex) */ rc = diswsi(chan, RM_PROTOCOL); if (rc != DIS_SUCCESS) goto do_mom_fail; rc = diswsi(chan, RM_PROTOCOL_VER); if (rc != DIS_SUCCESS) goto do_mom_fail; rc = diswsi(chan, 1); if (rc != DIS_SUCCESS) goto do_mom_fail; /* send_command will free chan */ send_command(chan,RM_CMD_CLOSE); return(0); do_mom_fail: DIS_tcp_close(chan); return(rc); } /* END do_mom() */
int diswl_( struct tcp_chan *chan, dis_long_double_t value, unsigned ndigs) { int c; int expon; int negate; int retval; unsigned pow2; char *cp; char *ocp; dis_long_double_t ldval; char scratch[DIS_BUFSIZ+1]; assert(ndigs > 0 && ndigs <= LDBL_DIG); memset(scratch, 0, DIS_BUFSIZ+1); /* Make zero a special case. If we don't it will blow exponent */ /* calculation. */ if (value == 0.0L) { retval = tcp_puts(chan, "+0+0", 4) < 0 ? DIS_PROTO : DIS_SUCCESS; return ((tcp_wcommit(chan, retval == DIS_SUCCESS) < 0) ? DIS_NOCOMMIT : retval); } /* Extract the sign from the coefficient. */ ldval = (negate = value < 0.0L) ? -value : value; /* Detect and complain about the infinite form. */ if (ldval > LDBL_MAX) return (DIS_HUGEVAL); /* Compute the integer part of the log to the base 10 of ldval. As a */ /* byproduct, reduce the range of ldval to the half-open interval, */ /* [1, 10). */ if (dis_lmx10 == 0) disi10l_(); expon = 0; pow2 = dis_lmx10 + 1; if (ldval < 1.0L) { do { if (ldval < dis_ln10[--pow2]) { ldval *= dis_lp10[pow2]; expon += 1 << pow2; } } while (pow2); ldval *= 10.0; expon = -expon - 1; } else { do { if (ldval >= dis_lp10[--pow2]) { ldval *= dis_ln10[pow2]; expon += 1 << pow2; } } while (pow2); } /* Round the value to the last digit */ ldval += 5.0L * disp10l_(-ndigs); if (ldval >= 10.0L) { expon++; ldval *= 0.1L; } /* Starting in the middle of the buffer, convert coefficient digits, */ /* most significant first. */ ocp = cp = &scratch[DIS_BUFSIZ - ndigs]; do { c = ldval; ldval = (ldval - c) * 10.0L; *ocp++ = c + '0'; } while (--ndigs); /* Eliminate trailing zeros. */ while (*--ocp == '0'); /* The decimal point is at the low order end of the coefficient */ /* integer, so adjust the exponent for the number of digits in the */ /* coefficient. */ ndigs = ++ocp - cp; expon -= ndigs - 1; /* Put the coefficient sign into the buffer, left of the coefficient. */ *--cp = negate ? '-' : '+'; /* Insert the necessary number of counts on the left. */ while (ndigs > 1) cp = discui_(cp, ndigs, &ndigs); /* The complete coefficient integer is done. Put it out. */ retval = tcp_puts(chan, cp, (size_t)(ocp - cp)) < 0 ? DIS_PROTO : DIS_SUCCESS; /* If that worked, follow with the exponent, commit, and return. */ if (retval == DIS_SUCCESS) return (diswsi(chan, expon)); /* If coefficient didn't work, negative commit and return the error. */ return ((tcp_wcommit(chan, FALSE) < 0) ? DIS_NOCOMMIT : retval); }
int encode_DIS_reply( struct tcp_chan *chan, struct batch_reply *reply) { int ct; int i; struct brp_select *psel; struct brp_status *pstat; svrattrl *psvrl; int rc; /* first encode "header" consisting of protocol type and version */ if ((rc = diswui(chan, PBS_BATCH_PROT_TYPE)) || (rc = diswui(chan, PBS_BATCH_PROT_VER))) return rc; /* next encode code, auxcode and choice (union type identifier) */ if ((rc = diswsi(chan, reply->brp_code)) || (rc = diswsi(chan, reply->brp_auxcode)) || (rc = diswui(chan, reply->brp_choice))) return rc; switch (reply->brp_choice) { case BATCH_REPLY_CHOICE_NULL: break; /* no more to do */ case BATCH_REPLY_CHOICE_Queue: case BATCH_REPLY_CHOICE_RdytoCom: case BATCH_REPLY_CHOICE_Commit: if ((rc = diswst(chan, reply->brp_un.brp_jid))) return (rc); break; case BATCH_REPLY_CHOICE_Select: /* have to send count of number of strings first */ ct = 0; psel = reply->brp_un.brp_select; while (psel) { ++ct; psel = psel->brp_next; } if ((rc = diswui(chan, ct))) return rc; psel = reply->brp_un.brp_select; while (psel) { /* now encode each string */ if ((rc = diswst(chan, psel->brp_jobid))) return rc; psel = psel->brp_next; } break; case BATCH_REPLY_CHOICE_Status: /* encode "server version" of status structure. * * Server always uses svrattrl form. * Commands decode into their form. * * First need to encode number of status objects and then * the object itself. */ ct = 0; pstat = (struct brp_status *)GET_NEXT(reply->brp_un.brp_status); while (pstat) { ++ct; pstat = (struct brp_status *)GET_NEXT(pstat->brp_stlink); } if ((rc = diswui(chan, ct))) return rc; pstat = (struct brp_status *)GET_NEXT(reply->brp_un.brp_status); while (pstat) { if ((rc = diswui(chan, pstat->brp_objtype)) || (rc = diswst(chan, pstat->brp_objname))) return rc; psvrl = (svrattrl *)GET_NEXT(pstat->brp_attr); if ((rc = encode_DIS_svrattrl(chan, psvrl))) return rc; pstat = (struct brp_status *)GET_NEXT(pstat->brp_stlink); } break; case BATCH_REPLY_CHOICE_Text: /* text reply */ if ((rc = diswcs(chan, reply->brp_un.brp_txt.brp_str, reply->brp_un.brp_txt.brp_txtlen))) return rc; break; case BATCH_REPLY_CHOICE_Locate: /* Locate Job Reply */ if ((rc = diswst(chan, reply->brp_un.brp_locate))) return rc; break; case BATCH_REPLY_CHOICE_RescQuery: /* Query Resources Reply */ ct = reply->brp_un.brp_rescq.brq_number; if ((rc = diswui(chan, ct))) return rc; for (i = 0; (i < ct) && (rc == 0); ++i) { rc = diswui(chan, *(reply->brp_un.brp_rescq.brq_avail + i)); } if (rc) return rc; for (i = 0; (i < ct) && (rc == 0); ++i) { rc = diswui(chan, *(reply->brp_un.brp_rescq.brq_alloc + i)); } if (rc) return rc; for (i = 0; (i < ct) && (rc == 0); ++i) { rc = diswui(chan, *(reply->brp_un.brp_rescq.brq_resvd + i)); } if (rc) return rc; for (i = 0; (i < ct) && (rc == 0); ++i) { rc = diswui(chan, *(reply->brp_un.brp_rescq.brq_down + i)); } if (rc) return rc; break; default: return -1; } return 0; }
/** * @brief * Converts <value> into a Data-is-Strings floating point number and sends * it to <stream>. * * @param[in] stream socket fd * @param[in] value value to be converted * * @return int * @retval DIS_SUCCESS success * @retval error code error * */ int diswf(int stream, double value) { int c; int expon; unsigned ndigs; int negate; int retval; unsigned pow2; char *cp; char *ocp; double dval; assert(stream >= 0); assert(dis_puts != NULL); assert(disw_commit != NULL); /* Make zero a special case. If we don't it will blow exponent */ /* calculation. */ if (value == 0.0) { retval = (*dis_puts)(stream, "+0+0", 4) != 4 ? DIS_PROTO : DIS_SUCCESS; return (((*disw_commit)(stream, retval == DIS_SUCCESS) < 0) ? DIS_NOCOMMIT : retval); } /* Extract the sign from the coefficient. */ dval = (negate = value < 0.0) ? -value : value; /* Detect and complain about the infinite form. */ if (dval > FLT_MAX) return (DIS_HUGEVAL); /* Compute the integer part of the log to the base 10 of dval. As a */ /* byproduct, reduce the range of dval to the half-open interval, */ /* [1, 10). */ /* dis_dmx10 would be initialized by prior call to dis_init_tables */ expon = 0; pow2 = dis_dmx10 + 1; if (dval < 1.0) { do { if (dval < dis_dn10[--pow2]) { dval *= dis_dp10[pow2]; expon += 1 << pow2; } } while (pow2); dval *= 10.0; expon = -expon - 1; } else { do { if (dval >= dis_dp10[--pow2]) { dval *= dis_dn10[pow2]; expon += 1 << pow2; } } while (pow2); } /* Round the value to the last digit */ dval += 5.0 * disp10d_(-FLT_DIG); if (dval >= 10.0) { expon++; dval *= 0.1; } /* Starting in the middle of the buffer, convert coefficient digits, */ /* most significant first. */ ocp = cp = &dis_buffer[DIS_BUFSIZ - FLT_DIG]; ndigs = FLT_DIG; do { c = dval; dval = (dval - c) * 10.0; *ocp++ = c + '0'; } while (--ndigs); /* Eliminate trailing zeros. */ while (*--ocp == '0'); /* The decimal point is at the low order end of the coefficient */ /* integer, so adjust the exponent for the number of digits in the */ /* coefficient. */ ndigs = ++ocp - cp; expon -= ndigs - 1; /* Put the coefficient sign into the buffer, left of the coefficient. */ *--cp = negate ? '-' : '+'; /* Insert the necessary number of counts on the left. */ while (ndigs > 1) cp = discui_(cp, ndigs, &ndigs); /* The complete coefficient integer is done. Put it out. */ retval = (*dis_puts)(stream, cp, (size_t)(ocp - cp)) < 0 ? DIS_PROTO : DIS_SUCCESS; /* If that worked, follow with the exponent, commit, and return. */ if (retval == DIS_SUCCESS) return (diswsi(stream, expon)); /* If coefficient didn't work, negative commit and return the error. */ return (((*disw_commit)(stream, FALSE) < 0) ? DIS_NOCOMMIT : retval); }
/** * @brief * Generate munge key specific to the user and send PBS batch request * (PBS_BATCH_AuthExternal)to PBS server to authenticate user. * * @param[in] sock - socket fd * @param[in] auth_type - Authentication type (Munge/AMS etc) * @param[in] fromsvr - connection initiated from server? * * @return int * @retval 0 on success * @retval -1 on failure * @retval -2 on unsupported auth_type * */ int engage_external_authentication(int sock, int auth_type, int fromsvr, char *ebuf, int ebufsz) { int cred_len = 0, rc = 0, ret = 0; char *cred = NULL; struct batch_reply *reply = NULL; switch (auth_type) { #ifndef WIN32 case AUTH_MUNGE: ebuf[0] = '\0'; cred = pbs_get_munge_auth_data(fromsvr, ebuf, ebufsz); if (!cred) goto err; break; #endif default: snprintf(ebuf, ebufsz, "Authentication type not supported"); ret = -2; } if (cred) { ret = -1; cred_len = strlen(cred); DIS_tcp_setup(sock); if (encode_DIS_ReqHdr(sock, PBS_BATCH_AuthExternal, pbs_current_user) || diswuc(sock, auth_type) || /* authentication_type */ diswsi(sock, cred_len) || /* credential length */ diswcs(sock, cred, cred_len) || /* credential data */ encode_DIS_ReqExtend(sock, NULL)) { pbs_errno = PBSE_SYSTEM; goto err; } if (DIS_tcp_wflush(sock)) { pbs_errno = PBSE_SYSTEM; goto err; } memset(cred, 0, cred_len); reply = PBSD_rdrpy_sock(sock, &rc); if ((reply != NULL) && (reply->brp_code != 0)) { pbs_errno = PBSE_BADCRED; PBSD_FreeReply(reply); goto err; } PBSD_FreeReply(reply); free(cred); return 0; } /* else fall through */ err: if (ebuf[0] != '\0') { fprintf(stderr, "%s\n", ebuf); cs_logerr(-1, __func__, ebuf); } free(cred); return ret; }