summaryrefslogtreecommitdiff
path: root/sockets.c
diff options
context:
space:
mode:
Diffstat (limited to 'sockets.c')
-rw-r--r--sockets.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/sockets.c b/sockets.c
new file mode 100644
index 0000000..5a9bb15
--- /dev/null
+++ b/sockets.c
@@ -0,0 +1,230 @@
+/********************************
+this file was taken from the
+LCDproc source see
+http://lcdproc.omnipotent.net/
+for more info.
+*********************************/
+
+#include <unistd.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include "sockets.h"
+
+/**************************************************
+ LCDproc client sockets code...
+
+ Feel free to use this in your own clients... :)
+**************************************************/
+
+// Length of longest transmission allowed at once...
+#define MAXMSG 8192
+
+typedef struct sockaddr_in sockaddr_in;
+
+static int
+sock_init_sockaddr (sockaddr_in * name, const char *hostname, unsigned short int port)
+{
+ struct hostent *hostinfo;
+
+ name->sin_family = AF_INET;
+ name->sin_port = htons (port);
+ hostinfo = gethostbyname (hostname);
+ if (hostinfo == NULL) {
+ fprintf (stderr, "sock_init_sockaddr: Unknown host %s.\n", hostname);
+ return -1;
+ }
+ name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
+
+ return 0;
+
+}
+
+ // Client functions...
+int
+sock_connect (char *host, unsigned short int port)
+{
+ struct sockaddr_in servername;
+ int sock;
+ int err = 0;
+
+ //debug ("sock_connect: Creating socket\n");
+ sock = socket (PF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ perror ("sock_connect: Error creating socket");
+ return sock;
+ }
+ //debug ("sock_connect: Created socket (%i)\n", sock);
+
+ sock_init_sockaddr (&servername, host, port);
+
+ err = connect (sock, (struct sockaddr *) &servername, sizeof (servername));
+ if (err < 0) {
+ perror ("sock_connect: connect failed");
+ shutdown (sock, 2);
+ return 0; // Normal exit if server doesn't exist...
+ }
+
+ fcntl (sock, F_SETFL, O_NONBLOCK);
+
+ return sock;
+}
+
+int
+sock_close (int fd)
+{
+ int err;
+
+ err = shutdown (fd, 2);
+ if (!err)
+ close (fd);
+
+ return err;
+}
+
+// Send/receive lines of text
+int
+sock_send_string (int fd, char *string)
+{
+ int len;
+ int offset = 0;
+
+ if (!string)
+ return -1;
+
+ len = strlen (string) ;
+ while (offset != len) {
+ // write isn't guaranteed to send the entire string at once,
+ // so we have to sent it in a loop like this
+ int sent = write (fd, string + offset, len - offset);
+ if (sent == -1) {
+ if (errno != EAGAIN) {
+ perror ("sock_send_string: socket write error");
+ printf ("Message was: %s\n", string);
+ //shutdown(fd, 2);
+ return sent;
+ }
+ continue;
+ } else if (sent == 0) {
+ // when this returns zero, it generally means
+ // we got disconnected
+ return sent + offset;
+ }
+
+ offset += sent;
+ }
+
+ return offset;
+}
+
+// Recv gives only one line per call...
+int
+sock_recv_string (int fd, char *dest, size_t maxlen)
+{
+ char *ptr = dest;
+ unsigned int recv = 0;
+
+ if (!dest)
+ return -1;
+ if (maxlen <= 0)
+ return 0;
+
+ while (1) {
+ int err = read (fd, ptr, 1);
+ if (err == -1) {
+ if (errno == EAGAIN) {
+ if (recv) {
+ // We've begun to read a string, but no bytes are
+ // available. Loop.
+ continue;
+ }
+ return 0;
+ } else {
+ perror ("sock_recv_string: socket read error");
+ return err;
+ }
+ } else if (err == 0) {
+ return recv;
+ }
+
+ recv++;
+
+ if (recv == maxlen || *ptr == 0 || *ptr == 10) {
+ *ptr = 0;
+ break;
+ }
+ ptr++;
+ }
+
+ if (recv == 1 && dest[0] == 0) {
+ // Don't return a null string
+ return 0;
+ }
+
+ if (recv < maxlen - 1) {
+ dest[recv] = 0;
+ }
+
+ return recv;
+}
+
+// Send/receive raw data
+int
+sock_send (int fd, void *src, size_t size)
+{
+ unsigned int offset = 0;
+
+ if (!src)
+ return -1;
+
+ while (offset != size) {
+ // write isn't guaranteed to send the entire string at once,
+ // so we have to sent it in a loop like this
+ int sent = write (fd, ((char *) src) + offset, size - offset);
+ if (sent == -1) {
+ if (errno != EAGAIN) {
+ perror ("sock_send: socket write error");
+ //shutdown(fd, 2);
+ return sent;
+ }
+ continue;
+ } else if (sent == 0) {
+ // when this returns zero, it generally means
+ // we got disconnected
+ return sent + offset;
+ }
+
+ offset += sent;
+ }
+
+ return offset;
+}
+
+int
+sock_recv (int fd, void *dest, size_t maxlen)
+{
+ int err;
+
+ if (!dest)
+ return -1;
+ if (maxlen <= 0)
+ return 0;
+
+ err = read (fd, dest, maxlen);
+ if (err < 0) {
+ //fprintf (stderr,"sock_recv: socket read error\n");
+ //shutdown(fd, 2);
+ return err;
+ }
+ //debug("sock_recv: Got message \"%s\"\n", (char *)dest);
+
+ return err;
+}