/*! Receive message from queue (global or from own thread message queue) */ int sys__msg_recv ( void *p ) { /* parameters on thread stack */ int src_type; /* MSG_QUEUE or MSG_THREAD */ void *src; /* (msg_q *) or (thread_t *) */ msg_t *msg; /* { type, size, data[0..size-1] } */ int type; /* message type (identifier) */ size_t size; /* size of 'data' member */ uint flags; /* local variables */ kthread_t *kthr; kthrmsg_qs *thrmsg; kgmsg_q *kgmsgq; kmsg_q *kmsgq; msg_q *msgq; kmsg_t *kmsg; src_type = *( (int *) p ); p += sizeof (int); src = *( (void **) p ); p += sizeof (void *); msg = *( (msg_t **) p ); p += sizeof (msg_t *); type = *( (int *) p ); p += sizeof (int); size = *( (size_t *) p ); p += sizeof (size_t); flags = *( (uint *) p ); ASSERT_ERRNO_AND_EXIT ( src && msg, E_INVALID_HANDLE ); ASSERT_ERRNO_AND_EXIT ( src_type == MSG_THREAD || src_type == MSG_QUEUE, E_INVALID_TYPE ); if ( src_type == MSG_THREAD ) { kthr = k_get_active_thread (); thrmsg = k_get_thrmsg ( kthr ); kmsgq = &thrmsg->msgq; } else { /* src_type == MSG_QUEUE */ msgq = src; kgmsgq = msgq->handle; ASSERT_ERRNO_AND_EXIT ( kgmsgq && kgmsgq->id == msgq->id, E_INVALID_HANDLE ); kmsgq = &kgmsgq->mq; } /* get first message from queue */ kmsg = list_get ( &kmsgq->msgs, FIRST ); if ( type != 0 ) /* type != 0 => search for first message 'type' */ while ( kmsg && kmsg->msg.type != type ) kmsg = list_get_next ( &kmsg->list ); if ( kmsg ) /* have message */ { if ( size < kmsg->msg.size ) { msg->size = 0; EXIT ( E_TOO_BIG ); } msg->type = kmsg->msg.type; msg->size = kmsg->msg.size; memcpy ( msg->data, kmsg->msg.data, msg->size ); kmsg = list_remove ( &kmsgq->msgs, FIRST, &kmsg->list ); ASSERT ( kmsg ); kfree ( kmsg ); EXIT ( SUCCESS ); } else { /* queue empty! */ if ( !( flags & IPC_WAIT ) ) EXIT ( E_EMPTY ); SET_ERRNO ( E_RETRY ); /* block thread */ k_enqueue_thread ( NULL, &kmsgq->thrq ); k_schedule_threads (); RETURN ( E_RETRY ); } }
int pap_read(int fd, u_char *data, int len) { SET_ERRNO(ENXIO); return (-1); }
int assemble_rmcp_pkt (fiid_obj_t obj_rmcp_hdr, fiid_obj_t obj_cmd, void *pkt, unsigned int pkt_len, unsigned int flags) { int obj_cmd_len, obj_rmcp_hdr_len; unsigned int flags_mask = 0; if (!fiid_obj_valid (obj_rmcp_hdr) || !fiid_obj_valid (obj_cmd) || !pkt || !pkt_len || (flags & ~flags_mask)) { SET_ERRNO (EINVAL); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_rmcp_hdr, tmpl_rmcp_hdr) < 0) { ERRNO_TRACE (errno); return (-1); } if (FIID_OBJ_PACKET_VALID (obj_rmcp_hdr) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); return (-1); } if (FIID_OBJ_PACKET_VALID (obj_cmd) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } if ((obj_rmcp_hdr_len = fiid_obj_len_bytes (obj_rmcp_hdr)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); return (-1); } if ((obj_cmd_len = fiid_obj_len_bytes (obj_cmd)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } if (pkt_len < (obj_rmcp_hdr_len + obj_cmd_len)) { SET_ERRNO (EMSGSIZE); return (-1); } memset (pkt, '\0', pkt_len); if ((obj_rmcp_hdr_len = fiid_obj_get_all (obj_rmcp_hdr, pkt, pkt_len)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); return (-1); } if ((obj_cmd_len = fiid_obj_get_all (obj_cmd, pkt + obj_rmcp_hdr_len, pkt_len - obj_rmcp_hdr_len)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } return (obj_rmcp_hdr_len + obj_cmd_len); }
static int fuse_operations_mount_open(struct MountsPublicInterface* this_, const char* path, int oflag, uint32_t mode) { int ret=-1; int fd=-1; struct FuseOperationsMount* fs = (struct FuseOperationsMount*)this_; struct stat st; struct stat st_parent; int file_exist; CHECK_FUNC_ENSURE_EXIST(fs, open); file_exist=fs->fuse_operations->getattr(path, &st); /*file exist, do checks of O_CREAT, O_EXCL flags*/ if ( !file_exist && CHECK_FLAG(oflag, O_CREAT) && CHECK_FLAG(oflag, O_EXCL) ) { SET_ERRNO(EEXIST); return -1; } /*truncate existing writable file*/ if ( !file_exist && CHECK_FLAG(oflag, O_TRUNC) && (CHECK_FLAG(oflag, O_WRONLY) || CHECK_FLAG(oflag, O_RDWR)) ) { CHECK_FUNC_ENSURE_EXIST(fs, truncate); if ( (ret=fs->fuse_operations->truncate(path, 0)) <0 ) { /*truncate error*/ SET_ERRNO(-ret); return -1; } } /*create fuse object, it must be attached into ofd entry or be destroyed if zrt would not be able to return file handle*/ struct fuse_file_info *finfo = calloc(1, sizeof(struct fuse_file_info)); /*reset flags that should not be passed to fuse's open*/ finfo->flags = oflag & ~(O_CREAT|O_TRUNC|O_EXCL); /*is file exist?*/ if (!file_exist) { if ( (ret=fs->fuse_operations->open(path, finfo)) <0 ) { SET_ERRNO(-ret); } } else { /*file does not exist, create & open it*/ if ( CHECK_FLAG(oflag, O_CREAT) ) { CHECK_FUNC_ENSURE_EXIST(fs, create); if ( (ret=fs->fuse_operations->create(path, mode, finfo)) <0 ) { SET_ERRNO(-ret); } } } /*if path open/create success*/ if ( ! ret ) { int open_file_description_id; if ( fs->proxy_mode == EFuseProxyModeDisabled ) { /*in case if fs works in generic mode it use own handles stored in finfo->fh, so we need to issue a global fd visible across system*/ open_file_description_id = get_open_files_pool()->getnew_ofd(oflag); fd = fs->handle_allocator->allocate_handle(this_, st.st_ino, st_parent.st_ino, open_file_description_id); if ( fd < 0 ) { /*it's hipotetical but possible case if amount of open files are exceeded an maximum value.*/ fs->open_files_pool->release_ofd(open_file_description_id); SET_ERRNO(ENFILE); } } else if ( fs->proxy_mode == EFuseProxyModeEnabled) { /*proxy mode is enabled, so open already returned actual fd, therefore do not issue a new one and use returned*/ fd = finfo->fh; const struct HandleItem *hentry = fs->handle_allocator->entry(finfo->fh); if (hentry!=NULL) open_file_description_id = hentry->open_file_description_id; else { ZRT_LOG(L_ERROR, "can't open '%s' due to handle=%lld returned from fuse fs has no HandleEntry", path, finfo->fh ); SET_ERRNO(EINVAL); } } else { assert(0); } /*successfully opened, save fuse data*/ struct FuseFileOptionalData *fdata = malloc( sizeof(struct FuseFileOptionalData) ); fs->open_files_pool->set_optional_data( open_file_description_id, (intptr_t)fdata ); fdata->path = strdup(path); fdata->finfo = finfo; return fd; } else { free(finfo); return -1; } }
asmlinkage int pthread_create_sys (pthread_t *thread, const pthread_attr_t *attr, void *(*startup)(void *), void *(*start_routine)(void *), void *args) { int flags; hw_save_flags_and_cli (flags); // Check policy & prio if (attr) { if (attr->policy != SCHED_FIFO) { SET_ERRNO(EINVAL); return -1; } else { if (attr -> sched_param.sched_priority > MIN_SCHED_PRIORITY || attr -> sched_param.sched_priority < MAX_SCHED_PRIORITY) { SET_ERRNO(EINVAL); return -1; } } } // Creating the pthread structure if (!(*thread = create_pthread_struct ())) { SET_ERRNO (EAGAIN); hw_restore_flags (flags); return -1; } /* * Configuring the new thread either with attr (if not NULL) * or with the default values */ if (attr) { (*thread) -> sched_param = attr -> sched_param; (*thread) -> stack_info.stack_size = attr -> stack_size; (*thread) -> stack_info.stack_bottom = attr -> stack_addr; SET_THREAD_DETACH_STATE((*thread), attr -> detachstate); SET_THREAD_POLICY ((*thread), attr -> policy); } else { (*thread) -> sched_param.sched_priority = MIN_SCHED_PRIORITY; (*thread) -> stack_info.stack_size = STACK_SIZE; (*thread) -> stack_info.stack_bottom = 0; SET_THREAD_DETACH_STATE((*thread), 0); SET_THREAD_POLICY ((*thread), SCHED_FIFO); } if (!((*thread) -> stack_info.stack_bottom)) { // Creating the thread stack if (alloc_stack (&(*thread) -> stack_info) < 0) { SET_ERRNO (EAGAIN); hw_restore_flags (flags); return -1; } } // This is arhictecture dependent (*thread) -> stack = setup_stack ((*thread)->stack_info.stack_bottom + (*thread)->stack_info.stack_size / sizeof (int), startup, start_routine, args); activate_thread (*thread); pthread_t tmp = *thread; printf("pthred_create_sys thread 0x%x state:%d\n", (unsigned long)tmp, GET_THREAD_STATE(tmp)); // no error at all hw_restore_flags (flags); // Calling the scheduler scheduling (); return 0; }
int unassemble_ipmi_lan_pkt (const void *pkt, unsigned int pkt_len, fiid_obj_t obj_rmcp_hdr, fiid_obj_t obj_lan_session_hdr, fiid_obj_t obj_lan_msg_hdr, fiid_obj_t obj_cmd, fiid_obj_t obj_lan_msg_trlr, unsigned int flags) { uint8_t authentication_type; unsigned int indx = 0; unsigned int obj_cmd_len; int obj_lan_msg_trlr_len, len; uint64_t val; unsigned int flags_mask = (IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK); if (!pkt || !fiid_obj_valid (obj_rmcp_hdr) || !fiid_obj_valid (obj_lan_session_hdr) || !fiid_obj_valid (obj_lan_msg_hdr) || !fiid_obj_valid (obj_cmd) || !fiid_obj_valid (obj_lan_msg_trlr) || (flags & ~flags_mask)) { SET_ERRNO (EINVAL); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_rmcp_hdr, tmpl_rmcp_hdr) < 0) { ERRNO_TRACE (errno); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_session_hdr, tmpl_lan_session_hdr) < 0) { ERRNO_TRACE (errno); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_msg_hdr, tmpl_lan_msg_hdr_rs) < 0) { ERRNO_TRACE (errno); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_msg_trlr, tmpl_lan_msg_trlr) < 0) { ERRNO_TRACE (errno); return (-1); } indx = 0; if (fiid_obj_clear (obj_rmcp_hdr) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); return (-1); } if (fiid_obj_clear (obj_lan_session_hdr) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); return (-1); } if (fiid_obj_clear (obj_lan_msg_hdr) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr); return (-1); } if (fiid_obj_clear (obj_cmd) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } if (fiid_obj_clear (obj_lan_msg_trlr) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr); return (-1); } if ((len = fiid_obj_set_all (obj_rmcp_hdr, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); return (-1); } indx += len; if (pkt_len <= indx) { /* cannot parse packet */ ERR_TRACE ("malformed packet", EINVAL); return (0); } if ((len = fiid_obj_set_block (obj_lan_session_hdr, "authentication_type", "session_id", pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); return (-1); } indx += len; if (FIID_OBJ_GET (obj_lan_session_hdr, "authentication_type", &val) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); return (-1); } authentication_type = val; if (!IPMI_1_5_AUTHENTICATION_TYPE_VALID (authentication_type)) { /* cannot parse packet */ ERR_TRACE ("malformed packet", EINVAL); return (0); } if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE) { if ((len = fiid_obj_set_data (obj_lan_session_hdr, "authentication_code", pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); return (-1); } indx += len; if (pkt_len <= indx) { /* cannot parse packet */ ERR_TRACE ("malformed packet", EINVAL); return (0); } } if ((len = fiid_obj_set_data (obj_lan_session_hdr, "ipmi_msg_len", pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); return (-1); } indx += len; if (pkt_len <= indx) { /* cannot parse packet */ ERR_TRACE ("malformed packet", EINVAL); return (0); } if ((len = fiid_obj_set_all (obj_lan_msg_hdr, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr); return (-1); } indx += len; if (pkt_len <= indx) { /* cannot parse packet */ ERR_TRACE ("malformed packet", EINVAL); return (0); } if ((obj_lan_msg_trlr_len = fiid_template_len_bytes (tmpl_lan_msg_trlr)) < 0) { ERRNO_TRACE (errno); return (-1); } if ((pkt_len - indx) <= obj_lan_msg_trlr_len) { /* cannot parse packet */ ERR_TRACE ("malformed packet", EINVAL); return (0); } obj_cmd_len = (pkt_len - indx) - obj_lan_msg_trlr_len; if ((len = fiid_obj_set_all (obj_cmd, pkt + indx, obj_cmd_len)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } indx += len; if (pkt_len <= indx) { /* cannot parse packet */ ERR_TRACE ("malformed packet", EINVAL); return (0); } if ((len = fiid_obj_set_all (obj_lan_msg_trlr, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr); return (-1); } indx += len; if (FIID_OBJ_PACKET_VALID (obj_rmcp_hdr) == 1 && FIID_OBJ_PACKET_VALID (obj_lan_session_hdr) == 1 && FIID_OBJ_PACKET_VALID (obj_lan_msg_hdr) == 1 && ((flags & IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK) || FIID_OBJ_PACKET_SUFFICIENT (obj_cmd) == 1) && FIID_OBJ_PACKET_VALID (obj_lan_msg_trlr) == 1) return (1); return (0); }
int ipmi_algorithms_to_cipher_suite_id (uint8_t authentication_algorithm, uint8_t integrity_algorithm, uint8_t confidentiality_algorithm, uint8_t *cipher_suite_id) { if (!IPMI_AUTHENTICATION_ALGORITHM_SUPPORTED (authentication_algorithm) || !IPMI_INTEGRITY_ALGORITHM_SUPPORTED (integrity_algorithm) || !IPMI_CONFIDENTIALITY_ALGORITHM_SUPPORTED (confidentiality_algorithm) || !IPMI_CIPHER_SUITE_COMBINATION_VALID (authentication_algorithm, integrity_algorithm, confidentiality_algorithm) || !cipher_suite_id) { SET_ERRNO (EINVAL); return (-1); } if (authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE && integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE && confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) *cipher_suite_id = 0; else if (authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1) { if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE && confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) *cipher_suite_id = 1; else /* integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96) */ { if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) *cipher_suite_id = 2; else if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128) *cipher_suite_id = 3; else if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_128) *cipher_suite_id = 4; else /* confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40 */ *cipher_suite_id = 5; } } else if (authentication_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128) { if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE && confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) *cipher_suite_id = 6; else if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128) { if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) *cipher_suite_id = 7; else if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128) *cipher_suite_id = 8; else if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_128) *cipher_suite_id = 9; else /* confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40 */ *cipher_suite_id = 10; } else /* integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_MD5_128 */ { if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) *cipher_suite_id = 11; else if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128) *cipher_suite_id = 12; else if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_128) *cipher_suite_id = 13; else /* confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40 */ *cipher_suite_id = 14; } } else if (authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256) { if (integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE && confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) *cipher_suite_id = 15; else /* integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128 */ { if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE) *cipher_suite_id = 16; else if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128) *cipher_suite_id = 17; else if (confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_128) *cipher_suite_id = 18; else /* confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40 */ *cipher_suite_id = 19; } } return (0); }
/*! * Receive message from queue (global or from own thread message queue) */ int sys__msg_recv ( int src_type, void *src, msg_t *msg, int type, size_t size, uint flags ) { kthread_t *kthr; kthrmsg_qs *thrmsg; kgmsg_q *kgmsgq; kmsg_q *kmsgq; msg_q *msgq; kmsg_t *kmsg; ASSERT_ERRNO_AND_EXIT ( src && msg, E_INVALID_HANDLE ); ASSERT_ERRNO_AND_EXIT ( src_type == MSG_THREAD || src_type == MSG_QUEUE, E_INVALID_TYPE ); if ( src_type == MSG_THREAD ) { kthr = k_get_active_thread (); thrmsg = k_get_thrmsg ( kthr ); kmsgq = &thrmsg->msgq; } else { /* src_type == MSG_QUEUE */ msgq = src; kgmsgq = msgq->handle; ASSERT_ERRNO_AND_EXIT ( kgmsgq && kgmsgq->id == msgq->id, E_INVALID_HANDLE ); kmsgq = &kgmsgq->mq; } /* get first message from queue */ kmsg = list_get ( &kmsgq->msgs, FIRST ); if ( type != 0 ) /* type != 0 => search for first message 'type' */ while ( kmsg && kmsg->msg.type != type ) kmsg = list_get_next ( &kmsg->list ); if ( kmsg ) /* have message */ { if ( size < kmsg->msg.size ) { msg->size = 0; EXIT ( E_TOO_BIG ); } msg->type = kmsg->msg.type; msg->size = kmsg->msg.size; memcpy ( msg->data, kmsg->msg.data, msg->size ); kmsg = list_remove ( &kmsgq->msgs, FIRST, &kmsg->list ); ASSERT ( kmsg ); kfree ( kmsg ); EXIT ( SUCCESS ); } else { /* queue empty! */ if ( !( flags & IPC_WAIT ) ) EXIT ( E_EMPTY ); SET_ERRNO ( E_RETRY ); /* block thread */ k_enqueue_thread ( NULL, &kmsgq->thrq ); k_schedule_threads (); RETURN ( E_RETRY ); } }
/*! * Start new process * \param prog_name Program name (as given with module) * \param thr_desc Pointer to thread descriptor (user) for starting thread * \param param Command line arguments for starting thread (if not NULL) * \param prio Priority for starting thread */ int sys__start_program ( void *p ) { char *prog_name; void *param; int prio; thread_t *thr_desc; kthread_t *kthr, *cur = active_thread; char *arg, *karg, **args, **kargs = NULL; int argnum, argsize; prog_name = *( (void **) p ); p += sizeof (void *); ASSERT_ERRNO_AND_EXIT ( prog_name, E_INVALID_HANDLE ); prog_name = U2K_GET_ADR ( prog_name, cur->proc ); thr_desc = *( (void **) p ); p += sizeof (void *); param = *( (void **) p ); p += sizeof (void *); prio = *( (int *) p ); if ( param ) /* copy parameters from one process space to another */ { /* copy parameters to new process address space */ /* first copy them to kernel */ argnum = 0; argsize = 0; args = U2K_GET_ADR ( param, cur->proc ); while ( args[argnum] ) { arg = U2K_GET_ADR ( args[argnum++], cur->proc ); argsize += strlen ( arg ) + 1; } if ( argnum > 0 ) { kargs = kmalloc ( (argnum + 1) * sizeof (void *) + argsize ); karg = (void *) kargs + (argnum + 1) * sizeof (void *); argnum = 0; while ( args[argnum] ) { arg = U2K_GET_ADR ( args[argnum], cur->proc ); strcpy ( karg, arg ); kargs[argnum++] = karg; karg += strlen ( karg ) + 1; } kargs[argnum] = NULL; } } SET_ERRNO ( SUCCESS ); kthr = k_proc_start ( prog_name, kargs, prio ); if ( !kthr ) EXIT ( E_NO_MEMORY ); if ( thr_desc ) /* save thread descriptor */ { thr_desc = U2K_GET_ADR ( thr_desc, cur->proc ); thr_desc->thread = kthr; thr_desc->thr_id = kthr->id; } RETURN ( SUCCESS ); }
int ipmi_dump_rmcp_packet (int fd, const char *prefix, const char *hdr, const char *trlr, const void *pkt, unsigned int pkt_len, fiid_template_t tmpl_cmd) { unsigned int indx = 0; char prefix_buf[IPMI_DEBUG_MAX_PREFIX_LEN]; char *rmcp_hdr = "RMCP Header:\n" "------------"; char *rmcp_cmd = "RMCP Command Data:\n" "------------------"; char *unexpected_hdr = "Unexpected Data:\n" "----------------"; fiid_obj_t obj_rmcp_hdr = NULL; fiid_obj_t obj_cmd = NULL; fiid_obj_t obj_unexpected_data = NULL; int len, rv = -1; if (!pkt || !tmpl_cmd) { SET_ERRNO (EINVAL); return (-1); } if (debug_set_prefix (prefix_buf, IPMI_DEBUG_MAX_PREFIX_LEN, prefix) < 0) { ERRNO_TRACE (errno); return (-1); } if (debug_output_str (fd, prefix_buf, hdr) < 0) { ERRNO_TRACE (errno); return (-1); } /* Dump rmcp header */ if (!(obj_rmcp_hdr = fiid_obj_create (tmpl_rmcp_hdr))) { ERRNO_TRACE (errno); goto cleanup; } if ((len = fiid_obj_set_all (obj_rmcp_hdr, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); goto cleanup; } indx += len; if (ipmi_obj_dump (fd, prefix, rmcp_hdr, NULL, obj_rmcp_hdr) < 0) { ERRNO_TRACE (errno); goto cleanup; } if (pkt_len <= indx) { rv = 0; goto cleanup; } /* Dump command data */ if (!(obj_cmd = fiid_obj_create (tmpl_cmd))) { ERRNO_TRACE (errno); goto cleanup; } if ((len = fiid_obj_set_all (obj_cmd, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); goto cleanup; } indx += len; if (ipmi_obj_dump (fd, prefix, rmcp_cmd, NULL, obj_cmd) < 0) { ERRNO_TRACE (errno); goto cleanup; } /* Dump unexpected stuff */ if ((pkt_len - indx) > 0) { if (!(obj_unexpected_data = fiid_obj_create (tmpl_unexpected_data))) { ERRNO_TRACE (errno); goto cleanup; } if ((len = fiid_obj_set_all (obj_unexpected_data, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_unexpected_data); goto cleanup; } indx += len; if (ipmi_obj_dump (fd, prefix, unexpected_hdr, NULL, obj_unexpected_data) < 0) { ERRNO_TRACE (errno); goto cleanup; } } if (debug_output_str (fd, prefix_buf, trlr) < 0) { ERRNO_TRACE (errno); goto cleanup; } #if WITH_RAWDUMPS /* For those vendors that get confused when they see the nice output * and want the hex output */ if (ipmi_dump_hex (fd, prefix, hdr, trlr, pkt, pkt_len) < 0) { ERRNO_TRACE (errno); goto cleanup; } #endif rv = 0; cleanup: fiid_obj_destroy (obj_rmcp_hdr); fiid_obj_destroy (obj_cmd); fiid_obj_destroy (obj_unexpected_data); return (rv); }
/*! * Send message to queue or signal to thread */ int sys__msg_post ( int dest_type, void *dest, msg_t *msg, uint flags ) { thread_t *thr; kthread_t *kthr, *new_kthr; kthrmsg_qs *thrmsg; kgmsg_q *kgmsgq; kmsg_q *kmsgq; msg_q *msgq; kmsg_t *kmsg; msg_t *cmsg; ASSERT_ERRNO_AND_EXIT ( dest && msg, E_INVALID_HANDLE ); if ( dest_type == MSG_THREAD || dest_type == MSG_SIGNAL ) { thr = dest; kthr = k_get_kthread ( thr ); ASSERT_ERRNO_AND_EXIT ( kthr, E_DONT_EXIST ); thrmsg = k_get_thrmsg ( kthr ); kmsgq = &thrmsg->msgq; } else if ( dest_type == MSG_QUEUE ) { msgq = dest; kgmsgq = msgq->handle; ASSERT_ERRNO_AND_EXIT ( kgmsgq && kgmsgq->id == msgq->id, E_INVALID_HANDLE ); kmsgq = &kgmsgq->mq; } else { EXIT ( E_INVALID_TYPE ); } if ( dest_type == MSG_THREAD || dest_type == MSG_QUEUE ) { /* send message to queue */ if ( kmsgq->min_prio <= msg->type ) /* msg has required prio. */ { kmsg = kmalloc ( sizeof (kmsg_t) + msg->size ); ASSERT_ERRNO_AND_EXIT ( kmsg, E_NO_MEMORY ); kmsg->msg.type = msg->type; kmsg->msg.size = msg->size; memcpy ( kmsg->msg.data, msg->data, msg->size ); list_append ( &kmsgq->msgs, kmsg, &kmsg->list ); /* is thread waiting for message? */ if ( k_release_thread ( &kmsgq->thrq ) ) k_schedule_threads (); EXIT ( SUCCESS ); } else { /* ignore message */ EXIT ( E_IGNORED ); } } /* must be MSG_SIGNAL */ if ( thrmsg->sig_prio <= msg->type ) { /* create thread that will service this signal */ cmsg = k_create_thread_private_storage ( kthr, sizeof (msg_t) + msg->size ); cmsg->type = msg->type; cmsg->size = msg->size; memcpy ( cmsg->data, msg->data, msg->size ); new_kthr = k_create_thread ( thrmsg->signal_handler, cmsg, pi.exit, k_get_thread_prio ( kthr ) + 1, NULL, 0, 1 ); ASSERT_ERRNO_AND_EXIT ( new_kthr, k_get_errno() ); k_set_thread_private_storage ( new_kthr, cmsg ); SET_ERRNO ( SUCCESS ); k_schedule_threads (); RETURN ( SUCCESS ); } else { /* ignore signal */ EXIT ( E_IGNORED ); } }
const char *Curl_sspi_strerror (struct connectdata *conn, int err) { #ifndef CURL_DISABLE_VERBOSE_STRINGS char txtbuf[80]; char msgbuf[sizeof(conn->syserr_buf)]; char *p, *str, *msg = NULL; bool msg_formatted = FALSE; int old_errno; #endif const char *txt; char *outbuf; size_t outmax; DEBUGASSERT(conn); outbuf = conn->syserr_buf; outmax = sizeof(conn->syserr_buf)-1; *outbuf = '\0'; #ifndef CURL_DISABLE_VERBOSE_STRINGS old_errno = ERRNO; switch (err) { case SEC_E_OK: txt = "No error"; break; case SEC_E_ALGORITHM_MISMATCH: txt = "SEC_E_ALGORITHM_MISMATCH"; break; case SEC_E_BAD_BINDINGS: txt = "SEC_E_BAD_BINDINGS"; break; case SEC_E_BAD_PKGID: txt = "SEC_E_BAD_PKGID"; break; case SEC_E_BUFFER_TOO_SMALL: txt = "SEC_E_BUFFER_TOO_SMALL"; break; case SEC_E_CANNOT_INSTALL: txt = "SEC_E_CANNOT_INSTALL"; break; case SEC_E_CANNOT_PACK: txt = "SEC_E_CANNOT_PACK"; break; case SEC_E_CERT_EXPIRED: txt = "SEC_E_CERT_EXPIRED"; break; case SEC_E_CERT_UNKNOWN: txt = "SEC_E_CERT_UNKNOWN"; break; case SEC_E_CERT_WRONG_USAGE: txt = "SEC_E_CERT_WRONG_USAGE"; break; case SEC_E_CONTEXT_EXPIRED: txt = "SEC_E_CONTEXT_EXPIRED"; break; case SEC_E_CROSSREALM_DELEGATION_FAILURE: txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE"; break; case SEC_E_CRYPTO_SYSTEM_INVALID: txt = "SEC_E_CRYPTO_SYSTEM_INVALID"; break; case SEC_E_DECRYPT_FAILURE: txt = "SEC_E_DECRYPT_FAILURE"; break; case SEC_E_DELEGATION_POLICY: txt = "SEC_E_DELEGATION_POLICY"; break; case SEC_E_DELEGATION_REQUIRED: txt = "SEC_E_DELEGATION_REQUIRED"; break; case SEC_E_DOWNGRADE_DETECTED: txt = "SEC_E_DOWNGRADE_DETECTED"; break; case SEC_E_ENCRYPT_FAILURE: txt = "SEC_E_ENCRYPT_FAILURE"; break; case SEC_E_ILLEGAL_MESSAGE: txt = "SEC_E_ILLEGAL_MESSAGE"; break; case SEC_E_INCOMPLETE_CREDENTIALS: txt = "SEC_E_INCOMPLETE_CREDENTIALS"; break; case SEC_E_INCOMPLETE_MESSAGE: txt = "SEC_E_INCOMPLETE_MESSAGE"; break; case SEC_E_INSUFFICIENT_MEMORY: txt = "SEC_E_INSUFFICIENT_MEMORY"; break; case SEC_E_INTERNAL_ERROR: txt = "SEC_E_INTERNAL_ERROR"; break; case SEC_E_INVALID_HANDLE: txt = "SEC_E_INVALID_HANDLE"; break; case SEC_E_INVALID_PARAMETER: txt = "SEC_E_INVALID_PARAMETER"; break; case SEC_E_INVALID_TOKEN: txt = "SEC_E_INVALID_TOKEN"; break; case SEC_E_ISSUING_CA_UNTRUSTED: txt = "SEC_E_ISSUING_CA_UNTRUSTED"; break; case SEC_E_ISSUING_CA_UNTRUSTED_KDC: txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC"; break; case SEC_E_KDC_CERT_EXPIRED: txt = "SEC_E_KDC_CERT_EXPIRED"; break; case SEC_E_KDC_CERT_REVOKED: txt = "SEC_E_KDC_CERT_REVOKED"; break; case SEC_E_KDC_INVALID_REQUEST: txt = "SEC_E_KDC_INVALID_REQUEST"; break; case SEC_E_KDC_UNABLE_TO_REFER: txt = "SEC_E_KDC_UNABLE_TO_REFER"; break; case SEC_E_KDC_UNKNOWN_ETYPE: txt = "SEC_E_KDC_UNKNOWN_ETYPE"; break; case SEC_E_LOGON_DENIED: txt = "SEC_E_LOGON_DENIED"; break; case SEC_E_MAX_REFERRALS_EXCEEDED: txt = "SEC_E_MAX_REFERRALS_EXCEEDED"; break; case SEC_E_MESSAGE_ALTERED: txt = "SEC_E_MESSAGE_ALTERED"; break; case SEC_E_MULTIPLE_ACCOUNTS: txt = "SEC_E_MULTIPLE_ACCOUNTS"; break; case SEC_E_MUST_BE_KDC: txt = "SEC_E_MUST_BE_KDC"; break; case SEC_E_NOT_OWNER: txt = "SEC_E_NOT_OWNER"; break; case SEC_E_NO_AUTHENTICATING_AUTHORITY: txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY"; break; case SEC_E_NO_CREDENTIALS: txt = "SEC_E_NO_CREDENTIALS"; break; case SEC_E_NO_IMPERSONATION: txt = "SEC_E_NO_IMPERSONATION"; break; case SEC_E_NO_IP_ADDRESSES: txt = "SEC_E_NO_IP_ADDRESSES"; break; case SEC_E_NO_KERB_KEY: txt = "SEC_E_NO_KERB_KEY"; break; case SEC_E_NO_PA_DATA: txt = "SEC_E_NO_PA_DATA"; break; case SEC_E_NO_S4U_PROT_SUPPORT: txt = "SEC_E_NO_S4U_PROT_SUPPORT"; break; case SEC_E_NO_TGT_REPLY: txt = "SEC_E_NO_TGT_REPLY"; break; case SEC_E_OUT_OF_SEQUENCE: txt = "SEC_E_OUT_OF_SEQUENCE"; break; case SEC_E_PKINIT_CLIENT_FAILURE: txt = "SEC_E_PKINIT_CLIENT_FAILURE"; break; case SEC_E_PKINIT_NAME_MISMATCH: txt = "SEC_E_PKINIT_NAME_MISMATCH"; break; case SEC_E_POLICY_NLTM_ONLY: txt = "SEC_E_POLICY_NLTM_ONLY"; break; case SEC_E_QOP_NOT_SUPPORTED: txt = "SEC_E_QOP_NOT_SUPPORTED"; break; case SEC_E_REVOCATION_OFFLINE_C: txt = "SEC_E_REVOCATION_OFFLINE_C"; break; case SEC_E_REVOCATION_OFFLINE_KDC: txt = "SEC_E_REVOCATION_OFFLINE_KDC"; break; case SEC_E_SECPKG_NOT_FOUND: txt = "SEC_E_SECPKG_NOT_FOUND"; break; case SEC_E_SECURITY_QOS_FAILED: txt = "SEC_E_SECURITY_QOS_FAILED"; break; case SEC_E_SHUTDOWN_IN_PROGRESS: txt = "SEC_E_SHUTDOWN_IN_PROGRESS"; break; case SEC_E_SMARTCARD_CERT_EXPIRED: txt = "SEC_E_SMARTCARD_CERT_EXPIRED"; break; case SEC_E_SMARTCARD_CERT_REVOKED: txt = "SEC_E_SMARTCARD_CERT_REVOKED"; break; case SEC_E_SMARTCARD_LOGON_REQUIRED: txt = "SEC_E_SMARTCARD_LOGON_REQUIRED"; break; case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED: txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED"; break; case SEC_E_TARGET_UNKNOWN: txt = "SEC_E_TARGET_UNKNOWN"; break; case SEC_E_TIME_SKEW: txt = "SEC_E_TIME_SKEW"; break; case SEC_E_TOO_MANY_PRINCIPALS: txt = "SEC_E_TOO_MANY_PRINCIPALS"; break; case SEC_E_UNFINISHED_CONTEXT_DELETED: txt = "SEC_E_UNFINISHED_CONTEXT_DELETED"; break; case SEC_E_UNKNOWN_CREDENTIALS: txt = "SEC_E_UNKNOWN_CREDENTIALS"; break; case SEC_E_UNSUPPORTED_FUNCTION: txt = "SEC_E_UNSUPPORTED_FUNCTION"; break; case SEC_E_UNSUPPORTED_PREAUTH: txt = "SEC_E_UNSUPPORTED_PREAUTH"; break; case SEC_E_UNTRUSTED_ROOT: txt = "SEC_E_UNTRUSTED_ROOT"; break; case SEC_E_WRONG_CREDENTIAL_HANDLE: txt = "SEC_E_WRONG_CREDENTIAL_HANDLE"; break; case SEC_E_WRONG_PRINCIPAL: txt = "SEC_E_WRONG_PRINCIPAL"; break; case SEC_I_COMPLETE_AND_CONTINUE: txt = "SEC_I_COMPLETE_AND_CONTINUE"; break; case SEC_I_COMPLETE_NEEDED: txt = "SEC_I_COMPLETE_NEEDED"; break; case SEC_I_CONTEXT_EXPIRED: txt = "SEC_I_CONTEXT_EXPIRED"; break; case SEC_I_CONTINUE_NEEDED: txt = "SEC_I_CONTINUE_NEEDED"; break; case SEC_I_INCOMPLETE_CREDENTIALS: txt = "SEC_I_INCOMPLETE_CREDENTIALS"; break; case SEC_I_LOCAL_LOGON: txt = "SEC_I_LOCAL_LOGON"; break; case SEC_I_NO_LSA_CONTEXT: txt = "SEC_I_NO_LSA_CONTEXT"; break; case SEC_I_RENEGOTIATE: txt = "SEC_I_RENEGOTIATE"; break; case SEC_I_SIGNATURE_NEEDED: txt = "SEC_I_SIGNATURE_NEEDED"; break; default: txt = "Unknown error"; } if(err == SEC_E_OK) strncpy(outbuf, txt, outmax); else { str = txtbuf; snprintf(txtbuf, sizeof(txtbuf), "%s (0x%04X%04X)", txt, (err >> 16) & 0xffff, err & 0xffff); txtbuf[sizeof(txtbuf)-1] = '\0'; #ifdef _WIN32_WCE { wchar_t wbuf[256]; wbuf[0] = L'\0'; if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) { wcstombs(msgbuf,wbuf,sizeof(msgbuf)-1); msg_formatted = TRUE; } } #else if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, LANG_NEUTRAL, msgbuf, sizeof(msgbuf)-1, NULL)) { msg_formatted = TRUE; } #endif if(msg_formatted) { msgbuf[sizeof(msgbuf)-1] = '\0'; /* strip trailing '\r\n' or '\n' */ if((p = strrchr(msgbuf,'\n')) != NULL && (p - msgbuf) >= 2) *p = '\0'; if((p = strrchr(msgbuf,'\r')) != NULL && (p - msgbuf) >= 1) *p = '\0'; msg = msgbuf; } if(msg) snprintf(outbuf, outmax, "%s - %s", str, msg); else strncpy(outbuf, str, outmax); } if(old_errno != ERRNO) SET_ERRNO(old_errno); #else if(err == SEC_E_OK) txt = "No error"; else txt = "Error"; strncpy(outbuf, txt, outmax); #endif outbuf[outmax] = '\0'; return outbuf; }
/* * init_resolve_thread() starts a new thread that performs the actual * resolve. This function returns before the resolve is done. * * Returns FALSE in case of failure, otherwise TRUE. */ static bool init_resolve_thread (struct connectdata *conn, const char *hostname, int port, const struct addrinfo *hints) { struct thread_data *td = calloc(sizeof(*td), 1); HANDLE thread_and_event[2] = {0}; if (!td) { SET_ERRNO(ENOMEM); return FALSE; } Curl_safefree(conn->async.hostname); conn->async.hostname = strdup(hostname); if (!conn->async.hostname) { free(td); SET_ERRNO(ENOMEM); return FALSE; } conn->async.port = port; conn->async.done = FALSE; conn->async.status = 0; conn->async.dns = NULL; conn->async.os_specific = (void*) td; td->dummy_sock = CURL_SOCKET_BAD; /* Create the mutex used to inform the resolver thread that we're * still waiting, and take initial ownership. */ td->mutex_waiting = CreateMutex(NULL, TRUE, NULL); if (td->mutex_waiting == NULL) { Curl_destroy_thread_data(&conn->async); SET_ERRNO(EAGAIN); return FALSE; } /* Create the event that the thread uses to inform us that it's * done resolving. Do not signal it. */ td->event_resolved = CreateEvent(NULL, TRUE, FALSE, NULL); if (td->event_resolved == NULL) { Curl_destroy_thread_data(&conn->async); SET_ERRNO(EAGAIN); return FALSE; } /* Create the mutex used to serialize access to event_terminated * between us and resolver thread. */ td->mutex_terminate = CreateMutex(NULL, FALSE, NULL); if (td->mutex_terminate == NULL) { Curl_destroy_thread_data(&conn->async); SET_ERRNO(EAGAIN); return FALSE; } /* Create the event used to signal thread that it should terminate. */ td->event_terminate = CreateEvent(NULL, TRUE, FALSE, NULL); if (td->event_terminate == NULL) { Curl_destroy_thread_data(&conn->async); SET_ERRNO(EAGAIN); return FALSE; } /* Create the event used by thread to inform it has initialized its own data. */ td->event_thread_started = CreateEvent(NULL, TRUE, FALSE, NULL); if (td->event_thread_started == NULL) { Curl_destroy_thread_data(&conn->async); SET_ERRNO(EAGAIN); return FALSE; } #ifdef _WIN32_WCE td->thread_hnd = (HANDLE) CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) THREAD_FUNC, conn, 0, &td->thread_id); #else td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, THREAD_FUNC, conn, 0, &td->thread_id); #endif #ifdef CURLRES_IPV6 DEBUGASSERT(hints); td->hints = *hints; #else (void) hints; #endif if (!td->thread_hnd) { #ifndef _WIN32_WCE SET_ERRNO(errno); #endif Curl_destroy_thread_data(&conn->async); return FALSE; } /* Waiting until the thread will initialize its data or it will exit due errors. */ thread_and_event[0] = td->thread_hnd; thread_and_event[1] = td->event_thread_started; if (WaitForMultipleObjects(sizeof(thread_and_event) / sizeof(thread_and_event[0]), (const HANDLE*)thread_and_event, FALSE, INFINITE) == WAIT_FAILED) { /* The resolver thread has been created, * most probably it works now - ignoring this "minor" error */ } /* This socket is only to keep Curl_resolv_fdset() and select() happy; * should never become signalled for read/write since it's unbound but * Windows needs atleast 1 socket in select(). */ td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0); return TRUE; }
int assemble_ipmi_kcs_pkt (fiid_obj_t obj_kcs_hdr, fiid_obj_t obj_cmd, void *pkt, unsigned int pkt_len, unsigned int flags) { int obj_cmd_len, obj_kcs_hdr_len; unsigned int utmp; unsigned int flags_mask = 0; if (!fiid_obj_valid (obj_kcs_hdr) || !fiid_obj_valid (obj_cmd) || !pkt || (flags & ~flags_mask)) { SET_ERRNO (EINVAL); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_kcs_hdr, tmpl_hdr_kcs) < 0) { ERRNO_TRACE (errno); return (-1); } if (FIID_OBJ_PACKET_VALID (obj_kcs_hdr) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_kcs_hdr); return (-1); } if (FIID_OBJ_PACKET_VALID (obj_cmd) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } if ((obj_kcs_hdr_len = fiid_obj_len_bytes (obj_kcs_hdr)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_kcs_hdr); return (-1); } if ((obj_cmd_len = fiid_obj_len_bytes (obj_cmd)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } /* int overflow not possible here */ if (pkt_len < (obj_kcs_hdr_len + obj_cmd_len)) { SET_ERRNO (EMSGSIZE); return (-1); } memset (pkt, 0, pkt_len); if ((obj_kcs_hdr_len = fiid_obj_get_all (obj_kcs_hdr, pkt, pkt_len)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_kcs_hdr); return (-1); } if ((obj_cmd_len = fiid_obj_get_all (obj_cmd, pkt + obj_kcs_hdr_len, pkt_len - obj_kcs_hdr_len)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } utmp = obj_kcs_hdr_len + obj_cmd_len; if (utmp > INT_MAX) { SET_ERRNO (EMSGSIZE); return (-1); } return (obj_kcs_hdr_len + obj_cmd_len); }
void *MIONet_Open (char *pmOpenString) { NetRecord *myNetRecord; char myNetAddr[256]; char myDoc [256]; int myPort; if (!stMDNetInitialized) { ABORT_WITH_ERRNO (E_NET_INIT_FAILED); // Never reaches here } // Allocate the NetRecord myNetRecord = (NetRecord *) malloc (sizeof (NetRecord)); if (myNetRecord == NULL) { SET_ERRNO (E_INSUFFICIENT_MEMORY); return NULL; } // Initialize the entire record to zeroes memset (myNetRecord, 0, sizeof (NetRecord)); // Allocate the socket myNetRecord -> socket = MDIONet_CreateSocket (); if (myNetRecord -> socket == NULL) { free (myNetRecord); return NULL; } // Allocate the socket address myNetRecord -> sockAddr = MDIO_AllocateSockAddr (); if (myNetRecord -> sockAddr == NULL) { free (myNetRecord); return NULL; } // Allocate the buffer myNetRecord -> buf = (BYTE *) malloc(BUFFER_SIZE); if (myNetRecord -> buf == NULL) { MDIONet_CloseSocket (myNetRecord -> socket); free (myNetRecord); SET_ERRNO (E_INSUFFICIENT_MEMORY); return NULL; } memset (myNetRecord -> buf, 128, BUFFER_SIZE); switch (pmOpenString[0]) { case 'C': // Connect to arbitrary port if (MyDoConnect (myNetRecord, pmOpenString + 2, &myPort, myNetAddr)) { MDIO_sprintf (stLastOpenDescription, "Connect to port %d on %s", &myPort, myNetAddr); stLastStreamOpened = myNetRecord; return myNetRecord; } break; case 'A': // Open for accepting a connection on a port if (MyDoOpenForAccept (myNetRecord, pmOpenString + 2, &myPort)) { MDIO_sprintf (stLastOpenDescription, "Accepted connection on port %d", &myPort); stLastStreamOpened = myNetRecord; return myNetRecord; } break; case 'U': // Open a URL for read { if (MyGetURLAddressAndDocument (myNetAddr, myDoc, pmOpenString + 2)) { if (MyDoConnect (myNetRecord, myNetAddr, &myPort, NULL)) { MySendURLGet (myNetRecord, myDoc); if (myPort == 80) { MDIO_sprintf (stLastOpenDescription, "Connect to URL %s", myNetAddr); } else { MDIO_sprintf (stLastOpenDescription, "Connect to URL %s (port %d)", myNetAddr, myPort); } stLastStreamOpened = myNetRecord; return myNetRecord; } } } break; } MDIONet_CloseSocket (myNetRecord -> socket); if (myNetRecord -> sockAddr != NULL) { free (myNetRecord -> sockAddr); } free (myNetRecord -> buf); free (myNetRecord); stLastStreamOpened = NULL; return NULL; } // MIONet_Open
/** * Emulated version of the strtoll function. This extracts a long long * value from the given input string and returns it. */ curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base) { char *end; int is_negative = 0; int overflow; int i; curl_off_t value = 0; curl_off_t newval; /* Skip leading whitespace. */ end = (char*)nptr; while (ISSPACE(end[0])) { end++; } /* Handle the sign, if any. */ if (end[0] == '-') { is_negative = 1; end++; } else if (end[0] == '+') { end++; } else if (end[0] == '\0') { /* We had nothing but perhaps some whitespace -- there was no number. */ if (endptr) { *endptr = end; } return 0; } /* Handle special beginnings, if present and allowed. */ if (end[0] == '0' && end[1] == 'x') { if (base == 16 || base == 0) { end += 2; base = 16; } } else if (end[0] == '0') { if (base == 8 || base == 0) { end++; base = 8; } } /* Matching strtol, if the base is 0 and it doesn't look like * the number is octal or hex, we assume it's base 10. */ if (base == 0) { base = 10; } /* Loop handling digits. */ value = 0; overflow = 0; for (i = get_char(end[0], base); i != -1; end++, i = get_char(end[0], base)) { newval = base * value + i; if (newval < value) { /* We've overflowed. */ overflow = 1; break; } else value = newval; } if (!overflow) { if (is_negative) { /* Fix the sign. */ value *= -1; } } else { if (is_negative) value = CURL_LLONG_MIN; else value = CURL_LLONG_MAX; SET_ERRNO(ERANGE); } if (endptr) *endptr = end; return value; }
int assemble_ipmi_lan_pkt (fiid_obj_t obj_rmcp_hdr, fiid_obj_t obj_lan_session_hdr, fiid_obj_t obj_lan_msg_hdr, fiid_obj_t obj_cmd, const void *authentication_code_data, unsigned int authentication_code_data_len, void *pkt, unsigned int pkt_len, unsigned int flags) { uint8_t authentication_type; uint64_t val; unsigned int indx = 0; int required_len; void *authentication_code_field_ptr = NULL; void *checksum_data_ptr = NULL; void *msg_data_ptr = NULL; void *ipmi_msg_len_ptr = NULL; unsigned int msg_data_count = 0; unsigned int checksum_data_count = 0; uint8_t ipmi_msg_len; fiid_obj_t obj_lan_msg_trlr = NULL; uint8_t pwbuf[IPMI_1_5_MAX_PASSWORD_LENGTH]; uint8_t checksum; int len, rv = -1; unsigned int flags_mask = 0; if (!fiid_obj_valid (obj_rmcp_hdr) || !fiid_obj_valid (obj_lan_session_hdr) || !fiid_obj_valid (obj_lan_msg_hdr) || !fiid_obj_valid (obj_cmd) || (authentication_code_data && authentication_code_data_len > IPMI_1_5_MAX_PASSWORD_LENGTH) || !pkt || (flags & ~flags_mask)) { SET_ERRNO (EINVAL); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_rmcp_hdr, tmpl_rmcp_hdr) < 0) { ERRNO_TRACE (errno); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_session_hdr, tmpl_lan_session_hdr) < 0) { ERRNO_TRACE (errno); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_lan_msg_hdr, tmpl_lan_msg_hdr_rq) < 0) { ERRNO_TRACE (errno); return (-1); } if (FIID_OBJ_PACKET_VALID (obj_rmcp_hdr) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); return (-1); } /* * ipmi_msg_len is calculated in this function, so we can't use * fiid_obj_packet_valid() on obj_lan_session_hdr b/c ipmi_msg_len * is probably not set yet. */ if (FIID_OBJ_PACKET_VALID (obj_lan_msg_hdr) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr); return (-1); } if (FIID_OBJ_PACKET_VALID (obj_cmd) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } if (FIID_OBJ_GET (obj_lan_session_hdr, "authentication_type", &val) < 0) { ERRNO_TRACE (errno); return (-1); } authentication_type = val; if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE && authentication_type != IPMI_AUTHENTICATION_TYPE_MD2 && authentication_type != IPMI_AUTHENTICATION_TYPE_MD5 && authentication_type != IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY) { SET_ERRNO (EINVAL); return (-1); } /* no need for overflow checks, handled w/ _ipmi_lan_pkt_rq_min_size check */ required_len = _ipmi_lan_pkt_rq_min_size (authentication_type, obj_cmd); if (pkt_len < required_len) { SET_ERRNO (EMSGSIZE); return (-1); } memset (pkt, 0, pkt_len); if ((len = fiid_obj_get_all (obj_rmcp_hdr, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); goto cleanup; } indx += len; if ((len = fiid_obj_get_block (obj_lan_session_hdr, "authentication_type", "session_id", pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); goto cleanup; } indx += len; /* authentication_code generated last. Save pointers for later calculation */ if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE) { authentication_code_field_ptr = (pkt + indx); indx += IPMI_1_5_MAX_PASSWORD_LENGTH; } ipmi_msg_len_ptr = (pkt + indx); if ((len = fiid_template_field_len_bytes (tmpl_lan_session_hdr, "ipmi_msg_len")) < 0) { ERRNO_TRACE (errno); goto cleanup; } if (len != 1) { SET_ERRNO (EINVAL); goto cleanup; } indx += len; msg_data_ptr = (pkt + indx); if ((len = fiid_obj_get_block (obj_lan_msg_hdr, "rs_addr", "checksum1", pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr); goto cleanup; } indx += len; msg_data_count += len; checksum_data_ptr = (pkt + indx); if ((len = fiid_obj_get_block (obj_lan_msg_hdr, "rq_addr", "rq_seq", pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_hdr); goto cleanup; } indx += len; msg_data_count += len; checksum_data_count += len; if ((len = fiid_obj_get_all (obj_cmd, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); goto cleanup; } indx += len; msg_data_count += len; checksum_data_count += len; if (!(obj_lan_msg_trlr = fiid_obj_create (tmpl_lan_msg_trlr))) { ERRNO_TRACE (errno); goto cleanup; } checksum = ipmi_checksum (checksum_data_ptr, checksum_data_count); if (fiid_obj_set_all (obj_lan_msg_trlr, &checksum, sizeof (checksum)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr); goto cleanup; } if ((len = fiid_obj_get_all (obj_lan_msg_trlr, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_msg_trlr); goto cleanup; } indx += len; msg_data_count += len; /* ipmi_msg_len done after message length is computed */ ipmi_msg_len = msg_data_count; memcpy (ipmi_msg_len_ptr, &ipmi_msg_len, sizeof (ipmi_msg_len)); /* Auth code must be done last, some authentication like md2 and md5 * require all fields, including checksums, to be calculated * beforehand */ if (authentication_type != IPMI_AUTHENTICATION_TYPE_NONE) { int authentication_len; memset (pwbuf, '\0', IPMI_1_5_MAX_PASSWORD_LENGTH); if ((authentication_len = fiid_obj_field_len_bytes (obj_lan_session_hdr, "authentication_code")) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); goto cleanup; } if (authentication_len) { if (fiid_obj_get_data (obj_lan_session_hdr, "authentication_code", pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); goto cleanup; } memcpy (authentication_code_field_ptr, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); } else { if (authentication_code_data) memcpy (pwbuf, authentication_code_data, authentication_code_data_len); if (authentication_type == IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY) { memcpy (authentication_code_field_ptr, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); } else /* IPMI_AUTHENTICATION_TYPE_MD2 || IPMI_AUTHENTICATION_TYPE_MD5 */ { uint8_t session_id_buf[1024]; uint8_t session_sequence_number_buf[1024]; int session_id_len, session_sequence_number_len; if ((session_id_len = fiid_obj_get_data (obj_lan_session_hdr, "session_id", session_id_buf, 1024)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); goto cleanup; } if ((session_sequence_number_len = fiid_obj_get_data (obj_lan_session_hdr, "session_sequence_number", session_sequence_number_buf, 1024)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_lan_session_hdr); goto cleanup; } if (authentication_type == IPMI_AUTHENTICATION_TYPE_MD2) { md2_t ctx; uint8_t digest[MD2_DIGEST_LENGTH]; assert (IPMI_1_5_MAX_PASSWORD_LENGTH == MD2_DIGEST_LENGTH); md2_init (&ctx); md2_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); md2_update_data (&ctx, session_id_buf, session_id_len); md2_update_data (&ctx, msg_data_ptr, msg_data_count); md2_update_data (&ctx, session_sequence_number_buf, session_sequence_number_len); md2_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); md2_finish (&ctx, digest, MD2_DIGEST_LENGTH); md2_init (&ctx); memcpy (authentication_code_field_ptr, digest, IPMI_1_5_MAX_PASSWORD_LENGTH); secure_memset (digest, '\0', MD2_DIGEST_LENGTH); } else if (authentication_type == IPMI_AUTHENTICATION_TYPE_MD5) { md5_t ctx; uint8_t digest[MD5_DIGEST_LENGTH]; assert (IPMI_1_5_MAX_PASSWORD_LENGTH == MD5_DIGEST_LENGTH); md5_init (&ctx); md5_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); md5_update_data (&ctx, session_id_buf, session_id_len); md5_update_data (&ctx, msg_data_ptr, msg_data_count); md5_update_data (&ctx, session_sequence_number_buf, session_sequence_number_len); md5_update_data (&ctx, pwbuf, IPMI_1_5_MAX_PASSWORD_LENGTH); md5_finish (&ctx, digest, MD5_DIGEST_LENGTH); md5_init (&ctx); memcpy (authentication_code_field_ptr, digest, IPMI_1_5_MAX_PASSWORD_LENGTH); secure_memset (digest, '\0', MD5_DIGEST_LENGTH); } } } } if (indx > INT_MAX) { SET_ERRNO (EMSGSIZE); goto cleanup; } rv = indx; cleanup: if (rv < 0) secure_memset (pkt, '\0', pkt_len); fiid_obj_destroy (obj_lan_msg_trlr); secure_memset (pwbuf, '\0', IPMI_1_5_MAX_PASSWORD_LENGTH); return (rv); }
size_t http_parser_execute (http_parser *parser, const http_parser_settings *settings, const char *data, size_t len) { char c, ch; int8_t unhex_val; const char *p = data, *pe; int64_t to_read; enum state state; enum header_states header_state; uint64_t index = parser->index; uint64_t nread = parser->nread; /* technically we could combine all of these (except for url_mark) into one variable, saving stack space, but it seems more clear to have them separated. */ const char *header_field_mark = 0; const char *header_value_mark = 0; const char *url_mark = 0; /* We're in an error state. Don't bother doing anything. */ if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { return 0; } state = (enum state) parser->state; header_state = (enum header_states) parser->header_state; if (len == 0) { switch (state) { case s_body_identity_eof: CALLBACK2(message_complete); return 0; case s_dead: case s_start_req_or_res: case s_start_res: case s_start_req: return 0; default: SET_ERRNO(HPE_INVALID_EOF_STATE); return 1; } } if (state == s_header_field) header_field_mark = data; if (state == s_header_value) header_value_mark = data; if (state == s_req_path || state == s_req_schema || state == s_req_schema_slash || state == s_req_schema_slash_slash || state == s_req_port || state == s_req_query_string_start || state == s_req_query_string || state == s_req_host || state == s_req_fragment_start || state == s_req_fragment) url_mark = data; for (p=data, pe=data+len; p != pe; p++) { ch = *p; if (PARSING_HEADER(state)) { ++nread; /* Buffer overflow attack */ if (nread > HTTP_MAX_HEADER_SIZE) { SET_ERRNO(HPE_HEADER_OVERFLOW); goto error; } } switch (state) { case s_dead: /* this state is used after a 'Connection: close' message * the parser will error out if it reads another message */ SET_ERRNO(HPE_CLOSED_CONNECTION); goto error; case s_start_req_or_res: { if (ch == CR || ch == LF) break; parser->flags = 0; parser->content_length = -1; CALLBACK2(message_begin); if (ch == 'H') state = s_res_or_resp_H; else { parser->type = HTTP_REQUEST; goto start_req_method_assign; } break; } case s_res_or_resp_H: if (ch == 'T') { parser->type = HTTP_RESPONSE; state = s_res_HT; } else { if (ch != 'E') { SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } parser->type = HTTP_REQUEST; parser->method = HTTP_HEAD; index = 2; state = s_req_method; } break; case s_start_res: { parser->flags = 0; parser->content_length = -1; CALLBACK2(message_begin); switch (ch) { case 'H': state = s_res_H; break; case CR: case LF: break; default: SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } break; } case s_res_H: STRICT_CHECK(ch != 'T'); state = s_res_HT; break; case s_res_HT: STRICT_CHECK(ch != 'T'); state = s_res_HTT; break; case s_res_HTT: STRICT_CHECK(ch != 'P'); state = s_res_HTTP; break; case s_res_HTTP: STRICT_CHECK(ch != '/'); state = s_res_first_http_major; break; case s_res_first_http_major: if (ch < '0' || ch > '9') { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major = ch - '0'; state = s_res_http_major; break; /* major HTTP version or dot */ case s_res_http_major: { if (ch == '.') { state = s_res_first_http_minor; break; } if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major *= 10; parser->http_major += ch - '0'; if (parser->http_major > 999) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* first digit of minor HTTP version */ case s_res_first_http_minor: if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor = ch - '0'; state = s_res_http_minor; break; /* minor HTTP version or end of request line */ case s_res_http_minor: { if (ch == ' ') { state = s_res_first_status_code; break; } if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor *= 10; parser->http_minor += ch - '0'; if (parser->http_minor > 999) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } case s_res_first_status_code: { if (!IS_NUM(ch)) { if (ch == ' ') { break; } SET_ERRNO(HPE_INVALID_STATUS); goto error; } parser->status_code = ch - '0'; state = s_res_status_code; break; } case s_res_status_code: { if (!IS_NUM(ch)) { switch (ch) { case ' ': state = s_res_status; break; case CR: state = s_res_line_almost_done; break; case LF: state = s_header_field_start; break; default: SET_ERRNO(HPE_INVALID_STATUS); goto error; } break; } parser->status_code *= 10; parser->status_code += ch - '0'; if (parser->status_code > 999) { SET_ERRNO(HPE_INVALID_STATUS); goto error; } break; } case s_res_status: /* the human readable status. e.g. "NOT FOUND" * we are not humans so just ignore this */ if (ch == CR) { state = s_res_line_almost_done; break; } if (ch == LF) { state = s_header_field_start; break; } break; case s_res_line_almost_done: STRICT_CHECK(ch != LF); state = s_header_field_start; break; case s_start_req: { if (ch == CR || ch == LF) break; parser->flags = 0; parser->content_length = -1; CALLBACK2(message_begin); if (!IS_ALPHA(ch)) { SET_ERRNO(HPE_INVALID_METHOD); goto error; } start_req_method_assign: parser->method = (enum http_method) 0; index = 1; switch (ch) { case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; case 'D': parser->method = HTTP_DELETE; break; case 'G': parser->method = HTTP_GET; break; case 'H': parser->method = HTTP_HEAD; break; case 'L': parser->method = HTTP_LOCK; break; case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break; case 'N': parser->method = HTTP_NOTIFY; break; case 'O': parser->method = HTTP_OPTIONS; break; case 'P': parser->method = HTTP_POST; /* or PROPFIND or PROPPATCH or PUT or PATCH */ break; case 'R': parser->method = HTTP_REPORT; break; case 'S': parser->method = HTTP_SUBSCRIBE; break; case 'T': parser->method = HTTP_TRACE; break; case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break; default: SET_ERRNO(HPE_INVALID_METHOD); goto error; } state = s_req_method; break; } case s_req_method: { const char *matcher; if (ch == '\0') { SET_ERRNO(HPE_INVALID_METHOD); goto error; } matcher = method_strings[parser->method]; if (ch == ' ' && matcher[index] == '\0') { state = s_req_spaces_before_url; } else if (ch == matcher[index]) { ; /* nada */ } else if (parser->method == HTTP_CONNECT) { if (index == 1 && ch == 'H') { parser->method = HTTP_CHECKOUT; } else if (index == 2 && ch == 'P') { parser->method = HTTP_COPY; } else { goto error; } } else if (parser->method == HTTP_MKCOL) { if (index == 1 && ch == 'O') { parser->method = HTTP_MOVE; } else if (index == 1 && ch == 'E') { parser->method = HTTP_MERGE; } else if (index == 1 && ch == '-') { parser->method = HTTP_MSEARCH; } else if (index == 2 && ch == 'A') { parser->method = HTTP_MKACTIVITY; } else { goto error; } } else if (index == 1 && parser->method == HTTP_POST) { if (ch == 'R') { parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */ } else if (ch == 'U') { parser->method = HTTP_PUT; } else if (ch == 'A') { parser->method = HTTP_PATCH; } else { goto error; } } else if (index == 2 && parser->method == HTTP_UNLOCK && ch == 'S') { parser->method = HTTP_UNSUBSCRIBE; } else if (index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') { parser->method = HTTP_PROPPATCH; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } ++index; break; } case s_req_spaces_before_url: { if (ch == ' ') break; if (ch == '/' || ch == '*') { MARK(url); state = s_req_path; break; } /* Proxied requests are followed by scheme of an absolute URI (alpha). * CONNECT is followed by a hostname, which begins with alphanum. * All other methods are followed by '/' or '*' (handled above). */ if (IS_ALPHA(ch) || (parser->method == HTTP_CONNECT && IS_NUM(ch))) { MARK(url); state = (parser->method == HTTP_CONNECT) ? s_req_host : s_req_schema; break; } SET_ERRNO(HPE_INVALID_URL); goto error; } case s_req_schema: { if (IS_ALPHA(ch)) break; if (ch == ':') { state = s_req_schema_slash; break; } SET_ERRNO(HPE_INVALID_URL); goto error; } case s_req_schema_slash: STRICT_CHECK(ch != '/'); state = s_req_schema_slash_slash; break; case s_req_schema_slash_slash: STRICT_CHECK(ch != '/'); state = s_req_host; break; case s_req_host: { if (IS_HOST_CHAR(ch)) break; switch (ch) { case ':': state = s_req_port; break; case '/': state = s_req_path; break; case ' ': /* The request line looks like: * "GET http://foo.bar.com HTTP/1.1" * That is, there is no path. */ CALLBACK(url); state = s_req_http_start; break; case '?': state = s_req_query_string_start; break; default: SET_ERRNO(HPE_INVALID_HOST); goto error; } break; } case s_req_port: { if (IS_NUM(ch)) break; switch (ch) { case '/': state = s_req_path; break; case ' ': /* The request line looks like: * "GET http://foo.bar.com:1234 HTTP/1.1" * That is, there is no path. */ CALLBACK(url); state = s_req_http_start; break; case '?': state = s_req_query_string_start; break; default: SET_ERRNO(HPE_INVALID_PORT); goto error; } break; } case s_req_path: { if (IS_URL_CHAR(ch)) break; switch (ch) { case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_header_field_start; break; case '?': state = s_req_query_string_start; break; case '#': state = s_req_fragment_start; break; default: SET_ERRNO(HPE_INVALID_PATH); goto error; } break; } case s_req_query_string_start: { if (IS_URL_CHAR(ch)) { state = s_req_query_string; break; } switch (ch) { case '?': break; /* XXX ignore extra '?' ... is this right? */ case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_header_field_start; break; case '#': state = s_req_fragment_start; break; default: SET_ERRNO(HPE_INVALID_QUERY_STRING); goto error; } break; } case s_req_query_string: { if (IS_URL_CHAR(ch)) break; switch (ch) { case '?': /* allow extra '?' in query string */ break; case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_header_field_start; break; case '#': state = s_req_fragment_start; break; default: SET_ERRNO(HPE_INVALID_QUERY_STRING); goto error; } break; } case s_req_fragment_start: { if (IS_URL_CHAR(ch)) { state = s_req_fragment; break; } switch (ch) { case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_header_field_start; break; case '?': state = s_req_fragment; break; case '#': break; default: SET_ERRNO(HPE_INVALID_FRAGMENT); goto error; } break; } case s_req_fragment: { if (IS_URL_CHAR(ch)) break; switch (ch) { case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_major = 0; parser->http_minor = 9; state = s_header_field_start; break; case '?': case '#': break; default: SET_ERRNO(HPE_INVALID_FRAGMENT); goto error; } break; } case s_req_http_start: switch (ch) { case 'H': state = s_req_http_H; break; case ' ': break; default: SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } break; case s_req_http_H: STRICT_CHECK(ch != 'T'); state = s_req_http_HT; break; case s_req_http_HT: STRICT_CHECK(ch != 'T'); state = s_req_http_HTT; break; case s_req_http_HTT: STRICT_CHECK(ch != 'P'); state = s_req_http_HTTP; break; case s_req_http_HTTP: STRICT_CHECK(ch != '/'); state = s_req_first_http_major; break; /* first digit of major HTTP version */ case s_req_first_http_major: if (ch < '1' || ch > '9') { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major = ch - '0'; state = s_req_http_major; break; /* major HTTP version or dot */ case s_req_http_major: { if (ch == '.') { state = s_req_first_http_minor; break; } if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major *= 10; parser->http_major += ch - '0'; if (parser->http_major > 999) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* first digit of minor HTTP version */ case s_req_first_http_minor: if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor = ch - '0'; state = s_req_http_minor; break; /* minor HTTP version or end of request line */ case s_req_http_minor: { if (ch == CR) { state = s_req_line_almost_done; break; } if (ch == LF) { state = s_header_field_start; break; } /* XXX allow spaces after digit? */ if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor *= 10; parser->http_minor += ch - '0'; if (parser->http_minor > 999) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* end of request line */ case s_req_line_almost_done: { if (ch != LF) { SET_ERRNO(HPE_LF_EXPECTED); goto error; } state = s_header_field_start; break; } case s_header_field_start: header_field_start: { if (ch == CR) { state = s_headers_almost_done; break; } if (ch == LF) { /* they might be just sending \n instead of \r\n so this would be * the second \n to denote the end of headers*/ state = s_headers_almost_done; goto headers_almost_done; } c = TOKEN(ch); if (!c) { SET_ERRNO(HPE_INVALID_HEADER_TOKEN); goto error; } MARK(header_field); index = 0; state = s_header_field; switch (c) { case 'c': header_state = h_C; break; case 'p': header_state = h_matching_proxy_connection; break; case 't': header_state = h_matching_transfer_encoding; break; case 'u': header_state = h_matching_upgrade; break; default: header_state = h_general; break; } break; } case s_header_field: { c = TOKEN(ch); if (c) { switch (header_state) { case h_general: break; case h_C: index++; header_state = (c == 'o' ? h_CO : h_general); break; case h_CO: index++; header_state = (c == 'n' ? h_CON : h_general); break; case h_CON: index++; switch (c) { case 'n': header_state = h_matching_connection; break; case 't': header_state = h_matching_content_length; break; default: header_state = h_general; break; } break; /* connection */ case h_matching_connection: index++; if (index > sizeof(CONNECTION)-1 || c != CONNECTION[index]) { header_state = h_general; } else if (index == sizeof(CONNECTION)-2) { header_state = h_connection; } break; /* proxy-connection */ case h_matching_proxy_connection: index++; if (index > sizeof(PROXY_CONNECTION)-1 || c != PROXY_CONNECTION[index]) { header_state = h_general; } else if (index == sizeof(PROXY_CONNECTION)-2) { header_state = h_connection; } break; /* content-length */ case h_matching_content_length: index++; if (index > sizeof(CONTENT_LENGTH)-1 || c != CONTENT_LENGTH[index]) { header_state = h_general; } else if (index == sizeof(CONTENT_LENGTH)-2) { header_state = h_content_length; } break; /* transfer-encoding */ case h_matching_transfer_encoding: index++; if (index > sizeof(TRANSFER_ENCODING)-1 || c != TRANSFER_ENCODING[index]) { header_state = h_general; } else if (index == sizeof(TRANSFER_ENCODING)-2) { header_state = h_transfer_encoding; } break; /* upgrade */ case h_matching_upgrade: index++; if (index > sizeof(UPGRADE)-1 || c != UPGRADE[index]) { header_state = h_general; } else if (index == sizeof(UPGRADE)-2) { header_state = h_upgrade; } break; case h_connection: case h_content_length: case h_transfer_encoding: case h_upgrade: if (ch != ' ') header_state = h_general; break; default: assert(0 && "Unknown header_state"); break; } break; } if (ch == ':') { CALLBACK(header_field); state = s_header_value_start; break; } if (ch == CR) { state = s_header_almost_done; CALLBACK(header_field); break; } if (ch == LF) { CALLBACK(header_field); state = s_header_field_start; break; } SET_ERRNO(HPE_INVALID_HEADER_TOKEN); goto error; } case s_header_value_start: { if (ch == ' ' || ch == '\t') break; MARK(header_value); state = s_header_value; index = 0; if (ch == CR) { CALLBACK(header_value); header_state = h_general; state = s_header_almost_done; break; } if (ch == LF) { CALLBACK(header_value); state = s_header_field_start; break; } c = LOWER(ch); switch (header_state) { case h_upgrade: parser->flags |= F_UPGRADE; header_state = h_general; break; case h_transfer_encoding: /* looking for 'Transfer-Encoding: chunked' */ if ('c' == c) { header_state = h_matching_transfer_encoding_chunked; } else { header_state = h_general; } break; case h_content_length: if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); goto error; } parser->content_length = ch - '0'; break; case h_connection: /* looking for 'Connection: keep-alive' */ if (c == 'k') { header_state = h_matching_connection_keep_alive; /* looking for 'Connection: close' */ } else if (c == 'c') { header_state = h_matching_connection_close; } else { header_state = h_general; } break; default: header_state = h_general; break; } break; } case s_header_value: { if (ch == CR) { CALLBACK(header_value); state = s_header_almost_done; break; } if (ch == LF) { CALLBACK(header_value); goto header_almost_done; } c = LOWER(ch); switch (header_state) { case h_general: break; case h_connection: case h_transfer_encoding: assert(0 && "Shouldn't get here."); break; case h_content_length: if (ch == ' ') break; if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); goto error; } parser->content_length *= 10; parser->content_length += ch - '0'; break; /* Transfer-Encoding: chunked */ case h_matching_transfer_encoding_chunked: index++; if (index > sizeof(CHUNKED)-1 || c != CHUNKED[index]) { header_state = h_general; } else if (index == sizeof(CHUNKED)-2) { header_state = h_transfer_encoding_chunked; } break; /* looking for 'Connection: keep-alive' */ case h_matching_connection_keep_alive: index++; if (index > sizeof(KEEP_ALIVE)-1 || c != KEEP_ALIVE[index]) { header_state = h_general; } else if (index == sizeof(KEEP_ALIVE)-2) { header_state = h_connection_keep_alive; } break; /* looking for 'Connection: close' */ case h_matching_connection_close: index++; if (index > sizeof(CLOSE)-1 || c != CLOSE[index]) { header_state = h_general; } else if (index == sizeof(CLOSE)-2) { header_state = h_connection_close; } break; case h_transfer_encoding_chunked: case h_connection_keep_alive: case h_connection_close: if (ch != ' ') header_state = h_general; break; default: state = s_header_value; header_state = h_general; break; } break; } case s_header_almost_done: header_almost_done: { STRICT_CHECK(ch != LF); state = s_header_value_lws; switch (header_state) { case h_connection_keep_alive: parser->flags |= F_CONNECTION_KEEP_ALIVE; break; case h_connection_close: parser->flags |= F_CONNECTION_CLOSE; break; case h_transfer_encoding_chunked: parser->flags |= F_CHUNKED; break; default: break; } break; } case s_header_value_lws: { if (ch == ' ' || ch == '\t') state = s_header_value_start; else { state = s_header_field_start; goto header_field_start; } break; } case s_headers_almost_done: headers_almost_done: { STRICT_CHECK(ch != LF); if (parser->flags & F_TRAILING) { /* End of a chunked request */ CALLBACK2(message_complete); state = NEW_MESSAGE(); break; } nread = 0; if (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT) { parser->upgrade = 1; } /* Here we call the headers_complete callback. This is somewhat * different than other callbacks because if the user returns 1, we * will interpret that as saying that this message has no body. This * is needed for the annoying case of recieving a response to a HEAD * request. */ if (settings->on_headers_complete) { switch (settings->on_headers_complete(parser)) { case 0: break; case 1: parser->flags |= F_SKIPBODY; break; default: parser->state = state; SET_ERRNO(HPE_CB_headers_complete); return p - data; /* Error */ } } /* Exit, the rest of the connect is in a different protocol. */ if (parser->upgrade) { CALLBACK2(message_complete); return (p - data) + 1; } if (parser->flags & F_SKIPBODY) { CALLBACK2(message_complete); state = NEW_MESSAGE(); } else if (parser->flags & F_CHUNKED) { /* chunked encoding - ignore Content-Length header */ state = s_chunk_size_start; } else { if (parser->content_length == 0) { /* Content-Length header given but zero: Content-Length: 0\r\n */ CALLBACK2(message_complete); state = NEW_MESSAGE(); } else if (parser->content_length > 0) { /* Content-Length header given and non-zero */ state = s_body_identity; } else { if (parser->type == HTTP_REQUEST || http_should_keep_alive(parser)) { /* Assume content-length 0 - read the next */ CALLBACK2(message_complete); state = NEW_MESSAGE(); } else { /* Read body until EOF */ state = s_body_identity_eof; } } } break; } case s_body_identity: to_read = MIN(pe - p, (int64_t)parser->content_length); if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; parser->content_length -= to_read; if (parser->content_length == 0) { CALLBACK2(message_complete); state = NEW_MESSAGE(); } } break; /* read until EOF */ case s_body_identity_eof: to_read = pe - p; if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; } break; case s_chunk_size_start: { assert(nread == 1); assert(parser->flags & F_CHUNKED); unhex_val = unhex[(unsigned char)ch]; if (unhex_val == -1) { SET_ERRNO(HPE_INVALID_CHUNK_SIZE); goto error; } parser->content_length = unhex_val; state = s_chunk_size; break; } case s_chunk_size: { assert(parser->flags & F_CHUNKED); if (ch == CR) { state = s_chunk_size_almost_done; break; } unhex_val = unhex[(unsigned char)ch]; if (unhex_val == -1) { if (ch == ';' || ch == ' ') { state = s_chunk_parameters; break; } SET_ERRNO(HPE_INVALID_CHUNK_SIZE); goto error; } parser->content_length *= 16; parser->content_length += unhex_val; break; } case s_chunk_parameters: { assert(parser->flags & F_CHUNKED); /* just ignore this shit. TODO check for overflow */ if (ch == CR) { state = s_chunk_size_almost_done; break; } break; } case s_chunk_size_almost_done: { assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); nread = 0; if (parser->content_length == 0) { parser->flags |= F_TRAILING; state = s_header_field_start; } else { state = s_chunk_data; } break; } case s_chunk_data: { assert(parser->flags & F_CHUNKED); to_read = MIN(pe - p, (int64_t)(parser->content_length)); if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; } if (to_read == parser->content_length) { state = s_chunk_data_almost_done; } parser->content_length -= to_read; break; } case s_chunk_data_almost_done: assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != CR); state = s_chunk_data_done; break; case s_chunk_data_done: assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); state = s_chunk_size_start; break; default: assert(0 && "unhandled state"); SET_ERRNO(HPE_INVALID_INTERNAL_STATE); goto error; } } #if defined(HTTP_PARSER_USE_RESTART) if (url_mark) return (url_mark - data); if (header_field_mark) return (header_field_mark - data); if (header_value_mark) return (header_value_mark - data); #else CALLBACK(header_field); CALLBACK(header_value); CALLBACK(url); #endif parser->state = state; parser->header_state = header_state; parser->index = index; parser->nread = nread; return len; error: if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { SET_ERRNO(HPE_UNKNOWN); } return (p - data); }
int execlp(const char *file, const char *arg0, ... /*, (char *)0 */) { printk(">>> %s %s %s\n", __func__, file, arg0); return SET_ERRNO(ENOSYS); }
static int ProcessRequest(struct httprequest *req) { char *line=&req->reqbuf[req->checkindex]; bool chunked = FALSE; static char request[REQUEST_KEYWORD_SIZE]; static char doc[MAXDOCNAMELEN]; char logbuf[256]; int prot_major, prot_minor; char *end; int error; end = strstr(line, end_of_headers); logmsg("ProcessRequest() called"); /* try to figure out the request characteristics as soon as possible, but only once! */ if(use_gopher && (req->testno == DOCNUMBER_NOTHING) && !strncmp("/verifiedserver", line, 15)) { logmsg("Are-we-friendly question received"); req->testno = DOCNUMBER_WERULEZ; return 1; /* done */ } else if((req->testno == DOCNUMBER_NOTHING) && sscanf(line, "%" REQUEST_KEYWORD_SIZE_TXT"s %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d", request, doc, &prot_major, &prot_minor) == 4) { char *ptr; req->prot_version = prot_major*10 + prot_minor; /* find the last slash */ ptr = strrchr(doc, '/'); /* get the number after it */ if(ptr) { FILE *stream; char *filename; if((strlen(doc) + strlen(request)) < 200) sprintf(logbuf, "Got request: %s %s HTTP/%d.%d", request, doc, prot_major, prot_minor); else sprintf(logbuf, "Got a *HUGE* request HTTP/%d.%d", prot_major, prot_minor); logmsg("%s", logbuf); if(!strncmp("/verifiedserver", ptr, 15)) { logmsg("Are-we-friendly question received"); req->testno = DOCNUMBER_WERULEZ; return 1; /* done */ } if(!strncmp("/quit", ptr, 5)) { logmsg("Request-to-quit received"); req->testno = DOCNUMBER_QUIT; return 1; /* done */ } ptr++; /* skip the slash */ /* skip all non-numericals following the slash */ while(*ptr && !ISDIGIT(*ptr)) ptr++; req->testno = strtol(ptr, &ptr, 10); if(req->testno > 10000) { req->partno = req->testno % 10000; req->testno /= 10000; } else req->partno = 0; sprintf(logbuf, "Requested test number %ld part %ld", req->testno, req->partno); logmsg("%s", logbuf); filename = test2file(req->testno); stream=fopen(filename, "rb"); if(!stream) { error = ERRNO; logmsg("fopen() failed with error: %d %s", error, strerror(error)); logmsg("Error opening file: %s", filename); logmsg("Couldn't open test file %ld", req->testno); req->open = FALSE; /* closes connection */ return 1; /* done */ } else { char *orgcmd = NULL; char *cmd = NULL; size_t cmdsize = 0; int num=0; /* get the custom server control "commands" */ error = getpart(&orgcmd, &cmdsize, "reply", "servercmd", stream); fclose(stream); if(error) { logmsg("getpart() failed with error: %d", error); req->open = FALSE; /* closes connection */ return 1; /* done */ } cmd = orgcmd; while(cmd && cmdsize) { char *check; if(!strncmp(CMD_AUTH_REQUIRED, cmd, strlen(CMD_AUTH_REQUIRED))) { logmsg("instructed to require authorization header"); req->auth_req = TRUE; } else if(!strncmp(CMD_IDLE, cmd, strlen(CMD_IDLE))) { logmsg("instructed to idle"); req->rcmd = RCMD_IDLE; req->open = TRUE; } else if(!strncmp(CMD_STREAM, cmd, strlen(CMD_STREAM))) { logmsg("instructed to stream"); req->rcmd = RCMD_STREAM; } else if(1 == sscanf(cmd, "pipe: %d", &num)) { logmsg("instructed to allow a pipe size of %d", num); if(num < 0) logmsg("negative pipe size ignored"); else if(num > 0) req->pipe = num-1; /* decrease by one since we don't count the first request in this number */ } else if(1 == sscanf(cmd, "skip: %d", &num)) { logmsg("instructed to skip this number of bytes %d", num); req->skip = num; } else if(1 == sscanf(cmd, "writedelay: %d", &num)) { logmsg("instructed to delay %d secs between packets", num); req->writedelay = num; } else { logmsg("funny instruction found: %s", cmd); } /* try to deal with CRLF or just LF */ check = strchr(cmd, '\r'); if(!check) check = strchr(cmd, '\n'); if(check) { /* get to the letter following the newline */ while((*check == '\r') || (*check == '\n')) check++; if(!*check) /* if we reached a zero, get out */ break; cmd = check; } else break; } if(orgcmd) free(orgcmd); } } else { if(sscanf(req->reqbuf, "CONNECT %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d", doc, &prot_major, &prot_minor) == 3) { sprintf(logbuf, "Received a CONNECT %s HTTP/%d.%d request", doc, prot_major, prot_minor); logmsg("%s", logbuf); if(req->prot_version == 10) req->open = FALSE; /* HTTP 1.0 closes connection by default */ if(!strncmp(doc, "bad", 3)) /* if the host name starts with bad, we fake an error here */ req->testno = DOCNUMBER_BADCONNECT; else if(!strncmp(doc, "test", 4)) { /* if the host name starts with test, the port number used in the CONNECT line will be used as test number! */ char *portp = strchr(doc, ':'); if(portp && (*(portp+1) != '\0') && ISDIGIT(*(portp+1))) req->testno = strtol(portp+1, NULL, 10); else req->testno = DOCNUMBER_CONNECT; } else req->testno = DOCNUMBER_CONNECT; } else { logmsg("Did not find test number in PATH"); req->testno = DOCNUMBER_404; } } } if(!end) { /* we don't have a complete request yet! */ logmsg("ProcessRequest returned without a complete request"); return 0; /* not complete yet */ } logmsg("ProcessRequest found a complete request"); if(use_gopher) { /* when using gopher we cannot check the request until the entire thing has been received */ char *ptr; /* find the last slash in the line */ ptr = strrchr(line, '/'); if(ptr) { ptr++; /* skip the slash */ /* skip all non-numericals following the slash */ while(*ptr && !ISDIGIT(*ptr)) ptr++; req->testno = strtol(ptr, &ptr, 10); if(req->testno > 10000) { req->partno = req->testno % 10000; req->testno /= 10000; } else req->partno = 0; sprintf(logbuf, "Requested GOPHER test number %ld part %ld", req->testno, req->partno); logmsg("%s", logbuf); } } if(req->pipe) /* we do have a full set, advance the checkindex to after the end of the headers, for the pipelining case mostly */ req->checkindex += (end - line) + strlen(end_of_headers); /* **** Persistence **** * * If the request is a HTTP/1.0 one, we close the connection unconditionally * when we're done. * * If the request is a HTTP/1.1 one, we MUST check for a "Connection:" * header that might say "close". If it does, we close a connection when * this request is processed. Otherwise, we keep the connection alive for X * seconds. */ do { if(got_exit_signal) return 1; /* done */ if((req->cl==0) && curlx_strnequal("Content-Length:", line, 15)) { /* If we don't ignore content-length, we read it and we read the whole request including the body before we return. If we've been told to ignore the content-length, we will return as soon as all headers have been received */ char *endptr; char *ptr = line + 15; unsigned long clen = 0; while(*ptr && ISSPACE(*ptr)) ptr++; endptr = ptr; SET_ERRNO(0); clen = strtoul(ptr, &endptr, 10); if((ptr == endptr) || !ISSPACE(*endptr) || (ERANGE == ERRNO)) { /* this assumes that a zero Content-Length is valid */ logmsg("Found invalid Content-Length: (%s) in the request", ptr); req->open = FALSE; /* closes connection */ return 1; /* done */ } req->cl = clen - req->skip; logmsg("Found Content-Length: %lu in the request", clen); if(req->skip) logmsg("... but will abort after %zu bytes", req->cl); break; } else if(curlx_strnequal("Transfer-Encoding: chunked", line, strlen("Transfer-Encoding: chunked"))) { /* chunked data coming in */ chunked = TRUE; } if(chunked) { if(strstr(req->reqbuf, "\r\n0\r\n\r\n")) /* end of chunks reached */ return 1; /* done */ else return 0; /* not done */ } line = strchr(line, '\n'); if(line) line++; } while(line); if(!req->auth && strstr(req->reqbuf, "Authorization:")) { req->auth = TRUE; /* Authorization: header present! */ if(req->auth_req) logmsg("Authorization header found, as required"); } if(!req->digest && strstr(req->reqbuf, "Authorization: Digest")) { /* If the client is passing this Digest-header, we set the part number to 1000. Not only to spice up the complexity of this, but to make Digest stuff to work in the test suite. */ req->partno += 1000; req->digest = TRUE; /* header found */ logmsg("Received Digest request, sending back data %ld", req->partno); } else if(!req->ntlm && strstr(req->reqbuf, "Authorization: NTLM TlRMTVNTUAAD")) { /* If the client is passing this type-3 NTLM header */ req->partno += 1002; req->ntlm = TRUE; /* NTLM found */ logmsg("Received NTLM type-3, sending back data %ld", req->partno); if(req->cl) { logmsg(" Expecting %zu POSTed bytes", req->cl); } } else if(!req->ntlm && strstr(req->reqbuf, "Authorization: NTLM TlRMTVNTUAAB")) { /* If the client is passing this type-1 NTLM header */ req->partno += 1001; req->ntlm = TRUE; /* NTLM found */ logmsg("Received NTLM type-1, sending back data %ld", req->partno); } else if((req->partno >= 1000) && strstr(req->reqbuf, "Authorization: Basic")) { /* If the client is passing this Basic-header and the part number is already >=1000, we add 1 to the part number. This allows simple Basic authentication negotiation to work in the test suite. */ req->partno += 1; logmsg("Received Basic request, sending back data %ld", req->partno); } if(strstr(req->reqbuf, "Connection: close")) req->open = FALSE; /* close connection after this request */ if(!req->pipe && req->open && req->prot_version >= 11 && end && req->reqbuf + req->offset > end + strlen(end_of_headers) && (!strncmp(req->reqbuf, "GET", strlen("GET")) || !strncmp(req->reqbuf, "HEAD", strlen("HEAD")))) { /* If we have a persistent connection, HTTP version >= 1.1 and GET/HEAD request, enable pipelining. */ req->checkindex = (end - req->reqbuf) + strlen(end_of_headers); req->pipelining = TRUE; } while(req->pipe) { if(got_exit_signal) return 1; /* done */ /* scan for more header ends within this chunk */ line = &req->reqbuf[req->checkindex]; end = strstr(line, end_of_headers); if(!end) break; req->checkindex += (end - line) + strlen(end_of_headers); req->pipe--; } /* If authentication is required and no auth was provided, end now. This makes the server NOT wait for PUT/POST data and you can then make the test case send a rejection before any such data has been sent. Test case 154 uses this.*/ if(req->auth_req && !req->auth) return 1; /* done */ if(req->cl > 0) { if(req->cl <= req->offset - (end - req->reqbuf) - strlen(end_of_headers)) return 1; /* done */ else return 0; /* not complete yet */ } return 1; /* done */ }
int ipmi_cipher_suite_id_to_algorithms (uint8_t cipher_suite_id, uint8_t *authentication_algorithm, uint8_t *integrity_algorithm, uint8_t *confidentiality_algorithm) { uint8_t a, i, c; /* To avoid gcc warnings, add +1 to comparison */ if (!((cipher_suite_id + 1) >= 1 && cipher_suite_id <= 19)) { SET_ERRNO (EINVAL); return (-1); } if (cipher_suite_id == 0) a = IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE; else if (cipher_suite_id >= 1 && cipher_suite_id <= 5) a = IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA1; else if (cipher_suite_id >= 6 && cipher_suite_id <= 14) a = IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5; else /* cipher_suite_id >= 15 && cipher_suite_id <= 19 */ a = IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_SHA256; if (cipher_suite_id == 0 || cipher_suite_id == 1 || cipher_suite_id == 6 || cipher_suite_id == 15) i = IPMI_INTEGRITY_ALGORITHM_NONE; else if (cipher_suite_id >= 2 && cipher_suite_id <= 5) i = IPMI_INTEGRITY_ALGORITHM_HMAC_SHA1_96; else if (cipher_suite_id >= 7 && cipher_suite_id <= 10) i = IPMI_INTEGRITY_ALGORITHM_HMAC_MD5_128; else if (cipher_suite_id >= 11 && cipher_suite_id <= 14) i = IPMI_INTEGRITY_ALGORITHM_MD5_128; else /* cipher_suite_id >= 16 && cipher_suite_id <= 19 */ i = IPMI_INTEGRITY_ALGORITHM_HMAC_SHA256_128; if (cipher_suite_id == 0 || cipher_suite_id == 1 || cipher_suite_id == 2 || cipher_suite_id == 6 || cipher_suite_id == 7 || cipher_suite_id == 11 || cipher_suite_id == 15 || cipher_suite_id == 16) c = IPMI_CONFIDENTIALITY_ALGORITHM_NONE; else if (cipher_suite_id == 3 || cipher_suite_id == 8 || cipher_suite_id == 12 || cipher_suite_id == 17) c = IPMI_CONFIDENTIALITY_ALGORITHM_AES_CBC_128; else if (cipher_suite_id == 4 || cipher_suite_id == 9 || cipher_suite_id == 13 || cipher_suite_id == 18) c = IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_128; else /* cipher_suite_id == 5 || cipher_suite_id == 10 || cipher_suite_id == 14 || cipher_suite_id == 19 */ c = IPMI_CONFIDENTIALITY_ALGORITHM_XRC4_40; if (authentication_algorithm) *authentication_algorithm = a; if (integrity_algorithm) *integrity_algorithm = i; if (confidentiality_algorithm) *confidentiality_algorithm = c; return (0); }
BOOL MIOMusic_PlayFile (EventDescriptor *pmEvent, OOTstring pmPath) { char myFilePath[4096]; int myKind; int mySoundID; Sound *mySound; PreLoadFile *myPtr = stPreLoadHead; if (!stAllowSound) { SET_ERRNO(E_MUSIC_DISABLED); return FALSE; } /* File name is "CD" or "CD:<track>" */ if ((strlen (pmPath) >= 2) && (((pmPath [0] == 'c') || (pmPath [0] == 'C')) && ((pmPath [1] == 'd') || (pmPath [1] == 'D')) && ((pmPath [2] == 0) || (pmPath [2] == ':')))) { if (MDIOMusic_FileCDPlay (&pmPath [2], &myKind, &mySoundID)) { mySound = (Sound *) malloc (sizeof (Sound)); mySound -> fileKind = myKind; mySound -> soundID = mySoundID; pmEvent -> mode = EventMode_PlayFileDone; pmEvent -> count = (int) mySound; return TRUE; } } if (!MIOFile_ConvertPath (pmPath, NULL, myFilePath, NO_TRAILING_SLASH)) { return FALSE; } while (myPtr != NULL) { if (stricmp (myPtr -> pathName, myFilePath) == 0) { if (MDIOMusic_PreLoadPlay (myPtr -> mdInfo, &myKind, &mySoundID)) { mySound = (Sound *) malloc (sizeof (Sound)); mySound -> fileKind = myKind; mySound -> soundID = mySoundID; pmEvent -> mode = EventMode_PlayFileDone; pmEvent -> count = (int) mySound; return TRUE; } return FALSE; } myPtr = myPtr -> next; } // while /* File name is <pmPath>.wav */ if (stricmp (".wav", &myFilePath [strlen (myFilePath) - 4]) == 0) { if (MDIOMusic_FileWAVEPlay (myFilePath, &myKind, &mySoundID)) { mySound = (Sound *) malloc (sizeof (Sound)); mySound -> fileKind = myKind; mySound -> soundID = mySoundID; pmEvent -> mode = EventMode_PlayFileDone; pmEvent -> count = (int) mySound; return TRUE; } return FALSE; } /* File name is <pmPath>.mp3 */ if (stricmp (".mp3", &myFilePath [strlen (myFilePath) - 4]) == 0) { if (MDIOMusic_FileMP3Play (myFilePath, &myKind, &mySoundID)) { mySound = (Sound *) malloc (sizeof (Sound)); mySound -> fileKind = myKind; mySound -> soundID = mySoundID; pmEvent -> mode = EventMode_PlayFileDone; pmEvent -> count = (int) mySound; return TRUE; } return FALSE; } /* File name is <pmPath>.mid */ if ((stricmp (".mid", &myFilePath [strlen (myFilePath) - 4]) == 0) || (stricmp (".midi", &myFilePath [strlen (myFilePath) - 5]) == 0)) { if (MDIOMusic_FileMIDIPlay (myFilePath, &myKind, &mySoundID)) { mySound = (Sound *) malloc (sizeof (Sound)); mySound -> fileKind = myKind; mySound -> soundID = mySoundID; pmEvent -> mode = EventMode_PlayFileDone; pmEvent -> count = (int) mySound; return TRUE; } return FALSE; } SET_ERRNO(E_MUSIC_UNKNOWN_FILE_TYPE); return FALSE; } // MIOMusic_PlayFile
static int fuse_operations_mount_fcntl(struct MountsPublicInterface* this_, int fd, int cmd, ...) { ZRT_LOG(L_INFO, "cmd=%s", STR_FCNTL_CMD(cmd)); SET_ERRNO(ENOSYS); return -1; }
static void MyParsePlayString (const OOTstring pmPlayStr, TONE_RECORD pmToneList [], int *pmNumTones) { #define NUM_NOTE_TYPES 6 char *myPtr = pmPlayStr; char myChar; int myNoteInd, myNote; int cnt; static char stMyNoteCode [NUM_NOTE_TYPES] = { '1', '2', '4', '8', '6', '3' }; *pmNumTones = 0; while (*myPtr != 0) { myChar = tolower (*myPtr); if (isdigit (myChar)) { cnt = 0; while ((cnt < NUM_NOTE_TYPES) && (myChar != stMyNoteCode [cnt])) { cnt++; } if (cnt == NUM_NOTE_TYPES) { SET_ERRNO(E_MUSIC_BAD_PLAY_CHAR); } else { stNoteDiv = (1 << cnt); } } else if (('a' <= myChar) && (myChar <= 'g')) { myNoteInd = ((( myChar < 'c' ) ? (myChar - 'a' + 5) : (myChar - 'c'))); myNote = stToneBase [myNoteInd]; // Check for flat or sharp if (*(myPtr + 1) == '-') { myNote--; myPtr++; } else if (*(myPtr + 1) == '+') { myNote++; myPtr++; } // Fill in a tone record pmToneList [*pmNumTones].midiTone = (myNote - 1) + stOctave * 12; pmToneList [*pmNumTones].freq = FREQ_FACTOR / (stToneDivisor [myNote] / ( 1 << stOctave )); pmToneList [*pmNumTones].duration = stWholeNoteDuration / stNoteDiv; pmToneList [*pmNumTones].volume = stVolume; (*pmNumTones)++; } else if (myChar == 'p') { // Fill in a tone record pmToneList [*pmNumTones].midiTone = -1; pmToneList [*pmNumTones].freq = 0; pmToneList [*pmNumTones].duration = stWholeNoteDuration / stNoteDiv; pmToneList [*pmNumTones].volume = 0; (*pmNumTones)++; } else if (myChar == '<') { // Down one octave if (stOctave > 1) { stOctave--; } } else if (myChar == '>') { // Up one octave if (stOctave < 8) { stOctave++; } } else { SET_ERRNO (E_MUSIC_BAD_PLAY_CHAR); } myPtr++; } #undef NUM_NOTE_TYPES } // MyParsePlayString
/* * Our thread-safe and smart strerror() replacement. * * The 'err' argument passed in to this function MUST be a true errno number * as reported on this system. We do no range checking on the number before * we pass it to the "number-to-message" conversion function and there might * be systems that don't do proper range checking in there themselves. * * We don't do range checking (on systems other than Windows) since there is * no good reliable and portable way to do it. */ const char *Curl_strerror(struct connectdata *conn, int err) { char *buf, *p; size_t max; int old_errno = ERRNO; DEBUGASSERT(conn); DEBUGASSERT(err >= 0); buf = conn->syserr_buf; max = sizeof(conn->syserr_buf)-1; *buf = '\0'; #ifdef USE_WINSOCK #ifdef _WIN32_WCE { wchar_t wbuf[256]; wbuf[0] = L'\0'; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL); wcstombs(buf,wbuf,max); } #else /* 'sys_nerr' is the maximum errno number, it is not widely portable */ if(err >= 0 && err < sys_nerr) strncpy(buf, strerror(err), max); else { if(!get_winsock_error(err, buf, max) && !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, LANG_NEUTRAL, buf, (DWORD)max, NULL)) snprintf(buf, max, "Unknown error %d (%#x)", err, err); } #endif #else /* not USE_WINSOCK coming up */ #if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R) /* * The POSIX-style strerror_r() may set errno to ERANGE if insufficient * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated * message string, or EINVAL if 'errnum' is not a valid error number. */ if(0 != strerror_r(err, buf, max)) { if('\0' == buf[0]) snprintf(buf, max, "Unknown error %d", err); } #elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R) /* * The glibc-style strerror_r() only *might* use the buffer we pass to * the function, but it always returns the error message as a pointer, * so we must copy that string unconditionally (if non-NULL). */ { char buffer[256]; char *msg = strerror_r(err, buffer, sizeof(buffer)); if(msg) strncpy(buf, msg, max); else snprintf(buf, max, "Unknown error %d", err); } #elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R) /* * The vxworks-style strerror_r() does use the buffer we pass to the function. * The buffer size should be at least MAXERRSTR_SIZE (150) defined in rtsold.h */ { char buffer[256]; if(OK == strerror_r(err, buffer)) strncpy(buf, buffer, max); else snprintf(buf, max, "Unknown error %d", err); } #else { char *msg = strerror(err); if(msg) strncpy(buf, msg, max); else snprintf(buf, max, "Unknown error %d", err); } #endif #endif /* end of ! USE_WINSOCK */ buf[max] = '\0'; /* make sure the string is zero terminated */ /* strip trailing '\r\n' or '\n'. */ if((p = strrchr(buf,'\n')) != NULL && (p - buf) >= 2) *p = '\0'; if((p = strrchr(buf,'\r')) != NULL && (p - buf) >= 1) *p = '\0'; if(old_errno != ERRNO) SET_ERRNO(old_errno); return buf; }
/* ========================================================================== * select() */ int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { fd_set real_exceptfds, real_readfds, real_writefds; /* mapped fd_sets */ fd_set * real_readfds_p, * real_writefds_p, * real_exceptfds_p; fd_set read_locks, write_locks, rdwr_locks; struct timespec timeout_time, current_time; int i, j, ret = 0, got_all_locks = 1; struct pthread_select_data data; if (numfds > dtablesize) { numfds = dtablesize; } data.nfds = 0; FD_ZERO(&data.readfds); FD_ZERO(&data.writefds); FD_ZERO(&data.exceptfds); /* Do this first */ if (timeout) { machdep_gettimeofday(¤t_time); timeout_time.tv_sec = current_time.tv_sec + timeout->tv_sec; if ((timeout_time.tv_nsec = current_time.tv_nsec + (timeout->tv_usec * 1000)) > 1000000000) { timeout_time.tv_nsec -= 1000000000; timeout_time.tv_sec++; } } FD_ZERO(&read_locks); FD_ZERO(&write_locks); FD_ZERO(&rdwr_locks); FD_ZERO(&real_readfds); FD_ZERO(&real_writefds); FD_ZERO(&real_exceptfds); /* lock readfds */ if (readfds || writefds || exceptfds) { for (i = 0; i < numfds; i++) { if ((readfds && (FD_ISSET(i, readfds))) || (exceptfds && FD_ISSET(i, exceptfds))) { if (writefds && FD_ISSET(i ,writefds)) { if ((ret = fd_lock(i, FD_RDWR, NULL)) != OK) { got_all_locks = 0; break; } FD_SET(i, &rdwr_locks); FD_SET(fd_table[i]->fd.i,&real_writefds); } else { if ((ret = fd_lock(i, FD_READ, NULL)) != OK) { got_all_locks = 0; break; } FD_SET(i, &read_locks); } if (readfds && FD_ISSET(i,readfds)) { FD_SET(fd_table[i]->fd.i, &real_readfds); } if (exceptfds && FD_ISSET(i,exceptfds)) { FD_SET(fd_table[i]->fd.i, &real_exceptfds); } if (fd_table[i]->fd.i >= data.nfds) { data.nfds = fd_table[i]->fd.i + 1; } } else { if (writefds && FD_ISSET(i, writefds)) { if ((ret = fd_lock(i, FD_WRITE, NULL)) != OK) { got_all_locks = 0; break; } FD_SET(i, &write_locks); FD_SET(fd_table[i]->fd.i,&real_writefds); if (fd_table[i]->fd.i >= data.nfds) { data.nfds = fd_table[i]->fd.i + 1; } } } } } if (got_all_locks) { memcpy(&data.readfds,&real_readfds,sizeof(fd_set)); memcpy(&data.writefds,&real_writefds,sizeof(fd_set)); memcpy(&data.exceptfds,&real_exceptfds,sizeof(fd_set)); real_readfds_p = (readfds == NULL) ? NULL : &real_readfds; real_writefds_p = (writefds == NULL) ? NULL : &real_writefds; real_exceptfds_p = (exceptfds == NULL) ? NULL : &real_exceptfds; pthread_run->sighandled=0; if ((ret = machdep_sys_select(data.nfds, real_readfds_p, real_writefds_p, real_exceptfds_p, &zero_timeout)) == OK) { pthread_sched_prevent(); real_exceptfds_p = (exceptfds == NULL) ? NULL : &data.exceptfds; real_writefds_p = (writefds == NULL) ? NULL : &data.writefds; real_readfds_p = (readfds == NULL) ? NULL : &data.readfds; pthread_queue_enq(&fd_wait_select, pthread_run); pthread_run->data.select_data = &data; SET_PF_WAIT_EVENT(pthread_run); if (timeout) { machdep_gettimeofday(¤t_time); sleep_schedule(¤t_time, &timeout_time); SET_PF_AT_CANCEL_POINT(pthread_run); pthread_resched_resume(PS_SELECT_WAIT); CLEAR_PF_AT_CANCEL_POINT(pthread_run); /* We're awake */ if (sleep_cancel(pthread_run) == NOTOK) { ret = OK; } else { int count = 0; for (i = 0; i < numfds; i++) { if (real_readfds_p && (FD_ISSET(i, real_readfds_p))) count++; if (real_writefds_p && (FD_ISSET(i, real_writefds_p))) count++; if (real_exceptfds_p && (FD_ISSET(i, real_exceptfds_p))) count++; } ret = count; } /* Moving this after the sleep_cancel() seemed * to fix intermittent crashes during heavy * socket use. (mevans) */ CLEAR_PF_DONE_EVENT(pthread_run); } else { int count = 0; SET_PF_AT_CANCEL_POINT(pthread_run); pthread_resched_resume(PS_SELECT_WAIT); CLEAR_PF_AT_CANCEL_POINT(pthread_run); CLEAR_PF_DONE_EVENT(pthread_run); for (i = 0; i < numfds; i++) { if (real_readfds_p && (FD_ISSET(i, real_readfds_p))) count++; if (real_writefds_p && (FD_ISSET(i, real_writefds_p))) count++; if (real_exceptfds_p && (FD_ISSET(i, real_exceptfds_p))) count++; } ret = count; } if (pthread_run->sighandled) /* Added by monty */ { /* We where aborted */ ret= NOTOK; SET_ERRNO(EINTR); } } else if (ret < 0) { SET_ERRNO(-ret); ret = NOTOK; } } /* clean up the locks */ for (i = 0; i < numfds; i++) { /* Changed by monty */ if (FD_ISSET(i,&read_locks)) fd_unlock(i,FD_READ); if (FD_ISSET(i,&rdwr_locks)) fd_unlock(i,FD_RDWR); if (FD_ISSET(i,&write_locks)) fd_unlock(i,FD_WRITE); } if (ret > 0) { if (readfds != NULL) { for (i = 0; i < numfds; i++) { if (! (FD_ISSET(i,readfds) && FD_ISSET(fd_table[i]->fd.i,real_readfds_p))) FD_CLR(i,readfds); } } if (writefds != NULL) { for (i = 0; i < numfds; i++) if (! (FD_ISSET(i,writefds) && FD_ISSET(fd_table[i]->fd.i,real_writefds_p))) FD_CLR(i,writefds); } if (exceptfds != NULL) { for (i = 0; i < numfds; i++) if (! (FD_ISSET(i,exceptfds) && FD_ISSET(fd_table[i]->fd.i,real_exceptfds_p))) FD_CLR(i,exceptfds); } } else { if (exceptfds != NULL) FD_ZERO(exceptfds); if (writefds != NULL) FD_ZERO(writefds); if (readfds != NULL) FD_ZERO(readfds); } return(ret); }
int unassemble_rmcp_pkt (const void *pkt, unsigned int pkt_len, fiid_obj_t obj_rmcp_hdr, fiid_obj_t obj_cmd, unsigned int flags) { unsigned int indx = 0; int len; unsigned int flags_mask = (IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK); if (!pkt || !fiid_obj_valid (obj_rmcp_hdr) || !fiid_obj_valid (obj_cmd) || (flags & ~flags_mask)) { SET_ERRNO (EINVAL); return (-1); } if (FIID_OBJ_TEMPLATE_COMPARE (obj_rmcp_hdr, tmpl_rmcp_hdr) < 0) { ERRNO_TRACE (errno); return (-1); } if (fiid_obj_clear (obj_rmcp_hdr) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); return (-1); } if (fiid_obj_clear (obj_cmd) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } if ((len = fiid_obj_set_all (obj_rmcp_hdr, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_rmcp_hdr); return (-1); } indx += len; if (pkt_len <= indx) { /* trace, but don't error out, cannot parse packet */ ERR_TRACE ("malformed packet", EINVAL); return (0); } if ((len = fiid_obj_set_all (obj_cmd, pkt + indx, pkt_len - indx)) < 0) { FIID_OBJECT_ERROR_TO_ERRNO (obj_cmd); return (-1); } indx += len; if (FIID_OBJ_PACKET_VALID (obj_rmcp_hdr) == 1 && ((flags & IPMI_INTERFACE_FLAGS_NO_LEGAL_CHECK) || FIID_OBJ_PACKET_SUFFICIENT (obj_cmd) == 1)) return (1); return (0); }
/* * Convert IPv6 binary address into presentation (printable) format. */ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; char *tp; struct { long base; long len; } best, cur; unsigned long words[IN6ADDRSZ / INT16SZ]; int i; /* Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof(words)); for (i = 0; i < IN6ADDRSZ; i++) words[i/2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; cur.base = -1; best.len = 0; cur.len = 0; for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { if(words[i] == 0) { if(cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else if(cur.base != -1) { if(best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } if((cur.base != -1) && (best.base == -1 || cur.len > best.len)) best = cur; if(best.base != -1 && best.len < 2) best.base = -1; /* Format the result. */ tp = tmp; for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if(best.base != -1 && i >= best.base && i < (best.base + best.len)) { if(i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if(i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ if(i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) { SET_ERRNO(ENOSPC); return (NULL); } tp += strlen(tp); break; } tp += snprintf(tp, 5, "%lx", words[i]); } /* Was it a trailing run of 0x00's? */ if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) *tp++ = ':'; *tp++ = '\0'; /* Check for overflow, copy, and we're done. */ if((size_t)(tp - tmp) > size) { SET_ERRNO(ENOSPC); return (NULL); } strcpy(dst, tmp); return dst; }
/* * static int * inet_net_pton_ipv4(src, dst, size) * convert IPv4 network number from presentation to network format. * accepts hex octets, hex strings, decimal octets, and /CIDR. * "size" is in bytes and describes "dst". * return: * number of bits, either imputed classfully or specified with /CIDR, * or -1 if some failure occurred (check errno). ENOENT means it was * not an IPv4 network specification. * note: * network byte order assumed. this means 192.5.5.240/28 has * 0b11110000 in its fourth octet. * note: * On Windows we store the error in the thread errno, not * in the winsock error code. This is to avoid loosing the * actual last winsock error. So use macro ERRNO to fetch the * errno this funtion sets when returning (-1), not SOCKERRNO. * author: * Paul Vixie (ISC), June 1996 */ static int inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) { static const char xdigits[] = "0123456789abcdef"; static const char digits[] = "0123456789"; int n, ch, tmp = 0, dirty, bits; const unsigned char *odst = dst; ch = *src++; if (ch == '0' && (src[0] == 'x' || src[0] == 'X') && ISXDIGIT(src[1])) { /* Hexadecimal: Eat nybble string. */ if (!size) goto emsgsize; dirty = 0; src++; /* skip x or X. */ while ((ch = *src++) != '\0' && ISXDIGIT(ch)) { if (ISUPPER(ch)) ch = tolower(ch); n = (int)(strchr(xdigits, ch) - xdigits); if (dirty == 0) tmp = n; else tmp = (tmp << 4) | n; if (++dirty == 2) { if (!size--) goto emsgsize; *dst++ = (unsigned char) tmp; dirty = 0; } } if (dirty) { /* Odd trailing nybble? */ if (!size--) goto emsgsize; *dst++ = (unsigned char) (tmp << 4); } } else if (ISDIGIT(ch)) { /* Decimal: eat dotted digit string. */ for (;;) { tmp = 0; do { n = (int)(strchr(digits, ch) - digits); tmp *= 10; tmp += n; if (tmp > 255) goto enoent; } while ((ch = *src++) != '\0' && ISDIGIT(ch)); if (!size--) goto emsgsize; *dst++ = (unsigned char) tmp; if (ch == '\0' || ch == '/') break; if (ch != '.') goto enoent; ch = *src++; if (!ISDIGIT(ch)) goto enoent; } } else goto enoent; bits = -1; if (ch == '/' && ISDIGIT(src[0]) && dst > odst) { /* CIDR width specifier. Nothing can follow it. */ ch = *src++; /* Skip over the /. */ bits = 0; do { n = (int)(strchr(digits, ch) - digits); bits *= 10; bits += n; } while ((ch = *src++) != '\0' && ISDIGIT(ch)); if (ch != '\0') goto enoent; if (bits > 32) goto emsgsize; } /* Firey death and destruction unless we prefetched EOS. */ if (ch != '\0') goto enoent; /* If nothing was written to the destination, we found no address. */ if (dst == odst) goto enoent; /* If no CIDR spec was given, infer width from net class. */ if (bits == -1) { if (*odst >= 240) /* Class E */ bits = 32; else if (*odst >= 224) /* Class D */ bits = 8; else if (*odst >= 192) /* Class C */ bits = 24; else if (*odst >= 128) /* Class B */ bits = 16; else /* Class A */ bits = 8; /* If imputed mask is narrower than specified octets, widen. */ if (bits < ((dst - odst) * 8)) bits = (int)(dst - odst) * 8; /* * If there are no additional bits specified for a class D * address adjust bits to 4. */ if (bits == 8 && *odst == 224) bits = 4; } /* Extend network to cover the actual mask. */ while (bits > ((dst - odst) * 8)) { if (!size--) goto emsgsize; *dst++ = '\0'; } return (bits); enoent: SET_ERRNO(ENOENT); return (-1); emsgsize: SET_ERRNO(EMSGSIZE); return (-1); }
int ipmi_device_type_modifer_message (uint8_t device_type, uint8_t device_modifier, char *buf, unsigned int buflen) { if (!IPMI_DEVICE_TYPE_VALID (device_type) || !buf || !buflen) { SET_ERRNO (EINVAL); return (-1); } switch (device_type) { case IPMI_DEVICE_TYPE_DS1624_TEMPERATURE_SENSOR_EEPROM_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_ds1624_temperature_sensor_eeprom_or_equivalent_max_index, ipmi_device_type_modifier_ds1624_temperature_sensor_eeprom_or_equivalent)); case IPMI_DEVICE_TYPE_DS1621_TEMPERATURE_SENSOR_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_ds1621_temperature_sensor_eeprom_or_equivalent_max_index, ipmi_device_type_modifier_ds1621_temperature_sensor_eeprom_or_equivalent)); case IPMI_DEVICE_TYPE_LM75_TEMPERATURE_SENSOR_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_lm75_temperature_sensor_eeprom_or_equivalent_max_index, ipmi_device_type_modifier_lm75_temperature_sensor_eeprom_or_equivalent)); case IPMI_DEVICE_TYPE_HECETA_ASIC_OR_SIMILAR: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_heceta_asic_or_similar_max_index, ipmi_device_type_modifier_heceta_asic_or_similar)); case IPMI_DEVICE_TYPE_EEPROM_24C01_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_eeprom_24c01_or_equivalent_max_index, ipmi_device_type_modifier_eeprom_24c01_or_equivalent)); case IPMI_DEVICE_TYPE_EEPROM_24C02_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_eeprom_24c02_or_equivalent_max_index, ipmi_device_type_modifier_eeprom_24c02_or_equivalent)); case IPMI_DEVICE_TYPE_EEPROM_24C04_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_eeprom_24c04_or_equivalent_max_index, ipmi_device_type_modifier_eeprom_24c04_or_equivalent)); case IPMI_DEVICE_TYPE_EEPROM_24C08_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_eeprom_24c08_or_equivalent_max_index, ipmi_device_type_modifier_eeprom_24c08_or_equivalent)); case IPMI_DEVICE_TYPE_EEPROM_24C16_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_eeprom_24c16_or_equivalent_max_index, ipmi_device_type_modifier_eeprom_24c16_or_equivalent)); case IPMI_DEVICE_TYPE_EEPROM_24C17_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_eeprom_24c17_or_equivalent_max_index, ipmi_device_type_modifier_eeprom_24c17_or_equivalent)); case IPMI_DEVICE_TYPE_EEPROM_24C32_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_eeprom_24c32_or_equivalent_max_index, ipmi_device_type_modifier_eeprom_24c32_or_equivalent)); case IPMI_DEVICE_TYPE_EEPROM_24C64_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_eeprom_24c64_or_equivalent_max_index, ipmi_device_type_modifier_eeprom_24c64_or_equivalent)); case IPMI_DEVICE_TYPE_FRU_INVENTORY_DEVICE_BEHIND_MANAGEMENT_CONTROLLER: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_fru_inventory_device_behind_management_controller_max_index, ipmi_device_type_modifier_fru_inventory_device_behind_management_controller)); case IPMI_DEVICE_TYPE_PCF_8570_256_BYTE_RAM_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_pcf_8570_256_byte_ram_or_equivalent_max_index, ipmi_device_type_modifier_pcf_8570_256_byte_ram_or_equivalent)); case IPMI_DEVICE_TYPE_PCF_8573_CLOCK_CALENDAR_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_pcf_8573_clock_calendar_or_equivalent_max_index, ipmi_device_type_modifier_pcf_8573_clock_calendar_or_equivalent)); case IPMI_DEVICE_TYPE_PCF_8574A_IO_PORT_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_pcf_8574a_io_port_or_equivalent_max_index, ipmi_device_type_modifier_pcf_8574a_io_port_or_equivalent)); case IPMI_DEVICE_TYPE_PCF_8583_CLOCK_CALENDAR_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_pcf_8583_clock_calendar_or_equivalent_max_index, ipmi_device_type_modifier_pcf_8583_clock_calendar_or_equivalent)); case IPMI_DEVICE_TYPE_PCF_8593_CLOCK_CALENDAR_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_pcf_8593_clock_calendar_or_equivalent_max_index, ipmi_device_type_modifier_pcf_8593_clock_calendar_or_equivalent)); case IPMI_DEVICE_TYPE_CLOCK_CALENDAR_TYPE_NOT_SPECIFIED: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_clock_calendar_type_not_specified_max_index, ipmi_device_type_modifier_clock_calendar_type_not_specified)); case IPMI_DEVICE_TYPE_PCF_8591_AD_DA_CONVERTER_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_pcf_8591_ad_da_converter_or_equivalent_max_index, ipmi_device_type_modifier_pcf_8591_ad_da_converter_or_equivalent)); case IPMI_DEVICE_TYPE_IO_PORT_SPECIFIC_DEVICE_NOT_SPECIFIED: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_io_port_specific_device_not_specified_max_index, ipmi_device_type_modifier_io_port_specific_device_not_specified)); case IPMI_DEVICE_TYPE_AD_CONVERTER_SPECIFIC_DEVICE_NOT_SPECIFIED: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_ad_converter_specific_device_not_specified_max_index, ipmi_device_type_modifier_ad_converter_specific_device_not_specified)); case IPMI_DEVICE_TYPE_DA_CONVERTER_SPECIFIC_DEVICE_NOT_SPECIFIED: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_da_converter_specific_device_not_specified_max_index, ipmi_device_type_modifier_da_converter_specific_device_not_specified)); case IPMI_DEVICE_TYPE_AD_DA_CONVERTER_SPECIFIC_DEVICE_NOT_SPECIFIED: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_ad_da_converter_specific_device_not_specified_max_index, ipmi_device_type_modifier_ad_da_converter_specific_device_not_specified)); case IPMI_DEVICE_TYPE_LCD_CONTROLLER_DRIVER_SPECIFIC_DEVICE_NOT_SPECIFIED: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_lcd_controller_driver_specific_device_not_specified_max_index, ipmi_device_type_modifier_lcd_controller_driver_specific_device_not_specified)); case IPMI_DEVICE_TYPE_CORE_LOGIC_DEVICE_SPECIFIC_DEVICE_NOT_SPECIFIED: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_core_logic_device_specific_device_not_specified_max_index, ipmi_device_type_modifier_core_logic_device_specific_device_not_specified)); case IPMI_DEVICE_TYPE_LMC6874_INTELLIGENT_BATTERY_CONTROLLER_OR_EQUIVALENT: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_lmc6874_intelligent_battery_controller_or_equivalent_max_index, ipmi_device_type_modifier_lmc6874_intelligent_battery_controller_or_equivalent)); case IPMI_DEVICE_TYPE_INTELLIGENT_BATTERY_CONTROLLER_SPECIFIC_DEVICE_NOT_SPECIFIED: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_intelligent_battery_controller_specific_device_not_specified_max_index, ipmi_device_type_modifier_intelligent_battery_controller_specific_device_not_specified)); case IPMI_DEVICE_TYPE_COMBO_MANAGEMENT_ASIC_SPECIFIC_DEVICE_NOT_SPECIFIED: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_combo_management_asic_specific_device_not_specified_max_index, ipmi_device_type_modifier_combo_management_asic_specific_device_not_specified)); case IPMI_DEVICE_TYPE_MAXIM_1617_TEMPERATURE_SENSOR: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_maxim_1617_temperature_sensor_max_index, ipmi_device_type_modifier_maxim_1617_temperature_sensor)); case IPMI_DEVICE_TYPE_OTHER_UNSPECIFIED_DEVICE: return (_get_message (device_modifier, buf, buflen, ipmi_device_type_modifier_other_unspecified_device_max_index, ipmi_device_type_modifier_other_unspecified_device)); } SET_ERRNO (EINVAL); return (-1); }