## modules/up/src/rpsl/rpsl/rpsl_attr.cc

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. print
2. print
3. print
4. print
5. print
6. print
7. print
8. print
9. print
10. print
11. print
12. print
13. print
14. print
15. print
16. print
17. searchMethod
18. searchNextMethod
19. startMandatoryCheck
20. missingMandatoryOption
21. searchOption
22. searchNextOption
23. searchOption
24. validateArgs
25. reset
26. searchAttr
27. validate
28. print
29. print
30. print

       1 //  $Id: rpsl_attr.cc,v 1.1.1.1 2000/03/10 16:32:23 engin Exp $
       2 //
       3 //  Copyright (c) 1994 by the University of Southern California
       4 //  All rights reserved.
       5 //
       6 //  Permission to use, copy, modify, and distribute this software and its
       7 //  documentation in source and binary forms for lawful non-commercial
       8 //  purposes and without fee is hereby granted, provided that the above
       9 //  copyright notice appear in all copies and that both the copyright
      10 //  notice and this permission notice appear in supporting documentation,
      11 //  and that any documentation, advertising materials, and other materials
      12 //  related to such distribution and use acknowledge that the software was
      13 //  developed by the University of Southern California, Information
      14 //  Sciences Institute. The name of the USC may not be used to endorse or
      15 //  promote products derived from this software without specific prior
      16 //  written permission.
      17 //
      18 //  THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY
      19 //  REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY
      20 //  PURPOSE.  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
      21 //  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
      22 //  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
      23 //  TITLE, AND NON-INFRINGEMENT.
      24 //
      25 //  IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
      26 //  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT, TORT,
      27 //  OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH, THE USE
      28 //  OR PERFORMANCE OF THIS SOFTWARE.
      29 //
      30 //  Questions concerning this software should be directed to
      31 //  ratoolset@isi.edu.
      32 //
      33 //  Author(s): Cengiz Alaettinoglu <cengiz@ISI.EDU>
      34
      35 #include "config.h"
      36 #include <cstdio>
      37 #include "rpsl_attr.hh"
      38 #include "object.hh"
      39 #include "schema.hh"
      40
      41 //// printing ////////////////////////////////////////////////////////
      42
      43 ostream &Attr::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
      44    if (object && object->contents)
      45       out.write(object->getTextAt(offset), len);
      46    return out;
      47 }
      48
      49 ostream &AttrGeneric::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
      50    out << type->name() << ":\t" << *items;
      51    return out;
      52 }
      53
      54 ostream &AttrImport::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
      55    out << "import: ";
      56    if (fromProt && fromProt->name && strcasecmp(fromProt->name, "BGP4"))
      57       out << "protocol " << fromProt->name << " ";
      58    if (intoProt && intoProt->name && strcasecmp(intoProt->name, "BGP4"))
      59       out << "into " << intoProt->name << " ";
      60    out << *policy;
      61    return out;
      62 }
      63
      64 ostream &AttrExport::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
      65    out << "export: " << *policy;
      66    return out;
      67 }
      68
      69 ostream &AttrDefault::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
      70    out << "default:\tto   " << *peering << "\n";
      71
      72    if (!action->isEmpty())
      73       out << "       \t " << *action << "\n";
      74
      75    if (filter && typeid(filter) != typeid(FilterANY))
      76       out << "       \t networks " << *filter;
      77
      78    return out;
      79 }
      80
      81 ostream &AttrFilter::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
      82    out << "filter: " << *filter;
      83
      84    return out;
      85 }
      86
      87 ostream &AttrPeering::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
      88    out << "peering: " << *peering;
      89
      90    return out;
      91 }
      92
      93 ostream &AttrIfAddr::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
      94    static char buffer[128];
      95    out << "ifaddr:\t" << int2quad(buffer, ifaddr.get_ipaddr())
      96        << " masklen " << ifaddr.get_length();
      97    return out;
      98 }
      99
     100 ostream &AttrPeerOption::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
     101    out << option << "(" << *args << ")";
     102    return out;
     103 }
     104
     105 ostream &AttrPeer::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
     106    out << "peer:\t" << protocol->name
     107        << " " << *peer << " ";
     108    for (AttrPeerOption *nd = options->head(); nd; ) {
     109       nd->print(out);
     110       nd = options->next(nd);
     111       if (nd)
     112          out << ", ";
     113    }
     114    return out;
     115 }
     116
     117 ostream &AttrTypedef::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
     118    if (type)
     119       out << "typedef: " << name << " " << *type;
     120    else
     121       out << "typedef: " << name << "<error in type spec>";
     122    return out;
     123 }
     124
     125 ostream &AttrProtocol::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
     126    out << "protocol: " << name;
     127    for (AttrProtocolOption *nd = options->head(); nd; nd = options->next(nd)) {
     128       nd->print(out);
     129       out << "\n             ";
     130    }
     131    return out;
     132 }
     133
     134 ostream &AttrProtocolOption::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
     135    out << (optional ? " optional " : " mandatory ") << *option << " ";
     136    return out;
     137 }
     138
     139 ostream &AttrMethod::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
     140    out << name << "(";
     141    for (RPTypeNode *n = args->head(); n; ) {
     142       out << *n->type;
     143       n = args->next(n);
     144       if (n)
     145          out << ", ";
     146    }
     147    if (varargs)
     148       out << ", ...";
     149    out << ")";
     150    return out;
     151 }
     152
     153 ostream &AttrRPAttr::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
     154    out << "rp-attribute: " << name;
     155    for (AttrMethod *nd = methods->head(); nd; nd = methods->next(nd))
     156       out << " " << *nd;
     157    return out;
     158 }
     159
     160 ostream &AttrAttr::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
     161    out << "attr: " << _name << " syntax(?) ?";
     162
     163    return out;
     164 }
     165
     166
     167
     168
     169
     170
     171
     172
     173 const AttrMethod *AttrRPAttr::searchMethod(const char *name) const {
         /* [<][>][^][v][top][bottom][index][help] */
     174    char buffer[1024] = "";
     175
     176    if (!isalpha(*name))
     177       strcpy(buffer, "operator");
     178
     179    strcat(buffer, name);
     180
     181    // return method or NULL
     182    for (AttrMethod *m = methods->head(); m; m = methods->next(m))
     183       if (!strcasecmp(m->name, buffer))
     184          return m;
     185
     186    return NULL;
     187 }
     188
     189 const AttrMethod *AttrRPAttr::searchNextMethod(const AttrMethod *last) const {
         /* [<][>][^][v][top][bottom][index][help] */
     190    // return method or NULL
     191    const AttrMethod *m = last;
     192
     193    if (!last)
     194       return NULL;
     195
     196    for (m = methods->next(m); m; m = methods->next(m))
     197       if (!strcasecmp(m->name, last->name))
     198          return m;
     199
     200    return NULL;
     201 }
     202
     203 void AttrProtocol::startMandatoryCheck() {
         /* [<][>][^][v][top][bottom][index][help] */
     204    for (AttrProtocolOption *m = options->head(); m; m = options->next(m))
     205       m->found = false;
     206 }
     207
     208 const AttrProtocolOption *AttrProtocol::missingMandatoryOption() {
         /* [<][>][^][v][top][bottom][index][help] */
     209    AttrProtocolOption *m, *n;
     210
     211    for (m = options->head(); m; m = options->next(m)) {
     212       if (! m->found && ! m->optional)
     213          return m;
     214       if (m->found)
     215          for (n = options->next(m); n; n = options->next(n))
     216             if (!strcasecmp(m->option->name, n->option->name))
     217                n->found = true;
     218    }
     219
     220    return NULL;
     221 }
     222
     223 const AttrProtocolOption *AttrProtocol::searchOption(const char *name) const {
         /* [<][>][^][v][top][bottom][index][help] */
     224    // return method or NULL
     225    for (AttrProtocolOption *m = options->head(); m; m = options->next(m))
     226       if (!strcasecmp(m->option->name, name)) {
     227          m->found = true;
     228          return m;
     229       }
     230
     231    return NULL;
     232 }
     233
     234 const AttrProtocolOption *AttrProtocol::searchNextOption
         /* [<][>][^][v][top][bottom][index][help] */
     235    (const AttrProtocolOption *last) const {
     236    // return method or NULL
     237    AttrProtocolOption *m = (AttrProtocolOption *) last;
     238
     239    if (!last)
     240       return NULL;
     241
     242    for (m = options->next(m); m; m = options->next(m))
     243       if (!strcasecmp(m->option->name, last->option->name)) {
     244          m->found = true;
     245          return m;
     246       }
     247
     248    return NULL;
     249 }
     250
     251 const AttrPeerOption *AttrPeer::searchOption(const char *name) const {
         /* [<][>][^][v][top][bottom][index][help] */
     252    // return method or NULL
     253    for (AttrPeerOption *m = options->head(); m; m = options->next(m))
     254       if (!strcasecmp(m->option, name))
     255          return m;
     256
     257    return NULL;
     258 }
     259
     260 bool AttrMethod::validateArgs(ItemList *actualArgs, int &position,
         /* [<][>][^][v][top][bottom][index][help] */
     261                               const RPType *&correctType) const {
     262    RPTypeNode *tnode = args->head();
     263    Item *arg = actualArgs->head();
     264    position = 0;
     265    Item *arg2;
     266
     267    if (!tnode && !arg)
     268       return true;
     269
     270    if (!tnode)
     271       return false;
     272
     273    position = 1;
     274    correctType = tnode->type;
     275    while (correctType && arg) {
     276       if (!correctType->validate(arg)) {
     277          arg2 = correctType->typeCast(arg);
     278          if (arg2) {
     279             actualArgs->insertAfter(arg, arg2);
     280             actualArgs->remove(arg);
     281             delete arg;
     282             arg = arg2;
     283          } else
     284             return false;
     285       }
     286
     287       position++;
     288       arg = actualArgs->next(arg);
     289       tnode = args->next(tnode);
     290       correctType = tnode ? tnode->type : NULL;
     291    }
     292
     293    if (!correctType && arg && varargs) { // extra args
     294       tnode = args->tail();
     295       correctType = tnode->type;
     296       while (correctType && arg) {
     297          if (!correctType->validate(arg)) {
     298             arg2 = correctType->typeCast(arg);
     299             if (arg2) {
     300                actualArgs->insertAfter(arg, arg2);
     301                actualArgs->remove(arg);
     302                delete arg;
     303                arg = arg2;
     304             } else
     305                return false;
     306          }
     307
     308          arg = actualArgs->next(arg);
     309          position++;
     310       }
     311       correctType = (RPType *) NULL;
     312    }
     313
     314    if (!correctType && !arg)
     315       return true;
     316
     317    position = 0;
     318    return false;
     319 }
     320
     321 void AttrClass::reset() {
         /* [<][>][^][v][top][bottom][index][help] */
     322    for (int i = 0; i < attribs.size(); ++i)
     323       attribs[i]->reset();
     324 }
     325
     326 AttrAttr* AttrClass::searchAttr(const char *name) {
         /* [<][>][^][v][top][bottom][index][help] */
     327    for (int i = 0; i < attribs.size(); ++i)
     328       if (!strcasecmp(name, attribs[i]->name())) {
     329          attribs[i]->touch();
     330          return attribs[i];
     331       }
     332
     333    return NULL;
     334 }
     335
     336 bool AttrClass::validate(string &errors) {
         /* [<][>][^][v][top][bottom][index][help] */
     337    // return true if valid i.e. no error
     338    static char buffer[1024];
     339    bool result = true;
     340
     341    for (int i = 0; i < attribs.size(); ++i) {
     342       if (!attribs[i]->testKey()) {
     343          sprintf(buffer, "***Error: key attribute %s is not specified.\n",
     344                  attribs[i]->name());
     345          errors += buffer;
     346          result = false;
     347       }
     348       if ((!schema.isForgiving() || attribs[i]->isKey())
     349           && !attribs[i]->testMandatory()) {
     350          sprintf(buffer, "***Error: mandatory attribute %s is not specified.\n",
     351                  attribs[i]->name());
     352          errors += buffer;
     353          result = false;
     354       }
     355       if ((!schema.isForgiving() || attribs[i]->isKey())
     356           && !attribs[i]->testSingleValued()) {
     357          sprintf(buffer,
     358                  "***Error: single-valued attribute %s occurs multiple times.\n",
     359                  attribs[i]->name());
     360          errors += buffer;
     361          result = false;
     362       }
     363    if (!attribs[i]->testGenerated()) {
     364          sprintf(buffer,
     365                  "***Error: generated attribute %s cannot appear in an update.\n",
     366                  attribs[i]->name());
     367          errors += buffer;
     368          result = false;
     369       }
     370
     371    }
     372    return result;
     373 }
     374
     375 ostream& AttrClass::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
     376 }
     377
     378 ostream& AttrMntRoutes::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
     379    out << "mnt-routes:";
     380    for (MntPrfxPair *p = mntPrfxList->head(); p; p = mntPrfxList->next(p)) {
     381       out << " " << p->mnt;
     382       if (p->prefixes)
     383          out << " " << p->prefixes;
     384       out << ",\n";
     385    }
     386 }
     387
     388 ostream& AttrTRLabel::print(ostream &out) const {
         /* [<][>][^][v][top][bottom][index][help] */
     389    out << "transaction-label: "
     390        << *source << " " << *seq << " " << *stamp;
     391 }
     392

/* [<][>][^][v][top][bottom][index][help] */