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