/* * utils.c * * Code that is generally useful, but I'm not sure where to stick yet. * * Copyright (c) 2004 Todd MacDermid * Kathy Wang * */ #include #include #include #include #include #include #include #include #include /* * cutlass_time is currently a pretty thin wrapper around gettimeofday. * As we run across platforms that don't support such a thing, we may * need to add functionality and define things around a bit. * * returns 0 on success, -1 on failure. */ int cutlass_time(struct timespec *now) { struct timeval tmp; if(gettimeofday(&tmp, NULL) < 0) return(-1); now->tv_sec = tmp.tv_sec; now->tv_nsec = tmp.tv_usec * 1000; return(0); } /* * cutlass_time_check will compare "now" and "last," and determine if the * elapsed time between the two is greater than "diff." If it is, it * will leave "remaining" unchanged, and return 1. If the time elapsed * has been less than "diff," it will return 0, and set "remaining" to * either the remaining time before we exceed "diff," or leave * "remaining" unchanged, whichever would leave "remaining" with a lower * value. * * Returns 0 or 1 on success (see above), -1 on failure. */ int cutlass_time_check(const struct timespec *now, const struct timespec *last, const struct timespec *diff, struct timespec *remaining) { struct timespec tmp; struct timespec tmp_remaining; if(diff->tv_sec >= now->tv_sec) { fprintf(stderr, "cutlass_time_check: specified differential is out-of-bounds\n"); return(-1); } tmp.tv_sec = now->tv_sec - diff->tv_sec; if(now->tv_nsec < diff->tv_nsec) { tmp.tv_sec--; tmp.tv_nsec = 1000000000 + now->tv_nsec - diff->tv_nsec; } else { tmp.tv_nsec = now->tv_nsec - diff->tv_nsec; } if(tmp.tv_sec > last->tv_sec) return(1); tmp_remaining.tv_sec = last->tv_sec - tmp.tv_sec; if(tmp.tv_nsec > last->tv_nsec) { if(tmp_remaining.tv_sec == 0) { return(1); } else { tmp_remaining.tv_sec--; tmp_remaining.tv_nsec = 1000000000 + last->tv_nsec - tmp.tv_nsec; } } else { tmp_remaining.tv_nsec = last->tv_nsec - tmp.tv_nsec; } if(remaining != NULL) { if(tmp_remaining.tv_sec < remaining->tv_sec) { memcpy(remaining, &tmp_remaining, sizeof(struct timespec)); } else if (tmp_remaining.tv_sec == remaining->tv_sec) { if(tmp_remaining.tv_nsec < remaining->tv_nsec) { memcpy(remaining, &tmp_remaining, sizeof(struct timespec)); } } } return(0); } int cutlass_hdr_unpack(uint8_t *packet, uint8_t *cut_type, uint8_t *stream_id, uint16_t *length) { uint8_t *tmp_ptr; if(packet == NULL) { fprintf(stderr, "cutlass_hdr_unpack: packet pointer was NULL\n"); return(-1); } tmp_ptr = packet; if(cut_type != NULL) { *cut_type = *tmp_ptr; } tmp_ptr++; if(stream_id != NULL) { *stream_id = *tmp_ptr; } tmp_ptr++; if(length != NULL) { *length = ntohs(*((uint16_t *)tmp_ptr)); } tmp_ptr += sizeof(uint16_t); return(0); } void cutlass_shutdown_all(cutlass_t *cut_handle) { uint8_t conn_array[CUT_HK_ARRAY_SZ * CUT_ID_LEN]; uint8_t *array_loc; int i; int num_conn; struct timespec begin; struct timespec delay; struct timespec now; struct timespec timeout; delay.tv_sec = 0; delay.tv_nsec = 100000000; timeout.tv_sec = CUT_SHUTDOWN_GRACE; timeout.tv_nsec = 0; cutlass_time(&begin); cutlass_audio_shutdown(cut_handle); while((num_conn = cutlass_conn_list(cut_handle, conn_array, CUT_HK_ARRAY_SZ)) > 0) { array_loc = conn_array; cutlass_time(&now); for(i = 0; i < num_conn; i++) { cutlass_conn_shutdown(cut_handle, array_loc); array_loc += CUT_ID_LEN; } if(cutlass_time_check(&now, &begin, &timeout, &delay) == 1) break; nanosleep(&delay, NULL); } pthread_mutex_lock(&(cut_handle->handle_mutex)); cut_handle->running_state = 0; cutlass_crypto_shutdown(); hdestroy(cut_handle->connections); hdestroy(cut_handle->directory); hdestroy(cut_handle->groups); close(cut_handle->listen_socket); /* The below causes a segfault, and I don't know why! */ /* delete_options(cut_handle->user_opts); */ pthread_mutex_unlock(&(cut_handle->handle_mutex)); return; } const char * cutlass_ntop(int addr_family, void *src, char *dst, socklen_t cnt) { #ifdef HAVE_INET_NTOP return(inet_ntop(addr_family, src, dst, cnt)); #else struct in_addr tmp_addr; memcpy(&tmp_addr, src, sizeof(struct in_addr)); return(inet_ntoa(tmp_addr)); #endif } int cutlass_pton(int addr_family, char *src, void *dst) { #ifdef HAVE_INET_NTOP return(inet_pton(addr_family, src, dst)); #else return(inet_aton(src, dst)); #endif }