Annotation of 43BSDReno/contrib/isode-beta/rosap/ro2ps.c, revision 1.1

1.1     ! root        1: /* ro2ps.c - ROPM: PSAP interface */
        !             2: 
        !             3: #ifndef        lint
        !             4: static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ps.c,v 7.1 90/07/01 21:05:43 mrose Exp $";
        !             5: #endif
        !             6: 
        !             7: /* 
        !             8:  * $Header: /f/osi/rosap/RCS/ro2ps.c,v 7.1 90/07/01 21:05:43 mrose Exp $
        !             9:  *
        !            10:  * Based on an TCP-based implementation by George Michaelson of University
        !            11:  * College London.
        !            12:  *
        !            13:  *
        !            14:  * $Log:       ro2ps.c,v $
        !            15:  * Revision 7.1  90/07/01  21:05:43  mrose
        !            16:  * pepsy
        !            17:  * 
        !            18:  * Revision 6.0  89/03/18  23:42:08  mrose
        !            19:  * Release 5.0
        !            20:  * 
        !            21:  */
        !            22: 
        !            23: /*
        !            24:  *                               NOTICE
        !            25:  *
        !            26:  *    Acquisition, use, and distribution of this module and related
        !            27:  *    materials are subject to the restrictions of a license agreement.
        !            28:  *    Consult the Preface in the User's Manual for the full terms of
        !            29:  *    this agreement.
        !            30:  *
        !            31:  */
        !            32: 
        !            33: 
        !            34: /* LINTLIBRARY */
        !            35: 
        !            36: #include <stdio.h>
        !            37: #include "ROS-types.h"
        !            38: #include "ropkt.h"
        !            39: #include "tailor.h"
        !            40: 
        !            41: /*    DATA */
        !            42: 
        !            43: int    acslose ();
        !            44: 
        !            45: int    pslose ();
        !            46: int    psDATAser (), psTOKENser (), psSYNCser (), psACTIVITYser (),
        !            47:        psREPORTser (), psFINISHser (), psABORTser ();
        !            48: 
        !            49: /*    bind underlying service */
        !            50: 
        !            51: int    RoPService (acb, roi)
        !            52: register struct assocblk   *acb;
        !            53: struct RoSAPindication *roi;
        !            54: {
        !            55:     if (!(acb -> acb_flags & ACB_ACS) || (acb -> acb_flags & ACB_RTS))
        !            56:        return rosaplose (roi, ROS_OPERATION, NULLCP,
        !            57:                "not an association descriptor for ROS on presentation");
        !            58: 
        !            59:     acb -> acb_putosdu = ro2pswrite;
        !            60:     acb -> acb_rowaitrequest = ro2pswait;
        !            61:     acb -> acb_ready = NULLIFP;
        !            62:     acb -> acb_rosetindications = ro2psasync;
        !            63:     acb -> acb_roselectmask = ro2psmask;
        !            64:     acb -> acb_ropktlose = NULLIFP;
        !            65: 
        !            66:     return OK;
        !            67: }
        !            68: 
        !            69: /*    define vectors for INDICATION events */
        !            70: 
        !            71: #define        e(i)    (indication ? (i) : NULLIFP)
        !            72: 
        !            73: 
        !            74: /* ARGSUSED */
        !            75: 
        !            76: int    ro2psasync (acb, indication, roi)
        !            77: register struct assocblk   *acb;
        !            78: IFP    indication;
        !            79: struct RoSAPindication *roi;
        !            80: {
        !            81:     struct PSAPindication   pis;
        !            82:     register struct PSAPabort  *pa = &pis.pi_abort;
        !            83: 
        !            84:     if (PSetIndications (acb -> acb_fd, e (psDATAser), e (psTOKENser),
        !            85:                e (psSYNCser), e (psACTIVITYser), e (psREPORTser),
        !            86:                e (psFINISHser), e (psABORTser), &pis) == NOTOK)
        !            87:        switch (pa -> pa_reason) {
        !            88:            case PC_WAITING: 
        !            89:                return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
        !            90: 
        !            91:            default: 
        !            92:                (void) pslose (acb, roi, "PSetIndications", pa);
        !            93:                freeacblk (acb);
        !            94:                return NOTOK;
        !            95:        }
        !            96: 
        !            97:     if (acb -> acb_rosindication = indication)
        !            98:        acb -> acb_flags |= ACB_ASYN;
        !            99:     else
        !           100:        acb -> acb_flags &= ~ACB_ASYN;
        !           101: 
        !           102:     return OK;
        !           103: }
        !           104: 
        !           105: #undef e
        !           106: 
        !           107: /*    map association descriptors for select() */
        !           108: 
        !           109: /* ARGSUSED */
        !           110: 
        !           111: int    ro2psmask (acb, mask, nfds, roi)
        !           112: register struct assocblk   *acb;
        !           113: fd_set *mask;
        !           114: int    *nfds;
        !           115: struct RoSAPindication *roi;
        !           116: {
        !           117:     struct PSAPindication   pis;
        !           118:     struct PSAPabort   *pa = &pis.pi_abort;
        !           119: 
        !           120:     if (PSelectMask (acb -> acb_fd, mask, nfds, &pis) == NOTOK)
        !           121:        switch (pa -> pa_reason) {
        !           122:            case PC_WAITING: 
        !           123:                return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
        !           124: 
        !           125:            default: 
        !           126:                (void) pslose (acb, roi, "PSelectMask", pa);
        !           127:                freeacblk (acb);
        !           128:                return NOTOK;
        !           129:        }
        !           130: 
        !           131:     return OK;
        !           132: }
        !           133: 
        !           134: /*    AcSAP interface */
        !           135: 
        !           136: static int acslose (acb, roi, event, aca)
        !           137: register struct assocblk *acb;
        !           138: register struct RoSAPindication *roi;
        !           139: char   *event;
        !           140: register struct AcSAPabort *aca;
        !           141: {
        !           142:     int     reason;
        !           143:     char   *cp,
        !           144:             buffer[BUFSIZ];
        !           145: 
        !           146:     if (event)
        !           147:        SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP,
        !           148:              (aca -> aca_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event,
        !           149:               AcErrString (aca -> aca_reason), aca -> aca_cc, aca -> aca_cc,
        !           150:               aca -> aca_data));
        !           151: 
        !           152:     cp = "";
        !           153:     switch (aca -> aca_reason) {
        !           154:        case ACS_ADDRESS: 
        !           155:            reason = ROS_ADDRESS;
        !           156:            break;
        !           157: 
        !           158:        case ACS_REFUSED:
        !           159:            reason = ROS_REFUSED;
        !           160:            break;
        !           161: 
        !           162:        case ACS_CONGEST: 
        !           163:            reason = ROS_CONGEST;
        !           164:            break;
        !           165: 
        !           166:        default: 
        !           167:            (void) sprintf (cp = buffer, " (%s at association control)",
        !           168:                    AcErrString (aca -> aca_reason));
        !           169:        case ACS_PRESENTATION:
        !           170:            reason = ROS_ACS;
        !           171:            break;
        !           172:     }
        !           173: 
        !           174:     if (aca -> aca_cc > 0)
        !           175:        return ropktlose (acb, roi, reason, NULLCP, "%*.*s%s",
        !           176:                aca -> aca_cc, aca -> aca_cc, aca -> aca_data, cp);
        !           177:     else
        !           178:        return ropktlose (acb, roi, reason, NULLCP, "%s", cp);
        !           179: }
        !           180: 
        !           181: /*    PSAP interface */
        !           182: 
        !           183: int    ro2pswait (acb, invokeID, secs, roi)
        !           184: register struct assocblk *acb;
        !           185: int    *invokeID,
        !           186:        secs;
        !           187: register struct RoSAPindication *roi;
        !           188: {
        !           189:     int     result;
        !           190:     struct PSAPdata pxs;
        !           191:     register struct PSAPdata   *px = &pxs;
        !           192:     struct PSAPindication   pis;
        !           193:     register struct PSAPindication *pi = &pis;
        !           194: 
        !           195:     for (;;) {
        !           196:        switch (result = PReadRequest (acb -> acb_fd, px, secs, pi)) {
        !           197:            case NOTOK: 
        !           198:                return doPSabort (acb, &pi -> pi_abort, roi);
        !           199: 
        !           200:            case OK: 
        !           201:                if ((result = doPSdata (acb, invokeID, px, roi)) != OK)
        !           202:                    return (result != DONE ? result : OK);
        !           203:                continue;
        !           204: 
        !           205:            case DONE: 
        !           206:                switch (pi -> pi_type) {
        !           207:                    case PI_TOKEN: 
        !           208:                        if (doPStokens (acb, &pi -> pi_token, roi) == NOTOK)
        !           209:                            return NOTOK;
        !           210:                        continue;
        !           211: 
        !           212:                    case PI_SYNC: 
        !           213:                        if (doPSsync (acb, &pi -> pi_sync, roi) == NOTOK)
        !           214:                            return NOTOK;
        !           215:                        continue;
        !           216: 
        !           217:                    case PI_ACTIVITY: 
        !           218:                        if (doPSactivity (acb, &pi -> pi_activity, roi) == NOTOK)
        !           219:                            return NOTOK;
        !           220:                        continue;
        !           221: 
        !           222:                    case PI_REPORT: 
        !           223:                        if (doPSreport (acb, &pi -> pi_report, roi) == NOTOK)
        !           224:                            return NOTOK;
        !           225:                        continue;
        !           226: 
        !           227:                    case PI_FINISH: 
        !           228:                        if (doPSfinish (acb, &pi -> pi_finish, roi) == NOTOK)
        !           229:                            return NOTOK;
        !           230:                        return DONE;
        !           231: 
        !           232:                    default: 
        !           233:                        (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
        !           234:                                "unknown indication (0x%x) from presentation",
        !           235:                                pi -> pi_type);
        !           236:                        break;
        !           237:                }
        !           238:                break;
        !           239: 
        !           240:            default: 
        !           241:                (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
        !           242:                        "unexpected return from PReadRequest=%d", result);
        !           243:                break;
        !           244:        }
        !           245:        break;
        !           246:     }
        !           247: 
        !           248:     freeacblk (acb);
        !           249: 
        !           250:     return NOTOK;
        !           251: }
        !           252: 
        !           253: /*  */
        !           254: 
        !           255: /* ARGSUSED */
        !           256: 
        !           257: int    ro2pswrite (acb, pe, fe, priority, roi)
        !           258: register struct assocblk *acb;
        !           259: PE     pe,
        !           260:        fe;
        !           261: int    priority;
        !           262: struct RoSAPindication *roi;
        !           263: {
        !           264:     int            result;
        !           265:     struct PSAPindication   pis;
        !           266:     register struct PSAPabort  *pa = &pis.pi_abort;
        !           267: 
        !           268:     pe -> pe_context = acb -> acb_rosid;
        !           269: 
        !           270:     PLOGP (rosap_log,ROS_ROSEapdus, pe, "ROSEapdus", 0);
        !           271: 
        !           272:     if ((result = PDataRequest (acb -> acb_fd, &pe, 1, &pis)) == NOTOK) {
        !           273:        (void) pslose (acb, roi, "PDataRequest", pa);   
        !           274:        freeacblk (acb);
        !           275:     }
        !           276:     
        !           277:     if (fe)
        !           278:        (void) pe_extract (pe, fe);
        !           279:     pe_free (pe);
        !           280: 
        !           281:     return result;
        !           282: }
        !           283: 
        !           284: /*  */
        !           285: 
        !           286: static int  doPSdata (acb, invokeID, px, roi)
        !           287: register struct assocblk   *acb;
        !           288: int    *invokeID;
        !           289: register struct PSAPdata *px;
        !           290: struct RoSAPindication *roi;
        !           291: {
        !           292:     register PE            pe;
        !           293: 
        !           294:     if (px -> px_type != SX_NORMAL) {
        !           295:        (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
        !           296:                "unexpected data indication (0x%x)", px -> px_type);
        !           297:        PXFREE (px);
        !           298: 
        !           299:        freeacblk (acb);
        !           300:        return NOTOK;
        !           301:     }
        !           302: 
        !           303:     pe = px -> px_info[0], px -> px_info[0] = NULLPE;
        !           304:     PXFREE (px);
        !           305: 
        !           306:     return acb2osdu (acb, invokeID, pe, roi);
        !           307: }
        !           308: 
        !           309: /*  */
        !           310: 
        !           311: static int  doPStokens (acb, pt, roi)
        !           312: register struct assocblk   *acb;
        !           313: register struct PSAPtoken *pt;
        !           314: struct RoSAPindication *roi;
        !           315: {
        !           316:     (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
        !           317:            "unexpected token indication (0x%x)", pt -> pt_type);
        !           318:     PTFREE (pt);
        !           319: 
        !           320:     freeacblk (acb);
        !           321:     return NOTOK;
        !           322: }
        !           323: 
        !           324: /*  */
        !           325: 
        !           326: static int  doPSsync (acb, pn, roi)
        !           327: register struct assocblk   *acb;
        !           328: register struct PSAPsync *pn;
        !           329: struct RoSAPindication *roi;
        !           330: {
        !           331:     (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
        !           332:            "unexpected sync indication (0x%x)", pn -> pn_type);
        !           333:     PNFREE (pn);
        !           334: 
        !           335:     freeacblk (acb);
        !           336:     return NOTOK;
        !           337: }
        !           338: 
        !           339: /*  */
        !           340: 
        !           341: static int  doPSactivity (acb, pv, roi)
        !           342: register struct assocblk   *acb;
        !           343: register struct PSAPactivity *pv;
        !           344: struct RoSAPindication *roi;
        !           345: {
        !           346:     (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
        !           347:            "unexpected activity indication (0x%x)", pv -> pv_type);
        !           348:     PVFREE (pv);
        !           349: 
        !           350:     freeacblk (acb);
        !           351:     return NOTOK;
        !           352: }
        !           353: 
        !           354: /*  */
        !           355: 
        !           356: static int  doPSreport (acb, pp, roi)
        !           357: register struct assocblk   *acb;
        !           358: register struct PSAPreport *pp;
        !           359: struct RoSAPindication *roi;
        !           360: {
        !           361:     (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
        !           362:            "unexpected exception report indication (0x%x)", pp -> pp_peer);
        !           363:     PPFREE (pp);
        !           364: 
        !           365:     freeacblk (acb);
        !           366:     return NOTOK;
        !           367: }
        !           368: 
        !           369: /*  */
        !           370: 
        !           371: /* ARGSUSED */
        !           372: 
        !           373: static int  doPSfinish (acb, pf, roi)
        !           374: register struct assocblk   *acb;
        !           375: struct PSAPfinish *pf;
        !           376: struct RoSAPindication *roi;
        !           377: {
        !           378:     struct AcSAPindication acis;
        !           379:     register struct AcSAPabort *aca = &acis.aci_abort;
        !           380: 
        !           381:     if (acb -> acb_flags & ACB_INIT) {
        !           382:        (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
        !           383:                "association management botched");
        !           384:        PFFREE (pf);
        !           385:        freeacblk (acb);
        !           386:        return NOTOK;
        !           387:     }
        !           388: 
        !           389:     roi -> roi_type = ROI_FINISH;
        !           390:     {
        !           391:        register struct AcSAPfinish   *acf = &roi -> roi_finish;
        !           392: 
        !           393:        if (AcFINISHser (acb -> acb_fd, pf, &acis) == NOTOK)
        !           394:            return acslose (acb, roi, "AcFINISHser", aca);
        !           395: 
        !           396:        *acf = acis.aci_finish; /* struct copy */
        !           397:     }
        !           398: 
        !           399:     return DONE;
        !           400: }
        !           401: 
        !           402: /*  */
        !           403: 
        !           404: static int  doPSabort (acb, pa, roi)
        !           405: register struct assocblk   *acb;
        !           406: register struct PSAPabort *pa;
        !           407: struct RoSAPindication *roi;
        !           408: {
        !           409:     struct AcSAPindication acis;
        !           410:     register struct AcSAPabort *aca = &acis.aci_abort;
        !           411: 
        !           412:     if (!pa -> pa_peer && pa -> pa_reason == PC_TIMER)
        !           413:        return rosaplose (roi, ROS_TIMER, NULLCP, NULLCP);
        !           414: 
        !           415:     if (AcABORTser (acb -> acb_fd, pa, &acis) == NOTOK) {
        !           416:        (void) acslose (acb, roi, "AcABORTser", aca);
        !           417:        goto out;
        !           418:     }
        !           419: 
        !           420:     if (aca -> aca_source != ACA_USER)
        !           421:        (void) acslose (acb, roi, NULLCP, aca);
        !           422:     else
        !           423:        (void) rosaplose (roi, ROS_ABORTED, NULLCP, NULLCP);
        !           424: 
        !           425:     /* XXX: perhaps should pass data up? */
        !           426:     ACAFREE (aca);
        !           427: 
        !           428: out: ;
        !           429:     acb -> acb_fd = NOTOK;
        !           430:     freeacblk (acb);
        !           431: 
        !           432:     return NOTOK;
        !           433: }
        !           434: 
        !           435: /*  */
        !           436: 
        !           437: static int  psDATAser (sd, px)
        !           438: int    sd;
        !           439: register struct PSAPdata *px;
        !           440: {
        !           441:     IFP            handler;
        !           442:     register struct assocblk   *acb;
        !           443:     struct RoSAPindication  rois;
        !           444:     register struct RoSAPindication *roi = &rois;
        !           445: 
        !           446:     if ((acb = findacblk (sd)) == NULL)
        !           447:        return;
        !           448:     handler = acb -> acb_rosindication;
        !           449: 
        !           450:     if (doPSdata (acb, NULLIP, px, roi) != OK)
        !           451:        (*handler) (sd, roi);
        !           452: }
        !           453: 
        !           454: /*  */
        !           455: 
        !           456: static int  psTOKENser (sd, pt)
        !           457: int    sd;
        !           458: register struct PSAPtoken *pt;
        !           459: {
        !           460:     IFP            handler;
        !           461:     register struct assocblk   *acb;
        !           462:     struct RoSAPindication  rois;
        !           463:     register struct RoSAPindication *roi = &rois;
        !           464: 
        !           465:     if ((acb = findacblk (sd)) == NULL)
        !           466:        return;
        !           467:     handler = acb -> acb_rosindication;
        !           468: 
        !           469:     if (doPStokens (acb, pt, roi) != OK)
        !           470:        (*handler) (sd, roi);
        !           471: }
        !           472: 
        !           473: /*  */
        !           474: 
        !           475: static int  psSYNCser (sd, pn)
        !           476: int    sd;
        !           477: register struct PSAPsync *pn;
        !           478: {
        !           479:     IFP            handler;
        !           480:     register struct assocblk   *acb;
        !           481:     struct RoSAPindication  rois;
        !           482:     register struct RoSAPindication *roi = &rois;
        !           483: 
        !           484:     if ((acb = findacblk (sd)) == NULL)
        !           485:        return;
        !           486:     handler = acb -> acb_rosindication;
        !           487: 
        !           488:     if (doPSsync (acb, pn, roi) != OK)
        !           489:        (*handler) (sd, roi);
        !           490: }
        !           491: 
        !           492: /*  */
        !           493: 
        !           494: static int  psACTIVITYser (sd, pv)
        !           495: int    sd;
        !           496: register struct PSAPactivity *pv;
        !           497: {
        !           498:     IFP            handler;
        !           499:     register struct assocblk   *acb;
        !           500:     struct RoSAPindication  rois;
        !           501:     register struct RoSAPindication *roi = &rois;
        !           502: 
        !           503:     if ((acb = findacblk (sd)) == NULL)
        !           504:        return;
        !           505:     handler = acb -> acb_rosindication;
        !           506: 
        !           507:     if (doPSactivity (acb, pv, roi) != OK)
        !           508:        (*handler) (sd, roi);
        !           509: }
        !           510: 
        !           511: /*  */
        !           512: 
        !           513: static int  psREPORTser (sd, pp)
        !           514: int    sd;
        !           515: register struct PSAPreport *pp;
        !           516: {
        !           517:     IFP            handler;
        !           518:     register struct assocblk   *acb;
        !           519:     struct RoSAPindication  rois;
        !           520:     register struct RoSAPindication *roi = &rois;
        !           521: 
        !           522:     if ((acb = findacblk (sd)) == NULL)
        !           523:        return;
        !           524:     handler = acb -> acb_rosindication;
        !           525: 
        !           526:     if (doPSreport (acb, pp, roi) != OK)
        !           527:        (*handler) (sd, roi);
        !           528: }
        !           529: 
        !           530: /*  */
        !           531: 
        !           532: static int  psFINISHser (sd, pf)
        !           533: int    sd;
        !           534: struct PSAPfinish *pf;
        !           535: {
        !           536:     IFP            handler;
        !           537:     register struct assocblk   *acb;
        !           538:     struct RoSAPindication  rois;
        !           539:     register struct RoSAPindication *roi = &rois;
        !           540: 
        !           541:     if ((acb = findacblk (sd)) == NULL)
        !           542:        return;
        !           543:     handler = acb -> acb_rosindication;
        !           544: 
        !           545:     (void) doPSfinish (acb, pf, roi);
        !           546: 
        !           547:     (*handler) (sd, roi);
        !           548: }
        !           549: 
        !           550: /*  */
        !           551: 
        !           552: static int  psABORTser (sd, pa)
        !           553: int    sd;
        !           554: register struct PSAPabort *pa;
        !           555: {
        !           556:     IFP            handler;
        !           557:     register struct assocblk   *acb;
        !           558:     struct RoSAPindication  rois;
        !           559:     register struct RoSAPindication *roi = &rois;
        !           560: 
        !           561:     if ((acb = findacblk (sd)) == NULL)
        !           562:        return;
        !           563:     handler = acb -> acb_rosindication;
        !           564: 
        !           565:     (void) doPSabort (acb, pa, roi);
        !           566: 
        !           567:     (*handler) (sd, roi);
        !           568: }
        !           569: 
        !           570: /*  */
        !           571: 
        !           572: static int pslose (acb, roi, event, pa)
        !           573: register struct assocblk *acb;
        !           574: register struct RoSAPindication *roi;
        !           575: char   *event;
        !           576: register struct PSAPabort *pa;
        !           577: {
        !           578:     int     reason;
        !           579:     char   *cp,
        !           580:             buffer[BUFSIZ];
        !           581: 
        !           582:     if (event)
        !           583:        SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP,
        !           584:              (pa -> pa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event,
        !           585:               PErrString (pa -> pa_reason), pa -> pa_cc, pa -> pa_cc,
        !           586:               pa -> pa_data));
        !           587: 
        !           588:     cp = "";
        !           589:     switch (pa -> pa_reason) {
        !           590:        case PC_ADDRESS: 
        !           591:            reason = ROS_ADDRESS;
        !           592:            break;
        !           593: 
        !           594:        case PC_REFUSED:
        !           595:            reason = ROS_REFUSED;
        !           596:            break;
        !           597: 
        !           598:        case PC_CONGEST: 
        !           599:            reason = ROS_CONGEST;
        !           600:            break;
        !           601: 
        !           602:        default: 
        !           603:            (void) sprintf (cp = buffer, " (%s at presentation)",
        !           604:                    PErrString (pa -> pa_reason));
        !           605:        case PC_SESSION:
        !           606:            reason = ROS_PRESENTATION;
        !           607:            break;
        !           608:     }
        !           609: 
        !           610:     if (pa -> pa_cc > 0)
        !           611:        return ropktlose (acb, roi, reason, NULLCP, "%*.*s%s",
        !           612:                pa -> pa_cc, pa -> pa_cc, pa -> pa_data, cp);
        !           613:     else
        !           614:        return ropktlose (acb, roi, reason, NULLCP, "%s", *cp ? cp + 1 : cp);
        !           615: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.