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  *
35  */
36 
37 
38 #include "ndmagents.h"
39 
40 
41 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
42 
43 
44 int
ndmca_connect_xxx_agent(struct ndm_session * sess,struct ndmconn ** connp,char * prefix,struct ndmagent * agent)45 ndmca_connect_xxx_agent (
46   struct ndm_session *sess,
47   struct ndmconn **connp,
48   char *prefix,
49   struct ndmagent *agent)
50 {
51 	struct ndmconn *	conn = *connp;
52 	char *			err;
53 	int			rc;
54 
55 	if (conn)
56 		return 0;		/* already connected */
57 
58 	if (agent->conn_type == NDMCONN_TYPE_NONE) {
59 		ndmalogf (sess, 0, 0, "agent %s not give", prefix+1);
60 		return -1;
61 	}
62 
63 	conn = ndmconn_initialize (0, prefix);
64 	if (!conn) {
65 		ndmalogf (sess, prefix, 0, "can't init connection");
66 		return -1;
67 	}
68 
69 	if (sess->control_acb->job.time_limit > 0)
70 	    conn->time_limit = sess->control_acb->job.time_limit;
71 
72 	if (sess->conn_snooping) {
73 		ndmconn_set_snoop (conn, &sess->param->log, sess->param->log_level);
74 	}
75 
76 	conn->call = ndma_call;
77 	conn->context = sess;
78 	conn->unexpected = ndma_dispatch_ctrl_unexpected;
79 
80 	rc = ndmconn_connect_agent (conn, agent);
81 	if (rc) {
82 		err = "Can't connect";
83 		goto error_out;
84 	}
85 
86 	rc = ndmconn_auth_agent (conn, agent);
87 	if (rc) {
88 		err = "Can't auth (bad pw?)";
89 		goto error_out;
90 	}
91 
92 	*connp = conn;
93 	return 0;
94 
95   error_out:
96 	ndmalogf (sess, prefix, 0, "err %s", ndmconn_get_err_msg (conn));
97 	//ndmconn_destruct (conn);
98 	*connp = conn;
99 	return -1;
100 
101 }
102 
103 int
ndmca_connect_data_agent(struct ndm_session * sess)104 ndmca_connect_data_agent (struct ndm_session *sess)
105 {
106 	int		rc;
107 
108 	rc = ndmca_connect_xxx_agent (sess,
109 				&sess->plumb.data,
110 				"#D",
111 				&sess->control_acb->job.data_agent);
112 	if (rc == 0) {
113 		if (sess->plumb.data->conn_type == NDMCONN_TYPE_RESIDENT) {
114 			sess->data_acb->protocol_version =
115 					sess->plumb.data->protocol_version;
116 		}
117 	}
118 
119 	return rc;
120 }
121 
122 int
ndmca_connect_tape_agent(struct ndm_session * sess)123 ndmca_connect_tape_agent (struct ndm_session *sess)
124 {
125 	int		rc;
126 
127 	if (sess->control_acb->job.tape_agent.conn_type == NDMCONN_TYPE_NONE) {
128 		rc = ndmca_connect_data_agent (sess);
129 		if (rc) {
130 			ndmconn_destruct (sess->plumb.data);
131 			sess->plumb.data = NULL;
132 			return rc;
133 		}
134 		sess->plumb.tape = sess->plumb.data;
135 		rc = 0;
136 	} else {
137 		rc = ndmca_connect_xxx_agent (sess,
138 				&sess->plumb.tape,
139 				"#T",
140 				&sess->control_acb->job.tape_agent);
141 		ndmalogf (sess, 0, 7, "ndmca_connect_tape_agent: %d %p", rc, sess->plumb.tape);
142 	}
143 
144 	if (rc == 0) {
145 		if (sess->plumb.tape->conn_type == NDMCONN_TYPE_RESIDENT) {
146 			sess->tape_acb->protocol_version =
147 					sess->plumb.tape->protocol_version;
148 		}
149 	}
150 
151 	return rc;
152 }
153 
154 int
ndmca_connect_robot_agent(struct ndm_session * sess)155 ndmca_connect_robot_agent (struct ndm_session *sess)
156 {
157 	int		rc;
158 
159 	if (sess->control_acb->job.robot_agent.conn_type == NDMCONN_TYPE_NONE) {
160 		rc = ndmca_connect_tape_agent (sess);
161 		if (rc) return rc;
162 		sess->plumb.robot = sess->plumb.tape;
163 		rc = 0;
164 	} else {
165 		rc = ndmca_connect_xxx_agent (sess,
166 				&sess->plumb.robot,
167 				"#R",
168 				&sess->control_acb->job.robot_agent);
169 	}
170 
171 	if (rc == 0) {
172 		if (sess->plumb.robot->conn_type == NDMCONN_TYPE_RESIDENT) {
173 			sess->robot_acb->protocol_version =
174 					sess->plumb.robot->protocol_version;
175 		}
176 	}
177 
178 	return rc;
179 }
180 
181 int
ndmca_connect_control_agent(struct ndm_session * sess)182 ndmca_connect_control_agent (struct ndm_session *sess)
183 {
184 	struct ndmagent	control_agent;
185 	int		rc;
186 
187 	ndmagent_from_str (&control_agent, ".");	/* resident */
188 
189 	rc = ndmca_connect_xxx_agent (sess,
190 				&sess->plumb.control,
191 				"#C.",
192 				&control_agent);
193 
194 	return rc;
195 }
196 
197 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
198