278f087d61cedd6a59e7ffff4e804729b3749aa7
[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
55 int
56 ndmagent_from_str (struct ndmagent *agent, char *str)
57 {
58         int             have_vers = 0;
59         int             have_auth = 0;
60         int             rc;
61         char *          acct;
62         char *          port;
63         char *          flags;
64
65         NDMOS_MACRO_ZEROFILL (agent);
66
67         if ((acct = strchr (str, ',')) != 0)
68                 *acct++ = 0;            /* stomp */
69
70         if ((port = strchr (str, ':')) != 0)
71                 *port++ = 0;            /* stomp */
72
73         if (port) {
74                 flags = strchr (port, '/');
75         } else {
76                 flags = strchr (str, '/');
77         }
78         if (flags)
79                 *flags++ = 0;           /* stomp */
80
81         /*
82          *           HOST[:PORT][/FLAGS][,ACCOUNT[,PASSWORD]]
83          *           ^     ^      ^       ^
84          *  str------+     |      |       |
85          *  port-----------+      |       |
86          *  flags-----------------+       |
87          *  acct--------------------------+
88          *
89          * The delimiters have been stomped (*p=0).
90          * If a portion is missing, the respective pointer is NULL (p==0)
91          * We restore the delimiters (p[-1]=x) as we proceed.
92          */
93
94         strncpy (agent->host, str, NDMAGENT_HOST_MAX-1);
95
96         if (port) {
97                 agent->port = atoi(port);
98                 port[-1] = ':';         /* restore */
99         } else {
100                 agent->port = NDMPPORT;
101         }
102
103         if (flags) {
104                 char *          p;
105
106                 for (p = flags; *p; p++) {
107                         switch (*p) {
108 #ifndef NDMOS_OPTION_NO_NDMP2
109                         case '2':
110                                 agent->protocol_version = 2;
111                                 have_vers++;
112                                 break;
113 #endif /* !NDMOS_OPTION_NO_NDMP2 */
114
115 #ifndef NDMOS_OPTION_NO_NDMP3
116                         case '3':
117                                 agent->protocol_version = 3;
118                                 have_vers++;
119                                 break;
120 #endif /* !NDMOS_OPTION_NO_NDMP3 */
121
122 #ifndef NDMOS_OPTION_NO_NDMP4
123                         case '4':
124                                 agent->protocol_version = 4;
125                                 have_vers++;
126                                 break;
127 #endif /* !NDMOS_OPTION_NO_NDMP4 */
128
129                         case 'n':       /* NDMP_AUTH_NONE */
130                         case 't':       /* NDMP_AUTH_TEXT */
131                         case 'm':       /* NDMP_AUTH_MD5 */
132                         case 'v':       /* void (don't auth) */
133                                 agent->auth_type = *p;
134                                 have_auth++;
135                                 break;
136
137                         default:
138                                 rc = -1;
139                                 goto error_out;
140                         }
141                 }
142                 if (have_auth > 1 || have_vers > 1) {
143                         rc = -2;
144                         goto error_out;
145                 }
146                 flags[-1] = '/';        /* restore */
147         }
148
149         if (acct) {
150                 char *          pass;
151
152                 if ((pass = strchr (acct, ',')) != 0)
153                         *pass++ = 0;
154
155                 strncpy (agent->account, acct, NDMAGENT_ACCOUNT_MAX-1);
156                 if (pass) {
157                         strncpy (agent->password, pass,
158                                         NDMAGENT_PASSWORD_MAX-1);
159                         pass[-1] = ',';
160                 }
161                 acct[-1] = ',';         /* restore */
162
163                 if (!have_auth) {
164                         agent->auth_type = 't'; /* NDMP_AUTH_TEXT */
165                 }
166         }
167
168         if (strcmp (agent->host, ".") == 0) {
169                 agent->conn_type = NDMCONN_TYPE_RESIDENT;
170                 strcpy (agent->host, "(resident)");
171         } else {
172                 agent->conn_type = NDMCONN_TYPE_REMOTE;
173         }
174
175         return 0;
176
177   error_out:
178         if (acct)  acct[-1] = ',';              /* restore */
179         if (port)  port[-1] = ':';              /* restore */
180         if (flags) flags[-1] = '/';             /* restore */
181
182         return rc;
183 }
184
185
186
187 int
188 ndmhost_lookup (char *hostname, struct sockaddr_in *sin)
189 {
190         struct hostent *        he;
191         in_addr_t               addr;
192
193         NDMOS_MACRO_ZEROFILL (sin);
194 #ifdef NDMOS_OPTION_HAVE_SIN_LEN
195         sin->sin_len = sizeof *sin;
196 #endif
197         sin->sin_family = AF_INET;
198
199         addr = inet_addr (hostname);
200         if (addr != INADDR_NONE) {
201                 bcopy (&addr, &sin->sin_addr, 4);
202         } else {
203                 he = gethostbyname (hostname);
204                 if (!he)
205                         return -1;
206                 bcopy (he->h_addr, &sin->sin_addr, 4);
207         }
208
209         return 0;
210 }
211
212 int
213 ndmagent_to_sockaddr_in (struct ndmagent *agent, struct sockaddr_in *sin)
214 {
215         int             rc;
216
217         rc = ndmhost_lookup (agent->host, sin);         /* inits sin */
218         if (rc) return rc;
219
220         sin->sin_port = htons (agent->port);
221
222         return 0;
223 }