1133211Sharti/* 2159063Sharti * Copyright (C) 2004-2006 3133211Sharti * Hartmut Brandt. 4133211Sharti * All rights reserved. 5133211Sharti * 6128237Sharti * Author: Harti Brandt <harti@freebsd.org> 7133211Sharti * 8133211Sharti * Redistribution and use in source and binary forms, with or without 9133211Sharti * modification, are permitted provided that the following conditions 10133211Sharti * are met: 11133211Sharti * 1. Redistributions of source code must retain the above copyright 12133211Sharti * notice, this list of conditions and the following disclaimer. 13128237Sharti * 2. Redistributions in binary form must reproduce the above copyright 14128237Sharti * notice, this list of conditions and the following disclaimer in the 15128237Sharti * documentation and/or other materials provided with the distribution. 16133211Sharti * 17133211Sharti * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18133211Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19133211Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20133211Sharti * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 21133211Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22133211Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23133211Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24133211Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25133211Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26133211Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27133211Sharti * SUCH DAMAGE. 28128237Sharti * 29159063Sharti * $Begemot: gensnmpdef.c 383 2006-05-30 07:40:49Z brandt_h $ 30128237Sharti */ 31159063Sharti#include <sys/queue.h> 32159063Sharti 33128237Sharti#include <stdio.h> 34128237Sharti#include <stdlib.h> 35128237Sharti#include <string.h> 36128237Sharti#include <unistd.h> 37128237Sharti#include <errno.h> 38128237Sharti#include <err.h> 39128237Sharti#include <assert.h> 40128237Sharti#include <smi.h> 41128237Sharti 42128237Shartistatic const char usgtxt[] = 43159063Sharti"Usage: gensnmpdef [-hEe] [-c <cut>] MIB [MIB ...]\n" 44128237Sharti"Options:\n" 45128237Sharti" -c specify the number of initial sub-oids to cut from the oids\n" 46159063Sharti" -E extract named enum types. Print a typedef for all enums defined\n" 47159063Sharti" in syntax clauses of normal objects. Suppress normal output.\n" 48159063Sharti" -e extract unnamed enum types. Print a typedef for all enums defined\n" 49159063Sharti" as textual conventions. Suppress normal output.\n" 50128237Sharti" -h print this help\n" 51128237Sharti"MIBs are searched according to the libsmi(3) search rules and can\n" 52128237Sharti"be specified either by path or module name\n"; 53128237Sharti 54128237Shartistatic SmiNode *last_node; 55128237Shartistatic u_int cut = 3; 56128237Sharti 57159063Shartistruct tdef { 58159063Sharti char *name; 59159063Sharti SLIST_ENTRY(tdef) link; 60159063Sharti}; 61159063Sharti 62205729Santoinestatic SLIST_HEAD(, tdef) tdefs = SLIST_HEAD_INITIALIZER(tdefs); 63159063Shartistatic int do_typedef = 0; 64159063Sharti 65128237Shartistatic void print_node(SmiNode *n, u_int level); 66128237Sharti 67128237Shartistatic void 68128237Shartisave_node(SmiNode *n) 69128237Sharti{ 70128237Sharti if (n != NULL) 71128237Sharti last_node = n; 72128237Sharti} 73128237Sharti 74128237Shartistatic void 75128237Shartipindent(u_int level) 76128237Sharti{ 77128237Sharti if (level >= cut) 78128237Sharti printf("%*s", (level - cut) * 2, ""); 79128237Sharti} 80128237Sharti 81128237Shartistatic void 82128237Shartiprint_name(SmiNode *n) 83128237Sharti{ 84128237Sharti char *p; 85128237Sharti 86128237Sharti for (p = n->name; *p != '\0'; p++) { 87128237Sharti if (*p == '-') 88128237Sharti printf("_"); 89128237Sharti else 90128237Sharti printf("%c", *p); 91128237Sharti } 92128237Sharti} 93128237Sharti 94128237Shartistatic u_int 95128237Sharticlose_node(u_int n, u_int level) 96128237Sharti{ 97128237Sharti while (n--) { 98128237Sharti pindent(level); 99128237Sharti level--; 100128237Sharti if (level >= cut) 101128237Sharti printf(")\n"); 102128237Sharti } 103128237Sharti return (level); 104128237Sharti} 105128237Sharti 106128237Shartistatic u_int 107128237Shartiopen_node(const SmiNode *n, u_int level, SmiNode **last) 108128237Sharti{ 109128237Sharti SmiNode *n1; 110128237Sharti u_int i; 111128237Sharti 112128237Sharti if (*last != NULL) { 113128237Sharti for (i = 0; i < (*last)->oidlen - 1; i++) { 114128237Sharti if (i >= n->oidlen) { 115128237Sharti level = close_node((*last)->oidlen - 116128237Sharti n->oidlen, level); 117128237Sharti break; 118128237Sharti } 119128237Sharti if ((*last)->oid[i] != n->oid[i]) 120128237Sharti break; 121128237Sharti } 122128237Sharti if (i < (*last)->oidlen - 1) 123128237Sharti level = close_node((*last)->oidlen - 1 - i, 124128237Sharti level - 1) + 1; 125128237Sharti } 126128237Sharti 127128237Sharti while (level < n->oidlen - 1) { 128128237Sharti if (level >= cut) { 129128237Sharti pindent(level); 130128237Sharti printf("(%u", n->oid[level]); 131128237Sharti n1 = smiGetNodeByOID(level + 1, n->oid); 132128237Sharti printf(" "); 133128237Sharti print_name(n1); 134128237Sharti printf("\n"); 135128237Sharti } 136128237Sharti level++; 137128237Sharti } 138128237Sharti return (level); 139128237Sharti} 140128237Sharti 141128237Shartistatic const char *const type_names[] = { 142128237Sharti [SMI_BASETYPE_UNKNOWN] = "UNKNOWN_TYPE", 143128237Sharti [SMI_BASETYPE_INTEGER32] = "INTEGER", 144128237Sharti [SMI_BASETYPE_OCTETSTRING] = "OCTETSTRING", 145128237Sharti [SMI_BASETYPE_OBJECTIDENTIFIER] = "OID", 146128237Sharti [SMI_BASETYPE_UNSIGNED32] = "UNSIGNED32", 147128237Sharti [SMI_BASETYPE_INTEGER64] = "INTEGER64", 148128237Sharti [SMI_BASETYPE_UNSIGNED64] = "UNSIGNED64", 149128237Sharti [SMI_BASETYPE_FLOAT32] = "FLOAT32", 150128237Sharti [SMI_BASETYPE_FLOAT64] = "FLOAT64", 151128237Sharti [SMI_BASETYPE_FLOAT128] = "FLOAT128", 152159063Sharti [SMI_BASETYPE_ENUM] = "ENUM", 153128237Sharti [SMI_BASETYPE_BITS] = "BITS", 154128237Sharti}; 155128237Sharti 156128237Shartistatic const char *const type_map[] = { 157128237Sharti "Gauge32", "GAUGE", 158128237Sharti "Gauge", "GAUGE", 159128237Sharti "TimeTicks", "TIMETICKS", 160128237Sharti "Counter32", "COUNTER", 161128237Sharti "Counter", "COUNTER", 162128237Sharti "Counter64", "COUNTER64", 163128237Sharti "Integer32", "INTEGER32", 164128237Sharti "IpAddress", "IPADDRESS", 165128237Sharti NULL 166128237Sharti}; 167128237Sharti 168128237Shartistatic void 169159063Shartiprint_enum(SmiType *t) 170159063Sharti{ 171159063Sharti SmiNamedNumber *nnum; 172159063Sharti 173159063Sharti printf(" ("); 174159063Sharti for (nnum = smiGetFirstNamedNumber(t); nnum != NULL; 175159063Sharti nnum = smiGetNextNamedNumber(nnum)) 176159063Sharti printf(" %ld %s", nnum->value.value.integer32, nnum->name); 177159063Sharti printf(" )"); 178159063Sharti} 179159063Sharti 180159063Shartistatic void 181128237Shartiprint_type(SmiNode *n) 182128237Sharti{ 183128237Sharti SmiType *type; 184128237Sharti u_int m; 185128237Sharti 186128237Sharti type = smiGetNodeType(n); 187128237Sharti assert(type != NULL); 188128237Sharti 189128237Sharti if (type->name != NULL) { 190128237Sharti for (m = 0; type_map[m] != NULL; m += 2) 191128237Sharti if (strcmp(type_map[m], type->name) == 0) { 192128237Sharti printf("%s", type_map[m + 1]); 193128237Sharti return; 194128237Sharti } 195128237Sharti } 196128237Sharti printf("%s", type_names[type->basetype]); 197159063Sharti 198159063Sharti if (type->basetype == SMI_BASETYPE_ENUM || 199159063Sharti type->basetype == SMI_BASETYPE_BITS) 200159063Sharti print_enum(type); 201159063Sharti 202159063Sharti else if (type->basetype == SMI_BASETYPE_OCTETSTRING && 203159063Sharti type->name != NULL) 204159063Sharti printf(" | %s", type->name); 205128237Sharti} 206128237Sharti 207128237Shartistatic void 208128237Shartiprint_access(SmiAccess a) 209128237Sharti{ 210128237Sharti if (a == SMI_ACCESS_READ_ONLY) 211128237Sharti printf(" GET"); 212128237Sharti else if (a == SMI_ACCESS_READ_WRITE) 213128237Sharti printf(" GET SET"); 214128237Sharti} 215128237Sharti 216128237Shartistatic void 217128237Shartiprint_scalar(SmiNode *n, u_int level) 218128237Sharti{ 219128237Sharti SmiNode *p; 220128237Sharti 221128237Sharti assert (n->nodekind == SMI_NODEKIND_SCALAR); 222128237Sharti 223128237Sharti save_node(n); 224128237Sharti 225128237Sharti pindent(level); 226128237Sharti printf("(%u ", n->oid[level]); 227128237Sharti print_name(n); 228128237Sharti printf(" "); 229128237Sharti print_type(n); 230128237Sharti 231128237Sharti /* generate the operation from the parent node name */ 232128237Sharti p = smiGetParentNode(n); 233128237Sharti printf(" op_%s", p->name); 234128237Sharti 235128237Sharti print_access(n->access); 236128237Sharti 237128237Sharti printf(")\n"); 238128237Sharti} 239128237Sharti 240128237Shartistatic void 241128237Shartiprint_notification(SmiNode *n, u_int level) 242128237Sharti{ 243128237Sharti 244128237Sharti assert (n->nodekind == SMI_NODEKIND_NOTIFICATION); 245128237Sharti 246128237Sharti save_node(n); 247128237Sharti 248128237Sharti pindent(level); 249128237Sharti printf("(%u ", n->oid[level]); 250128237Sharti print_name(n); 251128237Sharti printf(" OID"); 252128237Sharti 253128237Sharti printf(" op_%s)\n", n->name); 254128237Sharti} 255128237Sharti 256128237Shartistatic void 257128237Shartiprint_col(SmiNode *n, u_int level) 258128237Sharti{ 259128237Sharti assert (n->nodekind == SMI_NODEKIND_COLUMN); 260128237Sharti 261128237Sharti save_node(n); 262128237Sharti 263128237Sharti pindent(level); 264128237Sharti printf("(%u ", n->oid[level]); 265128237Sharti print_name(n); 266128237Sharti printf(" "); 267128237Sharti print_type(n); 268128237Sharti print_access(n->access); 269128237Sharti printf(")\n"); 270128237Sharti} 271128237Sharti 272128237Shartistatic void 273128237Shartiprint_index(SmiNode *row) 274128237Sharti{ 275128237Sharti SmiElement *e; 276128237Sharti 277128237Sharti e = smiGetFirstElement(row); 278128237Sharti while (e != NULL) { 279128237Sharti printf(" "); 280128237Sharti print_type(smiGetElementNode(e)); 281128237Sharti e = smiGetNextElement(e); 282128237Sharti } 283128237Sharti} 284128237Sharti 285128237Shartistatic void 286128237Shartiprint_table(SmiNode *n, u_int level) 287128237Sharti{ 288128237Sharti SmiNode *row, *col, *rel; 289128237Sharti 290128237Sharti assert (n->nodekind == SMI_NODEKIND_TABLE); 291128237Sharti 292128237Sharti save_node(n); 293128237Sharti 294128237Sharti pindent(level); 295128237Sharti printf("(%u ", n->oid[level]); 296128237Sharti print_name(n); 297128237Sharti printf("\n"); 298128237Sharti 299128237Sharti row = smiGetFirstChildNode(n); 300128237Sharti if (row->nodekind != SMI_NODEKIND_ROW) 301128237Sharti errx(1, "%s: kind %u, not row", __func__, row->nodekind); 302128237Sharti 303128237Sharti save_node(n); 304128237Sharti 305128237Sharti pindent(level + 1); 306128237Sharti printf("(%u ", row->oid[level + 1]); 307128237Sharti print_name(row); 308128237Sharti printf(" :"); 309128237Sharti 310128237Sharti /* index */ 311128237Sharti rel = smiGetRelatedNode(row); 312128237Sharti switch (row->indexkind) { 313128237Sharti 314128237Sharti case SMI_INDEX_INDEX: 315128237Sharti print_index(row); 316128237Sharti break; 317128237Sharti 318128237Sharti case SMI_INDEX_AUGMENT: 319128237Sharti if (rel == NULL) 320128237Sharti errx(1, "%s: cannot find augemented table", row->name); 321128237Sharti print_index(rel); 322128237Sharti break; 323128237Sharti 324128237Sharti default: 325128237Sharti errx(1, "%s: cannot handle index kind %u", row->name, 326128237Sharti row->indexkind); 327128237Sharti } 328128237Sharti 329128237Sharti printf(" op_%s", n->name); 330128237Sharti printf("\n"); 331128237Sharti 332128237Sharti col = smiGetFirstChildNode(row); 333128237Sharti while (col != NULL) { 334128237Sharti print_col(col, level + 2); 335128237Sharti col = smiGetNextChildNode(col); 336128237Sharti } 337128237Sharti pindent(level + 1); 338128237Sharti printf(")\n"); 339128237Sharti 340128237Sharti pindent(level); 341128237Sharti printf(")\n"); 342128237Sharti} 343128237Sharti 344128237Shartistatic void 345128237Shartiprint_it(SmiNode *n, u_int level) 346128237Sharti{ 347128237Sharti switch (n->nodekind) { 348128237Sharti 349128237Sharti case SMI_NODEKIND_NODE: 350128237Sharti print_node(n, level); 351128237Sharti break; 352128237Sharti 353128237Sharti case SMI_NODEKIND_SCALAR: 354128237Sharti print_scalar(n, level); 355128237Sharti break; 356128237Sharti 357128237Sharti case SMI_NODEKIND_TABLE: 358128237Sharti print_table(n, level); 359128237Sharti break; 360128237Sharti 361128237Sharti case SMI_NODEKIND_COMPLIANCE: 362128237Sharti case SMI_NODEKIND_GROUP: 363128237Sharti save_node(n); 364128237Sharti break; 365128237Sharti 366128237Sharti case SMI_NODEKIND_NOTIFICATION: 367128237Sharti print_notification(n, level); 368128237Sharti break; 369128237Sharti 370128237Sharti default: 371128237Sharti errx(1, "cannot handle %u nodes", n->nodekind); 372128237Sharti } 373128237Sharti} 374128237Sharti 375128237Shartistatic void 376128237Shartiprint_node(SmiNode *n, u_int level) 377128237Sharti{ 378128237Sharti assert (n->nodekind == SMI_NODEKIND_NODE); 379128237Sharti 380128237Sharti save_node(n); 381128237Sharti 382128237Sharti pindent(level); 383128237Sharti printf("(%u ", n->oid[level]); 384128237Sharti print_name(n); 385128237Sharti printf("\n"); 386128237Sharti 387128237Sharti n = smiGetFirstChildNode(n); 388128237Sharti while (n != NULL) { 389128237Sharti print_it(n, level + 1); 390128237Sharti n = smiGetNextChildNode(n); 391128237Sharti } 392128237Sharti pindent(level); 393128237Sharti printf(")\n"); 394128237Sharti} 395128237Sharti 396159063Shartistatic void 397159063Shartisave_typdef(char *name) 398159063Sharti{ 399159063Sharti struct tdef *t; 400159063Sharti t = malloc(sizeof(struct tdef)); 401159063Sharti 402159063Sharti if (t == NULL) 403159063Sharti err(1, NULL); 404159063Sharti 405159063Sharti memset(t, 0 , sizeof(struct tdef)); 406159063Sharti t->name = name; 407159063Sharti SLIST_INSERT_HEAD(&tdefs, t, link); 408159063Sharti} 409159063Sharti 410159063Shartistatic void 411159063Shartitdefs_cleanup(void) 412159063Sharti{ 413159063Sharti struct tdef *t; 414159063Sharti 415159063Sharti while ((t = SLIST_FIRST(&tdefs)) != NULL) { 416159063Sharti SLIST_REMOVE_HEAD(&tdefs, link); 417159063Sharti free(t); 418159063Sharti } 419159063Sharti} 420159063Sharti 421159063Shartistatic void 422159063Shartiprint_enum_typedef(SmiType *t) 423159063Sharti{ 424159063Sharti SmiNamedNumber *nnum; 425159063Sharti 426159063Sharti for (nnum = smiGetFirstNamedNumber(t); nnum != NULL; 427159063Sharti nnum = smiGetNextNamedNumber(nnum)) { 428159063Sharti printf("\t%ld %s\n" , nnum->value.value.integer32, nnum->name); 429159063Sharti } 430159063Sharti} 431159063Sharti 432159063Shartistatic void 433159063Shartiprint_stype(SmiNode *n) 434159063Sharti{ 435159063Sharti SmiType *type; 436159063Sharti struct tdef *t = NULL; 437159063Sharti 438159063Sharti type = smiGetNodeType(n); 439159063Sharti assert(type != NULL); 440159063Sharti 441159063Sharti if (type->basetype == SMI_BASETYPE_ENUM) { 442159063Sharti if (do_typedef == 'e' && type->name != NULL) { 443159063Sharti SLIST_FOREACH(t, &tdefs, link) { 444159063Sharti if (strcmp(t->name, type->name) == 0) 445159063Sharti return; 446159063Sharti } 447159063Sharti save_typdef(type->name); 448159063Sharti printf("typedef %s ENUM (\n", type->name); 449159063Sharti } else if (do_typedef == 'E' && type->name == NULL) 450159063Sharti printf("typedef %sType ENUM (\n", n->name); 451159063Sharti else 452159063Sharti return; 453159063Sharti 454159063Sharti print_enum_typedef(type); 455159063Sharti printf(")\n\n"); 456159063Sharti 457159063Sharti } else if (type->basetype == SMI_BASETYPE_BITS) { 458159063Sharti if (do_typedef == 'e' && type->name != NULL) { 459159063Sharti SLIST_FOREACH(t, &tdefs, link) { 460159063Sharti if (strcmp(t->name, type->name) == 0) 461159063Sharti return; 462159063Sharti } 463159063Sharti save_typdef(type->name); 464159063Sharti printf("typedef %s BITS (\n", type->name); 465159063Sharti } else if (do_typedef == 'E' && type->name == NULL) 466159063Sharti printf("typedef %sType BITS (\n", n->name); 467159063Sharti else 468159063Sharti return; 469159063Sharti 470159063Sharti print_enum_typedef(type); 471159063Sharti printf(")\n\n"); 472159063Sharti } 473159063Sharti} 474159063Sharti 475159063Shartistatic void 476159063Shartiprint_typdefs(SmiNode *n) 477159063Sharti{ 478159063Sharti SmiNode *p; 479159063Sharti 480159063Sharti p = n; 481159063Sharti n = smiGetFirstChildNode(n); 482159063Sharti while (n != NULL) { 483159063Sharti switch (n->nodekind) { 484159063Sharti case SMI_NODEKIND_SCALAR: 485159063Sharti case SMI_NODEKIND_COLUMN: 486159063Sharti print_stype(n); 487159063Sharti break; 488159063Sharti case SMI_NODEKIND_COMPLIANCE: 489159063Sharti case SMI_NODEKIND_GROUP: 490159063Sharti save_node(n); 491159063Sharti return; 492159063Sharti default: 493159063Sharti break; 494159063Sharti } 495159063Sharti n = smiGetNextChildNode(n); 496159063Sharti } 497159063Sharti 498159063Sharti save_node(p); 499159063Sharti} 500159063Sharti 501128237Shartiint 502128237Shartimain(int argc, char *argv[]) 503128237Sharti{ 504128237Sharti int opt; 505128237Sharti int flags; 506128237Sharti SmiModule **mods; 507128237Sharti char *name; 508128237Sharti SmiNode *n, *last; 509128237Sharti u_int level; 510128237Sharti long u; 511128237Sharti char *end; 512128237Sharti 513128237Sharti smiInit(NULL); 514128237Sharti 515159063Sharti while ((opt = getopt(argc, argv, "c:Eeh")) != -1) 516128237Sharti switch (opt) { 517128237Sharti 518128237Sharti case 'c': 519128237Sharti errno = 0; 520128237Sharti u = strtol(optarg, &end, 10); 521128237Sharti if (errno != 0) 522128237Sharti err(1, "argument to -c"); 523128237Sharti if (*end != '\0') 524128237Sharti err(1, "%s: not a number", optarg); 525128237Sharti if (u < 0 || u > 5) 526128237Sharti err(1, "%s: out of range", optarg); 527128237Sharti cut = (u_int)u; 528128237Sharti break; 529128237Sharti 530159063Sharti case 'E': 531159063Sharti do_typedef = 'E'; 532159063Sharti break; 533159063Sharti 534159063Sharti case 'e': 535159063Sharti do_typedef = 'e'; 536159063Sharti break; 537159063Sharti 538128237Sharti case 'h': 539128237Sharti fprintf(stderr, usgtxt); 540128237Sharti exit(0); 541128237Sharti } 542128237Sharti 543128237Sharti argc -= optind; 544128237Sharti argv += optind; 545128237Sharti 546128237Sharti flags = smiGetFlags(); 547128237Sharti flags |= SMI_FLAG_ERRORS; 548128237Sharti smiSetFlags(flags); 549128237Sharti 550128237Sharti mods = malloc(sizeof(mods[0]) * argc); 551128237Sharti if (mods == NULL) 552128237Sharti err(1, NULL); 553128237Sharti 554128237Sharti for (opt = 0; opt < argc; opt++) { 555128237Sharti if ((name = smiLoadModule(argv[opt])) == NULL) 556128237Sharti err(1, "%s: cannot load", argv[opt]); 557128237Sharti mods[opt] = smiGetModule(name); 558128237Sharti } 559128237Sharti level = 0; 560128237Sharti last = NULL; 561128237Sharti for (opt = 0; opt < argc; opt++) { 562128237Sharti n = smiGetFirstNode(mods[opt], SMI_NODEKIND_ANY); 563128237Sharti for (;;) { 564159063Sharti if (do_typedef == 0) { 565159063Sharti level = open_node(n, level, &last); 566159063Sharti print_it(n, level); 567159063Sharti last = n; 568159063Sharti } else 569159063Sharti print_typdefs(n); 570128237Sharti 571128237Sharti if (last_node == NULL || 572128237Sharti (n = smiGetNextNode(last_node, SMI_NODEKIND_ANY)) 573128237Sharti == NULL) 574128237Sharti break; 575128237Sharti } 576128237Sharti } 577159063Sharti if (last != NULL && do_typedef == 0) 578159063Sharti level = close_node(last->oidlen - 1, level - 1); 579159063Sharti else if (do_typedef != 0) 580159063Sharti tdefs_cleanup(); 581159063Sharti 582128237Sharti return (0); 583128237Sharti} 584