summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Troy <dave@popvox.com>2006-04-01 16:12:53 +0000
committerDavid Troy <dave@popvox.com>2006-04-01 16:12:53 +0000
commit5042462dccba27c667f02d9998176bd56534a86e (patch)
tree7148ce9aa7189fd9ae8e76de041e890aeaf4d7f3
parent3bc897e904c4c2f4412ec13de1de11aae4a3fb8f (diff)
downloadastmanproxy-5042462dccba27c667f02d9998176bd56534a86e.tar.gz
astmanproxy-5042462dccba27c667f02d9998176bd56534a86e.tar.xz
astmanproxy-5042462dccba27c667f02d9998176bd56534a86e.zip
Populating trunk
git-svn-id: http://svncommunity.digium.com/svn/astmanproxy/trunk@10 f02b47b9-160a-0410-81a6-dc3441afb0ec
-rw-r--r--common.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/common.c b/common.c
new file mode 100644
index 0000000..5f63c15
--- /dev/null
+++ b/common.c
@@ -0,0 +1,147 @@
+#include "astmanproxy.h"
+
+/* This routine based on get_input from Asterisk manager.c */
+/* Good generic line-based input routine for \r\n\r\n terminated input */
+/* Used by standard.c and other input handlers */
+int get_input(struct mansession *s, char *output)
+{
+ /* output must have at least sizeof(s->inbuf) space */
+ int res;
+ int x;
+ struct pollfd fds[1];
+ char iabuf[INET_ADDRSTRLEN];
+
+ debugmsg("in get_input");
+
+ /* Look for \r\n from the front, our preferred end of line */
+ for (x=0;x<s->inlen;x++) {
+ int xtra = 0;
+ if (s->inbuf[x] == '\n') {
+ if (x && s->inbuf[x-1] == '\r') {
+ xtra = 1;
+ }
+ /* Copy output data not including \r\n */
+ memcpy(output, s->inbuf, x - xtra);
+ /* Add trailing \0 */
+ output[x-xtra] = '\0';
+ /* Move remaining data back to the front */
+ memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x);
+ s->inlen -= (x + 1);
+ return 1;
+ }
+ }
+
+ if (s->inlen >= sizeof(s->inbuf) - 1) {
+ if (debug)
+ debugmsg("Warning: Got long line with no end from %s: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr), s->inbuf);
+ s->inlen = 0;
+ }
+ debugmsg("attempting poll operation");
+ fds[0].fd = s->fd;
+ fds[0].events = POLLIN;
+ res = poll(fds, 1, -1);
+ debugmsg("returned from poll op");
+ if (res < 0 && debug) {
+ debugmsg("Select returned error");
+ } else if (res > 0) {
+ pthread_mutex_lock(&s->lock);
+ debugmsg("attempting socket read in get_input...");
+ res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
+ pthread_mutex_unlock(&s->lock);
+ if (res < 1)
+ return -1;
+ }
+ s->inlen += res;
+ s->inbuf[s->inlen] = '\0';
+ return 0;
+ /* We have some input, but it's not ready for processing */
+}
+
+char *astman_get_header(struct message *m, char *var)
+{
+ char cmp[80];
+ int x;
+ snprintf(cmp, sizeof(cmp), "%s: ", var);
+ for (x=0;x<m->hdrcount;x++)
+ if (!strncasecmp(cmp, m->headers[x], strlen(cmp)))
+ return m->headers[x] + strlen(cmp);
+ return "";
+}
+
+int AddHeader(struct message *m, const char *fmt, ...) {
+ va_list ap;
+
+ int res;
+
+ if (m->hdrcount < MAX_HEADERS - 1) {
+ va_start(ap, fmt);
+ vsprintf(m->headers[m->hdrcount], fmt, ap);
+ va_end(ap);
+ m->hdrcount++;
+ res = 0;
+ } else
+ res = 1;
+
+ return res;
+}
+
+/* Recursive thread safe replacement of inet_ntoa */
+const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia)
+{
+ return inet_ntop(AF_INET, &ia, buf, bufsiz);
+}
+
+
+int connect_nonb(int sockfd, const struct sockaddr *saptr, socklen_t salen, int nsec)
+{
+ int flags, n, error;
+ socklen_t len;
+ fd_set rset, wset;
+ struct timeval tval;
+
+ flags = fcntl(sockfd, F_GETFL, 0);
+ fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+
+ error = 0;
+ if ( (n = connect(sockfd, (struct sockaddr *) saptr, salen)) < 0)
+ if (errno != EINPROGRESS)
+ return(-1);
+
+ /* Do whatever we want while the connect is taking place. */
+
+ if (n == 0)
+ goto done; /* connect completed immediately */
+
+ FD_ZERO(&rset);
+ FD_SET(sockfd, &rset);
+ wset = rset;
+ tval.tv_sec = nsec;
+ tval.tv_usec = 0;
+
+ if ( (n = select(sockfd+1, &rset, &wset, NULL,
+ nsec ? &tval : NULL)) == 0) {
+ /*close(sockfd);*/ /* we want to retry */
+ errno = ETIMEDOUT;
+ return(-1);
+ }
+
+ if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
+ len = sizeof(error);
+ if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
+ return(-1); /* Solaris pending error */
+ } else {
+ /*err_quit("select error: sockfd not set");*/
+ logmsg("select error: sockfd not set");
+ return(-1);
+ }
+
+done:
+ fcntl(sockfd, F_SETFL, flags); /* restore file status flags */
+
+ if (error) {
+ /* close(sockfd); */ /* disable for now, we want to retry... */
+ errno = error;
+ return(-1);
+ }
+ return(0);
+}