Package: apcupsd
Version: 3.10.17-2
Severity: normal
Tags: patch

Hi,

Example client.c cannot be compiled as supplied in the examples dir.
I downloaded the source and added the code necessary to compile it.

BTW thanks for maintaining apcupsd: it's the reason I picked an APC product.

Regards,

Hugo

===========================================================================================================
--- client.c    2003-11-26 09:54:46.000000000 -0600
+++ do_apcups_client.cpp        2005-12-25 07:33:12.000000000 -0600
@@ -17,15 +17,34 @@
 * For additional examples of code, see cgi/upsfetch.c
 */

-#include "apc.h"
+//     12/25/2005 - Changed by Hugo Vanwoerkom to compile + run on Debian 
Sarge.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <unistd.h>

-#ifdef HAVE_NISLIB

/* Default values, can be changed on command line */
#define SERV_TCP_PORT 3551
#define SERV_HOST_ADDR "127.0.0.1"

-void handle_client();
+//Only working parms:
+//127.0.0.1:3551 status
+//127.0.0.1:3551 events
+
+
+void handle_client(FILE *fp, int sockfd, char *cmd);
+int net_open(char *host, char *service, int port);
+int net_recv(int sockfd, char *buff, int maxlen);
+int net_send(int sockfd, char *buff, int len);
+void net_close(int sockfd);
+int asnprintf(char *str, size_t size, const char *fmt,  ...);
+void (*error_out)(const char *file, int line, const char *fmt,...);

extern int net_errno;

@@ -66,6 +85,7 @@
      error_abort(msg);
   }

+//printf("%d %s\n",__LINE__,__FILE__);
   handle_client(stdin, sockfd, cmd);       /* do it all */
   net_close(sockfd);
   exit(0);
@@ -83,39 +103,265 @@

void handle_client(FILE *fp, int sockfd, char *cmd)
{
- int n; - char sendline[MAXLINE];
-   char recvline[MAXLINE+1];
-   int quit = 0;
-
-   while (!quit) {
- if (cmd) { - strcpy(sendline, cmd); /* one shot command */
-        quit = 1;
-      } else if (fgets(sendline, MAXLINE, fp) == NULL) {
-        break;
-      }
-      n = strlen(sendline);
-      if (net_send(sockfd, sendline, n) != n)
-         error_abort("handle_client: write error on socket");
-
-      while ((n = net_recv(sockfd, recvline, sizeof(recvline))) > 0) {
-         recvline[n] = 0;
-         fputs(recvline, stdout);
-      }
-      if (n < 0) {
-        char msg[200];
-         sprintf(msg, "handle_client: net_recv error: %s\n", 
strerror(net_errno));
-        error_abort(msg);
-     }
-   }
+ int n; + char sendline[MAXLINE];
+    char recvline[MAXLINE+1];
+    int quit = 0;
+
+    while (!quit) {
+ if (cmd) { + strcpy(sendline, cmd); /* one shot command */
+           quit = 1;
+//     It's never NULL:
+//      } else if (fgets(sendline, MAXLINE, fp) == NULL) {
+//      break;
+//      }
+ } + else { + fgets(sendline, MAXLINE, fp);
+           if (strlen (sendline) == 1) {
+               break;
+           }
+       }
+       n = strlen(sendline);
+       if (net_send(sockfd, sendline, n) != n)
+           error_abort("handle_client: write error on socket");
+
+       while ((n = net_recv(sockfd, recvline, sizeof(recvline))) > 0) {
+           recvline[n] = 0;
+           fputs(recvline, stdout);
+       }
+       if (n < 0) {
+           char msg[200];
+           sprintf(msg, "handle_client: net_recv error: %s\n", 
strerror(net_errno));
+           error_abort(msg);
+       }
+    }
+}
+
+int net_errno = 0;                   /* error number -- not yet implemented */
+char *net_errmsg = NULL;             /* pointer to error message */
+char net_errbuf[256];                /* error message buffer for messages */
+
+
+/*
+ * Read a nbytes from the network.
+ * It is possible that the total bytes require in several
+ * read requests
+ */
+
+static int read_nbytes(int fd, char *ptr, int nbytes)
+{
+    int nleft, nread;
+
+    nleft = nbytes;
+
+    while (nleft > 0) {
+
+       do {
+ nread = read(fd, ptr, nleft); + } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
+       if (nread <= 0) {
+           net_errno = errno;
+           return(nread);               /* error, or EOF */
+       }
+       nleft -= nread;
+       ptr += nread;
+    }
+    return(nbytes - nleft);           /* return >= 0 */
}

-#else /* HAVE_NISLIB */
+/*
+ * Write nbytes to the network.
+ * It may require several writes.
+ */
+
+static int write_nbytes(int fd, char *ptr, int nbytes)
+{
+    int nleft, nwritten;
+
+    nleft = nbytes;
+    while (nleft > 0) {
+       nwritten = write(fd, ptr, nleft);
+       if (nwritten <= 0) {
+           net_errno = errno;
+           return (nwritten);           /* error */
+       }
+
+       nleft -= nwritten;
+       ptr += nwritten;
+    }
+    return(nbytes-nleft);
+}
+
+/* + * Receive a message from the other end. Each message consists of
+ * two packets. The first is a header that contains the size
+ * of the data that follows in the second packet.
+ * Returns number of bytes read
+ * Returns 0 on end of file
+ * Returns -1 on hard end of file (i.e. network connection close)
+ * Returns -2 on error
+ */
+int net_recv(int sockfd, char *buff, int maxlen)
+{
+    int nbytes;
+    short pktsiz;

-int main(int argc, char *argv[]) {
-    printf("Sorry, NIS code is not compiled in apcupsd.\n");
-    return 1;
+    /* get data size -- in short */
+    if ((nbytes = read_nbytes(sockfd, (char *)&pktsiz, sizeof(short))) <= 0) {
+       /* probably pipe broken because client died */
+       return -1;                      /* assume hard EOF received */
+    }
+    if (nbytes != sizeof(short)) {
+       return -2;
+    }
+
+    pktsiz = ntohs(pktsiz);         /* decode no. of bytes that follow */
+    if (pktsiz > maxlen) {
+        net_errmsg = "net_recv: record length too large\n";
+       return -2;
+    }
+    if (pktsiz == 0)
+       return 0;                       /* soft EOF */
+
+    /* now read the actual data */
+    if ((nbytes = read_nbytes(sockfd, buff, pktsiz)) <=  0) {
+        net_errmsg = "net_recv: read_nbytes error\n";
+       return -2;
+    }
+    if (nbytes != pktsiz) {
+        net_errmsg = "net_recv: error in read_nbytes\n";
+       return -2;
+    }
+    return(nbytes);                   /* return actual length of message */
}

-#endif /* HAVE_NISLIB */
+/*
+ * Send a message over the network. The send consists of
+ * two network packets. The first is sends a short containing
+ * the length of the data packet which follows.
+ * Returns number of bytes sent
+ * Returns -1 on error
+ */
+int net_send(int sockfd, char *buff, int len)
+{
+    int rc;
+    short pktsiz;
+
+    pktsiz = htons((short)len);
+    /* send short containing size of data packet */
+    rc = write_nbytes(sockfd, (char *)&pktsiz, sizeof(short));
+    if (rc != sizeof(short)) {
+        net_errmsg = "net_send: write_nbytes error of length prefix\n";
+       return -1;
+    }
+
+    /* send data packet */
+    rc = write_nbytes(sockfd, buff, len);
+    if (rc != len) {
+        net_errmsg = "net_send: write_nbytes error\n";
+       return -1;
+    }
+    return rc;
+}
+
+/* + * Open a TCP connection to the UPS network server
+ * Returns -1 on error
+ * Returns socket file descriptor otherwise
+ */
+int net_open(char *host, char *service, int port)
+{
+    int sockfd;
+    unsigned int inaddr;              /* Careful here to use unsigned int for 
*/
+                                      /* compatibility with Alpha */
+    struct hostent *hp;
+
+ /* + * Fill in the structure serv_addr with the address of
+     * the server that we want to connect with.
+     */
+    memset((char *) &tcp_serv_addr, 0, sizeof(tcp_serv_addr));
+    tcp_serv_addr.sin_family = AF_INET;
+    tcp_serv_addr.sin_port = htons(port);
+
+    if ((inaddr = inet_addr(host)) != INADDR_NONE) {
+       tcp_serv_addr.sin_addr.s_addr = inaddr;
+    } else {
+       if ((hp = gethostbyname(host)) == NULL) {
+          net_errmsg ="tcp_open: hostname error\n";
+         return -1;
+       }
+       if (hp->h_length != sizeof(inaddr) || hp->h_addrtype != AF_INET) {
+           net_errmsg ="tcp_open: funny gethostbyname value\n";
+          return -1;
+       }
+       tcp_serv_addr.sin_addr.s_addr = *(unsigned int *)hp->h_addr;
+    }
+ +
+    /* Open a TCP socket */
+    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        net_errmsg = "tcp_open: cannot open stream socket\n";
+       return -1;
+    }
+    /* connect to server */
+    if (connect(sockfd, (struct sockaddr *) &tcp_serv_addr, 
sizeof(tcp_serv_addr)) < 0) {
+//        asnprintf(net_errbuf, sizeof(net_errbuf), _("tcp_open: cannot 
connect to server %s on port %d.\n\
+        asnprintf(net_errbuf, sizeof(net_errbuf), ("tcp_open: cannot connect 
to server %s on port %d.\n\
+ERR=%s\n"), host, port, strerror(errno));
+       net_errmsg = net_errbuf;
+       close (sockfd);
+       return -1;
+    }
+    return sockfd;
+}
+
+/* Close the network connection */
+void net_close(int sockfd)
+{
+    short pktsiz = 0;
+    /* send EOF sentinel */
+    write_nbytes(sockfd, (char *)&pktsiz, sizeof(short));
+    close(sockfd);
+}
+ +/* + * Accept a TCP connection.
+ * Returns -1 on error.
+ * Returns file descriptor of new connection otherwise.
+ */
+int net_accept(int fd, struct sockaddr_in *cli_addr)
+{
+    socklen_t clilen = sizeof(*cli_addr);
+    int newfd;
+
+    do {
+       newfd = accept(fd, (struct sockaddr*)cli_addr, &clilen);
+    } while (newfd == -1 && (errno == EINTR || errno == EAGAIN));
+ + if (newfd < 0) {
+       net_errno = errno;
+       return(-1);              /* error */
+    }
+
+    return newfd;
+}
+
+/*
+ * Implement snprintf
+ */
+int asnprintf(char *str, size_t size, const char *fmt, ...) +{
+
+   va_list   arg_ptr;
+   int len;
+
+   va_start(arg_ptr, fmt);
+   len = vsnprintf(str, size, fmt, arg_ptr);
+   va_end(arg_ptr);
+   str[size-1] = 0;
+   return len;
+
+}



--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to