kamunix.c

00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2004 FhG FOKUS
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <unistd.h>
00027 #include <stdlib.h>
00028 #include <sys/stat.h>
00029 #include <sys/types.h>
00030 #include <sys/socket.h>
00031 #include <sys/un.h>
00032 #include <errno.h>
00033 
00034 
00035 /* AF_LOCAL is not defined on solaris */
00036 #if !defined(AF_LOCAL)
00037 #define AF_LOCAL AF_UNIX
00038 #endif
00039 #if !defined(PF_LOCAL)
00040 #define PF_LOCAL PF_UNIX
00041 #endif
00042 
00043 
00044 /* solaris doesn't have SUN_LEN */
00045 #ifndef SUN_LEN
00046 #define SUN_LEN(sa)      ( strlen((sa)->sun_path) + \
00047                                          (size_t)(((struct sockaddr_un*)0)->sun_path) )
00048 #endif
00049 
00050 
00051 #define BUF_SIZE 65536
00052 #define DEFAULT_TIMEOUT 5
00053 
00054 int main(int argc, char** argv)
00055 {
00056         int sock, len;
00057         socklen_t from_len;
00058         struct sockaddr_un from, to;
00059         char name[256];
00060         static char buffer[BUF_SIZE];
00061         char *chroot_dir;
00062 
00063         if (argc != 2) {
00064                 printf("Usage: %s <path_to_socket>\n", argv[0]);
00065                 return 1;
00066         }
00067 
00068         sock = socket(PF_LOCAL, SOCK_DGRAM, 0);
00069         if (sock == -1) {
00070                 fprintf(stderr, "Error while opening socket: %s\n", strerror(errno));
00071                 return -1;
00072         }
00073         
00074         memset(&from, 0, sizeof(from));
00075         from.sun_family = PF_LOCAL;
00076 
00077         chroot_dir = getenv("CHROOT_DIR");
00078         if (chroot_dir == NULL)
00079                 chroot_dir = "";
00080         sprintf(name, "%s/tmp/Kamailio.%d.XXXXXX", chroot_dir, getpid());
00081         umask(0); /* set mode to 0666 for when Kamailio is running as non-root user and kamctl is running as root */
00082 
00083         if (mkstemp(name) == -1) {
00084                 fprintf(stderr, "Error in mkstemp with name=%s: %s\n", name, strerror(errno));
00085                 return -2;
00086         }
00087         if (unlink(name) == -1) {
00088                 fprintf(stderr, "Error in unlink of %s: %s\n", name, strerror(errno));
00089                 return -2;
00090         }
00091         strncpy(from.sun_path, name, strlen(name));
00092 
00093         if (bind(sock, (struct sockaddr*)&from, SUN_LEN(&from)) == -1) {
00094                 fprintf(stderr, "Error in bind: %s\n", strerror(errno));
00095                 goto err;
00096         }
00097 
00098         memset(&to, 0, sizeof(to));
00099         to.sun_family = PF_LOCAL;
00100         strncpy(to.sun_path, argv[1], sizeof(to.sun_path) - 1);
00101         
00102         len = fread(buffer, 1, BUF_SIZE, stdin);
00103 
00104         if (len) {
00105                 if (sendto(sock, buffer, len, 0, (struct sockaddr*)&to, SUN_LEN(&to)) == -1) {
00106                         fprintf(stderr, "Error in sendto: %s\n", strerror(errno));
00107                         goto err;
00108                 }
00109                 from_len = sizeof(from);
00110                 len = recvfrom(sock, buffer, BUF_SIZE, 0, (struct sockaddr*)&from, &from_len);
00111                 if (len == -1) {
00112                         fprintf(stderr, "Error in recvfrom: %s\n", strerror(errno));
00113                         goto err;
00114                 }
00115 
00116                 fprintf(stdout, "%.*s", len, buffer);
00117         } else {
00118                 fprintf(stderr, "Nothing to send\n");
00119                 goto err;
00120         }
00121 
00122         close(sock);
00123         if (unlink(name) == -1)
00124                 fprintf(stderr, "Error in unlink of %s: %s\n", name, strerror(errno));
00125         return 0;
00126 
00127  err:
00128         close(sock);
00129         if (unlink(name) == -1)
00130                 fprintf(stderr, "Error in unlink of %s: %s\n", name, strerror(errno));
00131         return -1;
00132 }