00001
00005 #include <malloc.h>
00006 #include <string.h>
00007
00008 #include "libmgk.h"
00009 #include "allocate.h"
00010
00011 DEFINE_ALLOCATOR(mgk_link, 200, l.l2l.nextin);
00012
00013 static int dfltlen = 1000;
00014
00015 unsigned int
00016 mgk_set_default_connection_length(unsigned int newlen)
00017 {
00018 unsigned int retval = dfltlen;
00019 dfltlen = newlen;
00020 return (retval);
00021 }
00022
00023 static mgk_error_code
00024 do_connect(mgk_nodep src, unsigned int srcport,
00025 mgk_nodep dst, unsigned int dstport,
00026 unsigned int maxlen, int callremote)
00027 {
00028 mgk_link *lp;
00029 mgk_value *args[7];
00030 mgk_value *rargs[1];
00031 mgk_remnode *rsrc, *rdst;
00032 mgk_data_type t;
00033 mgk_scalar s;
00034 int *errp;
00035
00036 if (__mgk_check_node(src)) {
00037 if (srcport >= src->nout) {
00038 return (mgk_errno = E_BADPORTIX);
00039 }
00040 rsrc = NULL;
00041 }
00042 else if (__mgk_check_remnode(src)) {
00043 rsrc = (mgk_remnode *) src;
00044 }
00045 else {
00046 return (mgk_errno = E_NOTNODE);
00047 }
00048 if (__mgk_check_node(dst)) {
00049 if (dstport >= dst->nin) {
00050 return (mgk_errno = E_BADPORTIX);
00051 }
00052 rdst = NULL;
00053 }
00054 else if (__mgk_check_remnode(dst)) {
00055 rdst = (mgk_remnode *) dst;
00056 }
00057 else {
00058 return (mgk_errno = E_NOTNODE);
00059 }
00060
00061 if (!rsrc) {
00062 for (lp = src->outs[srcport].links; lp; lp = lp->l.l2l.nextout) {
00063 if ((lp->srcidx == srcport) && (lp->dstidx == dstport)) {
00064 switch (lp->type) {
00065 case LINK_L2L:
00066 if (!rdst && (lp->l.l2l.src == src) && (lp->l.l2l.dst == dst)) {
00067 return (mgk_errno == E_PORTCONN);
00068 }
00069 break;
00070 case LINK_L2R:
00071 if (rdst && (lp->l.l2r.src == src) && (lp->l.l2r.dst == rdst)) {
00072 return (mgk_errno == E_PORTCONN);
00073 }
00074 break;
00075 default:
00076 break;
00077 }
00078 }
00079 }
00080 }
00081 if (!rdst) {
00082 for (lp = dst->ins[dstport].links; lp; lp = lp->l.l2l.nextin) {
00083 if ((lp->srcidx == srcport) && (lp->dstidx == dstport)) {
00084 switch (lp->type) {
00085 case LINK_L2L:
00086 if (!rsrc && (lp->l.l2l.src == src) && (lp->l.l2l.dst == dst)) {
00087 return (mgk_errno == E_PORTCONN);
00088 }
00089 break;
00090 case LINK_R2L:
00091 if (rsrc && (lp->l.r2l.src == rsrc) && (lp->l.r2l.dst == dst)) {
00092 return (mgk_errno == E_PORTCONN);
00093 }
00094 break;
00095 default:
00096 break;
00097 }
00098 }
00099 }
00100 }
00101 if (rsrc && rdst) {
00102 if (!callremote) {
00103 return (mgk_errno = E_GENERROR);
00104 }
00105 args[0] = __mgk_build_value(&rsrc->ID, T_LONGINT);
00106 args[1] = __mgk_build_value(&rsrc->host->index, T_INTEGER);
00107 args[2] = __mgk_build_value(&srcport, T_INTEGER);
00108 args[3] = __mgk_build_value(&rdst->ID, T_LONGINT);
00109 args[4] = __mgk_build_value(&rdst->host->index, T_INTEGER);
00110 args[5] = __mgk_build_value(&dstport, T_INTEGER);
00111 args[6] = __mgk_build_value(&maxlen, T_INTEGER);
00112 if (__mgk_remote_call(rsrc->host,
00113 cmd_connect_nodes,
00114 7, args,
00115 1, rargs)) {
00116 errp = __mgk_extract_value(rargs[0], &t, &s);
00117 if (t == T_INTEGER) {
00118 return (mgk_errno = *errp);
00119 }
00120 }
00121 return (mgk_errno = E_COMM);
00122 }
00123 if (!(lp = ALLOC_mgk_link())) {
00124 return (mgk_errno = E_NOMEM);
00125 }
00126 if (rsrc) {
00127 if (callremote) {
00128 args[0] = __mgk_build_value(&rsrc->ID, T_LONGINT);
00129 args[1] = __mgk_build_value(&rsrc->host->index, T_INTEGER);
00130 args[2] = __mgk_build_value(&srcport, T_INTEGER);
00131 args[3] = __mgk_build_value(&dst->ID, T_LONGINT);
00132 args[4] = __mgk_build_value(&__mgk_local_host->index, T_INTEGER);
00133 args[5] = __mgk_build_value(&dstport, T_INTEGER);
00134 args[6] = __mgk_build_value(&maxlen, T_INTEGER);
00135 if (__mgk_remote_call(rsrc->host,
00136 cmd_connect_nodes,
00137 7, args,
00138 1, rargs)) {
00139 errp = __mgk_extract_value(rargs[0], &t, &s);
00140 mgk_errno = (t == T_INTEGER) ? *errp : E_COMM;
00141 }
00142 else {
00143 mgk_errno = E_COMM;
00144 }
00145 }
00146 else {
00147 mgk_errno = E_SUCCESS;
00148 }
00149 if (mgk_errno == E_SUCCESS) {
00150 lp->type = LINK_R2L;
00151 lp->srcidx = srcport;
00152 lp->dstidx = dstport;
00153 lp->l.r2l.src = rsrc;
00154 lp->l.r2l.dst = dst;
00155 lp->l.r2l.nextin = dst->ins[dstport].links;
00156 dst->ins[dstport].links = lp;
00157 dst->ins[dstport].maxlen = maxlen;
00158 }
00159 else {
00160 FREE_mgk_link(lp);
00161 }
00162 return (mgk_errno);
00163 }
00164 if (rdst) {
00165 if (callremote) {
00166 args[0] = __mgk_build_value(&src->ID, T_LONGINT);
00167 args[1] = __mgk_build_value(&__mgk_local_host->index, T_INTEGER);
00168 args[2] = __mgk_build_value(&srcport, T_INTEGER);
00169 args[3] = __mgk_build_value(&rdst->ID, T_LONGINT);
00170 args[4] = __mgk_build_value(&rdst->host->index, T_INTEGER);
00171 args[5] = __mgk_build_value(&dstport, T_INTEGER);
00172 args[6] = __mgk_build_value(&maxlen, T_INTEGER);
00173 if (__mgk_remote_call(rdst->host,
00174 cmd_connect_nodes,
00175 7, args,
00176 1, rargs)) {
00177 errp = __mgk_extract_value(rargs[0], &t, &s);
00178 mgk_errno = (t == T_INTEGER) ? *errp : E_COMM;
00179 }
00180 else {
00181 mgk_errno = E_COMM;
00182 }
00183 }
00184 else {
00185 mgk_errno = E_SUCCESS;
00186 }
00187 if (mgk_errno == E_SUCCESS) {
00188 lp->type = LINK_L2R;
00189 lp->srcidx = srcport;
00190 lp->dstidx = dstport;
00191 lp->l.l2r.src = src;
00192 lp->l.l2r.dst = rdst;
00193 lp->l.l2r.qlen = 0;
00194 lp->l.l2r.maxlen = maxlen;
00195 lp->l.l2r.head = NULL;
00196 lp->l.l2r.tail = NULL;
00197 lp->l.l2r.active = NULL;
00198 lp->l.l2r.nextout = src->outs[srcport].links;
00199 src->outs[srcport].links = lp;
00200 }
00201 else {
00202 FREE_mgk_link(lp);
00203 }
00204 return (mgk_errno);
00205 }
00206 lp->type = LINK_L2L;
00207 lp->srcidx = srcport;
00208 lp->dstidx = dstport;
00209 lp->l.l2l.src = src;
00210 lp->l.l2l.dst = dst;
00211 lp->l.l2l.nextin = dst->ins[dstport].links;
00212 lp->l.l2l.nextout = src->outs[srcport].links;
00213 src->outs[srcport].links = lp;
00214 dst->ins[dstport].links = lp;
00215 dst->ins[dstport].maxlen = maxlen;
00216 return (mgk_errno = E_SUCCESS);
00217 }
00218
00219 mgk_error_code
00220 mgk_connect_nodes(mgk_nodep src, unsigned int srcport,
00221 mgk_nodep dst, unsigned int dstport)
00222 {
00223 return (do_connect(src, srcport, dst, dstport, dfltlen, TRUE));
00224 }
00225
00226 mgk_error_code
00227 mgk_connect_nodes_len(mgk_nodep src, unsigned int srcport,
00228 mgk_nodep dst, unsigned int dstport,
00229 unsigned int maxlen)
00230 {
00231 return (do_connect(src, srcport, dst, dstport, maxlen, TRUE));
00232 }
00233
00234 DEFSVC(connect_nodes)
00235 {
00236 if ((argc == 7) && (rargc == 1)) {
00237 mgk_data_type t1, t2, t3, t4, t5, t6, t7;
00238 long *sidp = __mgk_parse_value(argv[0], &t1);
00239 int *shixp = __mgk_parse_value(argv[1], &t2);
00240 int *sidxp = __mgk_parse_value(argv[2], &t3);
00241 long *didp = __mgk_parse_value(argv[3], &t4);
00242 int *dhixp = __mgk_parse_value(argv[4], &t5);
00243 int *didxp = __mgk_parse_value(argv[5], &t6);
00244 int *maxlp = __mgk_parse_value(argv[6], &t7);
00245 if ((t1 == T_LONGINT) && (t2 == T_INTEGER) && (t3 == T_INTEGER) &&
00246 (t4 == T_LONGINT) && (t5 == T_INTEGER) && (t6 == T_INTEGER) &&
00247 (t7 == T_INTEGER)) {
00248 mgk_node *src = __mgk_locate_node(*shixp, *sidp);
00249 mgk_node *dst = __mgk_locate_node(*dhixp, *didp);
00250 do_connect(src, *sidxp, dst, *didxp, *maxlp, FALSE);
00251 rargv[0] = __mgk_build_value(&mgk_errno, T_INTEGER);
00252 return (TRUE);
00253 }
00254 }
00255 return (FALSE);
00256 }
00257
00258 static mgk_error_code
00259 do_disconnect(mgk_nodep src, unsigned int srcport,
00260 mgk_nodep dst, unsigned int dstport,
00261 int callremote)
00262 {
00263 mgk_link *slp, *dlp, **slpp, **dlpp;
00264 mgk_value *args[6];
00265 mgk_value *rargs[1];
00266 mgk_remnode *rsrc, *rdst;
00267 mgk_data_type t;
00268 mgk_scalar s;
00269 int *errp;
00270
00271 if (__mgk_check_node(src)) {
00272 if (srcport >= src->nout) {
00273 return (mgk_errno = E_BADPORTIX);
00274 }
00275 rsrc = NULL;
00276 }
00277 else if (__mgk_check_remnode(src)) {
00278 rsrc = (mgk_remnode *) src;
00279 }
00280 else {
00281 return (mgk_errno = E_NOTNODE);
00282 }
00283 if (__mgk_check_node(dst)) {
00284 if (dstport >= dst->nin) {
00285 return (mgk_errno = E_BADPORTIX);
00286 }
00287 rdst = NULL;
00288 }
00289 else if (__mgk_check_remnode(dst)) {
00290 rdst = (mgk_remnode *) dst;
00291 }
00292 else {
00293 return (mgk_errno = E_NOTNODE);
00294 }
00295
00296 if (rsrc) {
00297 slpp = NULL;
00298 slp = NULL;
00299 }
00300 else {
00301 for (slpp = &src->outs[srcport].links;
00302 (slp = *slpp);
00303 slpp = &slp->l.l2l.nextout) {
00304 if ((slp->srcidx == srcport) && (slp->dstidx == dstport)) {
00305 switch (slp->type) {
00306 case LINK_L2L:
00307 if (!rdst && (slp->l.l2l.src == src) && (slp->l.l2l.dst == dst)) {
00308 break;
00309 }
00310 continue;
00311 case LINK_L2R:
00312 if (rdst && (slp->l.l2r.src == src) && (slp->l.l2r.dst == rdst)) {
00313 break;
00314 }
00315 continue;
00316 default:
00317 continue;
00318 }
00319 break;
00320 }
00321 }
00322 if (!slp) {
00323 return (mgk_errno = E_PORTCONN);
00324 }
00325 }
00326 if (rdst) {
00327 dlpp = NULL;
00328 dlp = NULL;
00329 }
00330 else {
00331 for (dlpp = &dst->ins[dstport].links;
00332 (dlp = *dlpp);
00333 dlpp = &dlp->l.l2l.nextin) {
00334 if ((dlp->srcidx == srcport) && (dlp->dstidx == dstport)) {
00335 switch (dlp->type) {
00336 case LINK_L2L:
00337 if (!rsrc && (dlp->l.l2l.src == src) && (dlp->l.l2l.dst == dst)) {
00338 break;
00339 }
00340 continue;
00341 case LINK_R2L:
00342 if (rsrc && (dlp->l.r2l.src == rsrc) && (dlp->l.r2l.dst == dst)) {
00343 break;
00344 }
00345 continue;
00346 default:
00347 continue;
00348 }
00349 break;
00350 }
00351 }
00352 if (!dlp) {
00353 return (mgk_errno = E_PORTCONN);
00354 }
00355 }
00356 if (rsrc && rdst) {
00357 if (!callremote) {
00358 return (mgk_errno = E_GENERROR);
00359 }
00360 args[0] = __mgk_build_value(&rsrc->ID, T_LONGINT);
00361 args[1] = __mgk_build_value(&rsrc->host->index, T_INTEGER);
00362 args[2] = __mgk_build_value(&srcport, T_INTEGER);
00363 args[3] = __mgk_build_value(&rdst->ID, T_LONGINT);
00364 args[4] = __mgk_build_value(&rdst->host->index, T_INTEGER);
00365 args[5] = __mgk_build_value(&dstport, T_INTEGER);
00366 if (__mgk_remote_call(rsrc->host,
00367 cmd_disconnect_nodes,
00368 6, args,
00369 1, rargs)) {
00370 errp = __mgk_extract_value(rargs[0], &t, &s);
00371 if (t == T_INTEGER) {
00372 return (mgk_errno = *errp);
00373 }
00374 }
00375 return (mgk_errno = E_COMM);
00376 }
00377 if (rsrc) {
00378 if (callremote) {
00379 args[0] = __mgk_build_value(&rsrc->ID, T_LONGINT);
00380 args[1] = __mgk_build_value(&rsrc->host->index, T_INTEGER);
00381 args[2] = __mgk_build_value(&srcport, T_INTEGER);
00382 args[3] = __mgk_build_value(&dst->ID, T_LONGINT);
00383 args[4] = __mgk_build_value(&__mgk_local_host->index, T_INTEGER);
00384 args[5] = __mgk_build_value(&dstport, T_INTEGER);
00385 if (__mgk_remote_call(rsrc->host,
00386 cmd_disconnect_nodes,
00387 6, args,
00388 1, rargs)) {
00389 errp = __mgk_extract_value(rargs[0], &t, &s);
00390 mgk_errno = (t == T_INTEGER) ? *errp : E_COMM;
00391 }
00392 else {
00393 mgk_errno = E_COMM;
00394 }
00395 }
00396 else {
00397 mgk_errno = E_SUCCESS;
00398 }
00399 if (mgk_errno == E_SUCCESS) {
00400 *dlpp = dlp->l.r2l.nextin;
00401 FREE_mgk_link(dlp);
00402 }
00403 return (mgk_errno);
00404 }
00405 if (rdst) {
00406 if (callremote) {
00407 args[0] = __mgk_build_value(&src->ID, T_LONGINT);
00408 args[1] = __mgk_build_value(&__mgk_local_host->index, T_INTEGER);
00409 args[2] = __mgk_build_value(&srcport, T_INTEGER);
00410 args[3] = __mgk_build_value(&rdst->ID, T_LONGINT);
00411 args[4] = __mgk_build_value(&rdst->host->index, T_INTEGER);
00412 args[5] = __mgk_build_value(&dstport, T_INTEGER);
00413 if (__mgk_remote_call(rsrc->host,
00414 cmd_disconnect_nodes,
00415 6, args,
00416 1, rargs)) {
00417 errp = __mgk_extract_value(rargs[0], &t, &s);
00418 mgk_errno = (t == T_INTEGER) ? *errp : E_COMM;
00419 }
00420 else {
00421 mgk_errno = E_COMM;
00422 }
00423 }
00424 else {
00425 mgk_errno = E_SUCCESS;
00426 }
00427 if (mgk_errno == E_SUCCESS) {
00428 *slpp = slp->l.l2r.nextout;
00429 if (slp->l.l2r.active) {
00430 slp->l.l2r.active->backlink = NULL;
00431 }
00432 FREE_mgk_link(slp);
00433 }
00434 return (mgk_errno);
00435 }
00436 if (slp != dlp) {
00437 return (mgk_errno = E_GENERROR);
00438 }
00439 *slpp = slp->l.l2l.nextout;
00440 *dlpp = dlp->l.l2l.nextin;
00441 FREE_mgk_link(slp);
00442 return (mgk_errno = E_SUCCESS);
00443 }
00444
00445 mgk_error_code
00446 mgk_disconnect_nodes(mgk_nodep src, unsigned int srcport,
00447 mgk_nodep dst, unsigned int dstport)
00448 {
00449 return (do_disconnect(src, srcport, dst, dstport, TRUE));
00450 }
00451
00452 DEFSVC(disconnect_nodes)
00453 {
00454 if ((argc == 6) && (rargc == 1)) {
00455 mgk_data_type t1, t2, t3, t4, t5, t6;
00456 long *sidp = __mgk_parse_value(argv[0], &t1);
00457 int *shixp = __mgk_parse_value(argv[1], &t2);
00458 int *sidxp = __mgk_parse_value(argv[2], &t3);
00459 long *didp = __mgk_parse_value(argv[3], &t4);
00460 int *dhixp = __mgk_parse_value(argv[4], &t5);
00461 int *didxp = __mgk_parse_value(argv[5], &t6);
00462 if ((t1 == T_LONGINT) && (t2 == T_INTEGER) && (t3 == T_INTEGER) &&
00463 (t4 == T_LONGINT) && (t5 == T_INTEGER) && (t6 == T_INTEGER)) {
00464 mgk_node *src = __mgk_locate_node(*shixp, *sidp);
00465 mgk_node *dst = __mgk_locate_node(*dhixp, *didp);
00466 do_disconnect(src, *sidxp, dst, *didxp, FALSE);
00467 rargv[0] = __mgk_build_value(&mgk_errno, T_INTEGER);
00468 return (TRUE);
00469 }
00470 }
00471 return (FALSE);
00472 }