Imported Upstream version 3.2.0
[debian/amanda] / ndmp-src / ndml_agent.c
1 /*
2  * Copyright (c) 1998,1999,2000
3  *      Traakan, Inc., Los Altos, CA
4  *      All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 /*
30  * Project:  NDMJOB
31  * Ident:    $Id: $
32  *
33  * Description:
34  *      Handle representation of an NDMP agent.
35  *
36  *      This provides for a common text for specifying
37  *      an agent host, connection authentication, and
38  *      protocol version. The text specification may
39  *      originate on the command line, in a config file,
40  *      or elsewhere.
41  *
42  *      A text string representation has the form:
43  *
44  *              AGENT ::= HOST[:PORT][/FLAGS][,ACCOUNT[,PASSWORD]]
45  *              AGENT ::= .
46  *              FLAGS ::= [23][ntm]
47  *
48  *      The internal representation is a struct ndmagent.
49  */
50
51
52 #include "ndmlib.h"
53
54 /* On some solaris distributions INADDR_NONE is not defined,
55  * so define it here..
56  */
57
58 #ifndef INADDR_NONE
59 #define INADDR_NONE     ((in_addr_t)-1)
60 #endif
61
62 int
63 ndmagent_from_str (struct ndmagent *agent, char *str)
64 {
65         int             have_vers = 0;
66         int             have_auth = 0;
67         int             rc;
68         char *          acct;
69         char *          port;
70         char *          flags;
71
72         NDMOS_MACRO_ZEROFILL (agent);
73
74         if ((acct = strchr (str, ',')) != 0)
75                 *acct++ = 0;            /* stomp */
76
77         if ((port = strchr (str, ':')) != 0)
78                 *port++ = 0;            /* stomp */
79
80         if (port) {
81                 flags = strchr (port, '/');
82         } else {
83                 flags = strchr (str, '/');
84         }
85         if (flags)
86                 *flags++ = 0;           /* stomp */
87
88         /*
89          *           HOST[:PORT][/FLAGS][,ACCOUNT[,PASSWORD]]
90          *           ^     ^      ^       ^
91          *  str------+     |      |       |
92          *  port-----------+      |       |
93          *  flags-----------------+       |
94          *  acct--------------------------+
95          *
96          * The delimiters have been stomped (*p=0).
97          * If a portion is missing, the respective pointer is NULL (p==0)
98          * We restore the delimiters (p[-1]=x) as we proceed.
99          */
100
101         strncpy (agent->host, str, NDMAGENT_HOST_MAX-1);
102
103         if (port) {
104                 agent->port = atoi(port);
105                 port[-1] = ':';         /* restore */
106         } else {
107                 agent->port = NDMPPORT;
108         }
109
110         if (flags) {
111                 char *          p;
112
113                 for (p = flags; *p; p++) {
114                         switch (*p) {
115 #ifndef NDMOS_OPTION_NO_NDMP2
116                         case '2':
117                                 agent->protocol_version = 2;
118                                 have_vers++;
119                                 break;
120 #endif /* !NDMOS_OPTION_NO_NDMP2 */
121
122 #ifndef NDMOS_OPTION_NO_NDMP3
123                         case '3':
124                                 agent->protocol_version = 3;
125                                 have_vers++;
126                                 break;
127 #endif /* !NDMOS_OPTION_NO_NDMP3 */
128
129 #ifndef NDMOS_OPTION_NO_NDMP4
130                         case '4':
131                                 agent->protocol_version = 4;
132                                 have_vers++;
133                                 break;
134 #endif /* !NDMOS_OPTION_NO_NDMP4 */
135
136                         case 'n':       /* NDMP_AUTH_NONE */
137                         case 't':       /* NDMP_AUTH_TEXT */
138                         case 'm':       /* NDMP_AUTH_MD5 */
139                         case 'v':       /* void (don't auth) */
140                                 agent->auth_type = *p;
141                                 have_auth++;
142                                 break;
143
144                         default:
145                                 rc = -1;
146                                 goto error_out;
147                         }
148                 }
149                 if (have_auth > 1 || have_vers > 1) {
150                         rc = -2;
151                         goto error_out;
152                 }
153                 flags[-1] = '/';        /* restore */
154         }
155
156         if (acct) {
157                 char *          pass;
158
159                 if ((pass = strchr (acct, ',')) != 0)
160                         *pass++ = 0;
161
162                 strncpy (agent->account, acct, NDMAGENT_ACCOUNT_MAX-1);
163                 if (pass) {
164                         strncpy (agent->password, pass,
165                                         NDMAGENT_PASSWORD_MAX-1);
166                         pass[-1] = ',';
167                 }
168                 acct[-1] = ',';         /* restore */
169
170                 if (!have_auth) {
171                         agent->auth_type = 't'; /* NDMP_AUTH_TEXT */
172                 }
173         }
174
175         if (strcmp (agent->host, ".") == 0) {
176                 agent->conn_type = NDMCONN_TYPE_RESIDENT;
177                 strcpy (agent->host, "(resident)");
178         } else {
179                 agent->conn_type = NDMCONN_TYPE_REMOTE;
180         }
181
182         return 0;
183
184   error_out:
185         if (acct)  acct[-1] = ',';              /* restore */
186         if (port)  port[-1] = ':';              /* restore */
187         if (flags) flags[-1] = '/';             /* restore */
188
189         return rc;
190 }
191
192
193
194 int
195 ndmhost_lookup (char *hostname, struct sockaddr_in *sin)
196 {
197         struct hostent *        he;
198         in_addr_t               addr;
199
200         NDMOS_MACRO_ZEROFILL (sin);
201 #ifdef NDMOS_OPTION_HAVE_SIN_LEN
202         sin->sin_len = sizeof *sin;
203 #endif
204         sin->sin_family = AF_INET;
205
206         addr = inet_addr (hostname);
207         if (addr != INADDR_NONE) {
208                 bcopy (&addr, &sin->sin_addr, 4);
209         } else {
210                 he = gethostbyname (hostname);
211                 if (!he)
212                         return -1;
213                 bcopy (he->h_addr, &sin->sin_addr, 4);
214         }
215
216         return 0;
217 }
218
219 int
220 ndmagent_to_sockaddr_in (struct ndmagent *agent, struct sockaddr_in *sin)
221 {
222         int             rc;
223
224         rc = ndmhost_lookup (agent->host, sin);         /* inits sin */
225         if (rc) return rc;
226
227         sin->sin_port = htons (agent->port);
228
229         return 0;
230 }