Merge branch 'master' into squeeze
[debian/amanda] / ndmp-src / ndml_agent.c
diff --git a/ndmp-src/ndml_agent.c b/ndmp-src/ndml_agent.c
new file mode 100644 (file)
index 0000000..34998f3
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 1998,1999,2000
+ *     Traakan, Inc., Los Altos, CA
+ *     All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Project:  NDMJOB
+ * Ident:    $Id: $
+ *
+ * Description:
+ *     Handle representation of an NDMP agent.
+ *
+ *     This provides for a common text for specifying
+ *     an agent host, connection authentication, and
+ *     protocol version. The text specification may
+ *     originate on the command line, in a config file,
+ *     or elsewhere.
+ *
+ *     A text string representation has the form:
+ *
+ *             AGENT ::= HOST[:PORT][/FLAGS][,ACCOUNT[,PASSWORD]]
+ *             AGENT ::= .
+ *             FLAGS ::= [23][ntm]
+ *
+ *     The internal representation is a struct ndmagent.
+ */
+
+
+#include "ndmlib.h"
+
+/* On some solaris distributions INADDR_NONE is not defined,
+ * so define it here..
+ */
+
+#ifndef INADDR_NONE
+#define INADDR_NONE     ((in_addr_t)-1)
+#endif
+
+int
+ndmagent_from_str (struct ndmagent *agent, char *str)
+{
+       int             have_vers = 0;
+       int             have_auth = 0;
+       int             rc;
+       char *          acct;
+       char *          port;
+       char *          flags;
+
+       NDMOS_MACRO_ZEROFILL (agent);
+
+       if ((acct = strchr (str, ',')) != 0)
+               *acct++ = 0;            /* stomp */
+
+       if ((port = strchr (str, ':')) != 0)
+               *port++ = 0;            /* stomp */
+
+       if (port) {
+               flags = strchr (port, '/');
+       } else {
+               flags = strchr (str, '/');
+       }
+       if (flags)
+               *flags++ = 0;           /* stomp */
+
+       /*
+        *           HOST[:PORT][/FLAGS][,ACCOUNT[,PASSWORD]]
+        *           ^     ^      ^       ^
+        *  str------+     |      |       |
+        *  port-----------+      |       |
+        *  flags-----------------+       |
+        *  acct--------------------------+
+        *
+        * The delimiters have been stomped (*p=0).
+        * If a portion is missing, the respective pointer is NULL (p==0)
+        * We restore the delimiters (p[-1]=x) as we proceed.
+        */
+
+       strncpy (agent->host, str, NDMAGENT_HOST_MAX-1);
+
+       if (port) {
+               agent->port = atoi(port);
+               port[-1] = ':';         /* restore */
+       } else {
+               agent->port = NDMPPORT;
+       }
+
+       if (flags) {
+               char *          p;
+
+               for (p = flags; *p; p++) {
+                       switch (*p) {
+#ifndef NDMOS_OPTION_NO_NDMP2
+                       case '2':
+                               agent->protocol_version = 2;
+                               have_vers++;
+                               break;
+#endif /* !NDMOS_OPTION_NO_NDMP2 */
+
+#ifndef NDMOS_OPTION_NO_NDMP3
+                       case '3':
+                               agent->protocol_version = 3;
+                               have_vers++;
+                               break;
+#endif /* !NDMOS_OPTION_NO_NDMP3 */
+
+#ifndef NDMOS_OPTION_NO_NDMP4
+                       case '4':
+                               agent->protocol_version = 4;
+                               have_vers++;
+                               break;
+#endif /* !NDMOS_OPTION_NO_NDMP4 */
+
+                       case 'n':       /* NDMP_AUTH_NONE */
+                       case 't':       /* NDMP_AUTH_TEXT */
+                       case 'm':       /* NDMP_AUTH_MD5 */
+                       case 'v':       /* void (don't auth) */
+                               agent->auth_type = *p;
+                               have_auth++;
+                               break;
+
+                       default:
+                               rc = -1;
+                               goto error_out;
+                       }
+               }
+               if (have_auth > 1 || have_vers > 1) {
+                       rc = -2;
+                       goto error_out;
+               }
+               flags[-1] = '/';        /* restore */
+       }
+
+       if (acct) {
+               char *          pass;
+
+               if ((pass = strchr (acct, ',')) != 0)
+                       *pass++ = 0;
+
+               strncpy (agent->account, acct, NDMAGENT_ACCOUNT_MAX-1);
+               if (pass) {
+                       strncpy (agent->password, pass,
+                                       NDMAGENT_PASSWORD_MAX-1);
+                       pass[-1] = ',';
+               }
+               acct[-1] = ',';         /* restore */
+
+               if (!have_auth) {
+                       agent->auth_type = 't'; /* NDMP_AUTH_TEXT */
+               }
+       }
+
+       if (strcmp (agent->host, ".") == 0) {
+               agent->conn_type = NDMCONN_TYPE_RESIDENT;
+               strcpy (agent->host, "(resident)");
+       } else {
+               agent->conn_type = NDMCONN_TYPE_REMOTE;
+       }
+
+       return 0;
+
+  error_out:
+       if (acct)  acct[-1] = ',';              /* restore */
+       if (port)  port[-1] = ':';              /* restore */
+       if (flags) flags[-1] = '/';             /* restore */
+
+       return rc;
+}
+
+
+
+int
+ndmhost_lookup (char *hostname, struct sockaddr_in *sin)
+{
+       struct hostent *        he;
+       in_addr_t               addr;
+
+       NDMOS_MACRO_ZEROFILL (sin);
+#ifdef NDMOS_OPTION_HAVE_SIN_LEN
+       sin->sin_len = sizeof *sin;
+#endif
+       sin->sin_family = AF_INET;
+
+       addr = inet_addr (hostname);
+       if (addr != INADDR_NONE) {
+               bcopy (&addr, &sin->sin_addr, 4);
+       } else {
+               he = gethostbyname (hostname);
+               if (!he)
+                       return -1;
+               bcopy (he->h_addr, &sin->sin_addr, 4);
+       }
+
+       return 0;
+}
+
+int
+ndmagent_to_sockaddr_in (struct ndmagent *agent, struct sockaddr_in *sin)
+{
+       int             rc;
+
+       rc = ndmhost_lookup (agent->host, sin);         /* inits sin */
+       if (rc) return rc;
+
+       sin->sin_port = htons (agent->port);
+
+       return 0;
+}