|
|
1.1 ! root 1: /* A 'C' version of the shellscript dishinit ! 2: * By Steve Titcombe ! 3: * ! 4: * Most of this has fixed calls to other functions, and will require going ! 5: * through again to strip out all unnecessary error trapping, etc. ! 6: * (Utterly Horrible Hack.) ! 7: */ ! 8: ! 9: #ifndef lint ! 10: static char *rcsid = "$Header: /f/osi/others/quipu/uips/dish/RCS/quipurc.c,v 7.4 90/07/27 08:45:06 mrose Exp $"; ! 11: #endif ! 12: ! 13: /* ! 14: * NOTICE ! 15: * ! 16: * Acquisition, use, and distribution of this module and related ! 17: * materials are subject to the restrictions of a license agreement. ! 18: * Consult the Preface in the User's Manual for the full terms of ! 19: * this agreement. ! 20: * ! 21: */ ! 22: ! 23: #include <fcntl.h> ! 24: #include "manifest.h" ! 25: #include <sys/stat.h> ! 26: #include <signal.h> ! 27: #include <pwd.h> ! 28: #include "quipu/read.h" ! 29: #include "quipu/sequence.h" ! 30: #include "quipu/name.h" ! 31: #include "quipu/bind.h" ! 32: #include "quipu/dsp.h" ! 33: #include "quipu/ds_error.h" ! 34: #include "tailor.h" ! 35: #include "quipu/util.h" ! 36: #include "quipu/dua.h" ! 37: #include "quipu/ds_search.h" ! 38: #include "quipu/list.h" ! 39: #include "quipu/entry.h" ! 40: #include "quipu/modify.h" ! 41: ! 42: #define ORG_PERSON "thornPerson & quipuObject" ! 43: /* this should probably go elsewhere !!! */ ! 44: ! 45: LLog *log_dua; ! 46: DN sequence_dn() ; ! 47: DN dn, moddn ; ! 48: DN fixed_pos = NULLDN ; ! 49: PS opt; ! 50: PS rps; ! 51: PS fileps ; ! 52: ! 53: FILE *fp_quipurc ; ! 54: FILE *fp_draft ; ! 55: FILE *fp_tailor ; ! 56: ! 57: Filter get_filter (); ! 58: struct entrymod *ems_append() ; ! 59: struct entrymod *modify_avs() ; ! 60: ! 61: static struct ds_bind_arg bindarg ; ! 62: static struct ds_bind_arg bindresult ; ! 63: static struct ds_bind_error binderr ; ! 64: ! 65: struct ds_read_arg read_arg; ! 66: struct DSError read_error; ! 67: ! 68: struct ds_read_result read_result; ! 69: struct ds_modifyentry_arg mod_arg ; ! 70: struct DSError mod_error ; ! 71: ! 72: struct DSError search_error; ! 73: struct ds_search_result search_result; ! 74: static struct ds_search_arg search_arg = ! 75: { ! 76: default_common_args, ! 77: NULLDN, ! 78: SRA_ONELEVEL, ! 79: NULLFILTER, /* filter */ ! 80: FALSE, ! 81: { /* eis */ ! 82: FALSE, ! 83: NULLATTR, ! 84: EIS_ATTRIBUTESANDVALUES ! 85: } ! 86: }; ! 87: ! 88: static struct dua_sequence *current_sequence = NULL_DS; ! 89: struct entrymod *emnew ; ! 90: ! 91: AV_Sequence avst = NULLAV ; ! 92: Attr_Sequence as_flag = NULLATTR ; ! 93: Attr_Sequence trail = NULLATTR ; ! 94: Attr_Sequence eptr ; ! 95: Attr_Sequence temp ; ! 96: Attr_Sequence as ; ! 97: AttributeType at; ! 98: ! 99: extern Attr_Sequence get_attributes() ; ! 100: extern char *TidyString() ; ! 101: ! 102: Entry current_entry ; ! 103: Entry entry_ptr ; ! 104: ! 105: char Manager[LINESIZE] ; ! 106: char Password[LINESIZE] ; ! 107: char Local[LINESIZE] ; ! 108: char filterstring[LINESIZE] ; ! 109: ! 110: main() ! 111: { ! 112: struct passwd *pw_entry ; ! 113: struct passwd *getpwuid() ; ! 114: struct stat buf ; ! 115: ! 116: int i = 1 ; ! 117: int uid ; ! 118: int um ; ! 119: char pass1[LINESIZE] ; ! 120: char pass2[LINESIZE] ; ! 121: char Read_in_Stuff[LINESIZE] ; ! 122: char **vecptr ; ! 123: char *tmpdraft ; ! 124: char home_dir[LINESIZE] ; ! 125: char *p, *part1, *part2 ; ! 126: char quipurc_file[100] ; ! 127: char tailor_file[100] ; ! 128: char user_name[9] ; ! 129: char *localptr = Local ; ! 130: char print_format = EDBOUT ; ! 131: EntryInfo *ptr ; ! 132: static CommonArgs ca = default_common_args; ! 133: ! 134: vecptr = (char **) malloc(100) ; ! 135: vecptr[0] = malloc (LINESIZE) ; ! 136: (void) strcpy(vecptr[0], "showentry") ; ! 137: (void) strcpy(pass1, "x") ; ! 138: (void) strcpy(pass2, "y") ; ! 139: tmpdraft = malloc (LINESIZE) ; ! 140: (void) strcpy(tmpdraft, "/tmp/dish-") ; ! 141: ! 142: if ((opt = ps_alloc (std_open)) == NULLPS) ! 143: fatal (-62, "ps_alloc failed"); ! 144: if (std_setup (opt, stderr) == NOTOK) ! 145: fatal (-63, "std_setup failed"); ! 146: if ((rps = ps_alloc (std_open)) == NULLPS) ! 147: fatal (-64, "ps_alloc 2 failed"); ! 148: if (std_setup (rps, stdout) == NOTOK) ! 149: fatal (-65, "std_setup 2 failed"); ! 150: (void) strcpy(filterstring, "userid=") ; ! 151: ! 152: /* Sort out files, userids etc. */ ! 153: uid=getuid() ; ! 154: if ((pw_entry=getpwuid(uid)) == 0) ! 155: { ! 156: ps_printf(rps, "Who are you? (no name for your uid number)\n") ; ! 157: exit(1) ; ! 158: } ! 159: (void) strcpy(user_name, pw_entry->pw_name) ; ! 160: (void) strcat(tmpdraft, user_name) ; ! 161: ! 162: if (getenv("HOME") == 0) ! 163: { ! 164: ps_printf(rps, "No home directory?!!") ; ! 165: (void) strcpy(home_dir, pw_entry->pw_dir) ; ! 166: } ! 167: else ! 168: { ! 169: (void) strcpy(home_dir, getenv("HOME")) ; ! 170: } ! 171: ! 172: (void) strcpy(quipurc_file, home_dir) ; ! 173: (void) strcat(quipurc_file, "/.quipurc") ; ! 174: ! 175: (void) strcpy(tailor_file, isodefile ("dishinit", 1)); ! 176: ! 177: Manager[0] = 0; ! 178: Password[0] = 0; ! 179: Local[0] = 0; ! 180: ! 181: (void) stat(tailor_file, &buf) ; ! 182: (void) seteuid(buf.st_uid) ; /* set effective to enable */ ! 183: /* us to read protected file */ ! 184: ! 185: if ((fp_tailor = fopen(tailor_file, "r")) == 0) ! 186: { ! 187: ps_print(rps, "Can't open Tailor File. Abort.\n") ; ! 188: exit(1) ; ! 189: } ! 190: ! 191: while (fgets (Read_in_Stuff, LINESIZE, fp_tailor) != 0) ! 192: { ! 193: if (!strcmp(Read_in_Stuff, "##Anything after this line is copied into the users ~/.quipurc file\n")) ! 194: { ! 195: break ; ! 196: } ! 197: ! 198: p = SkipSpace (Read_in_Stuff); ! 199: if (( *p == '#') || (*p == '\0')) ! 200: continue; /* ignore comments and blanks */ ! 201: ! 202: part1 = p; ! 203: if ((part2 = index (p,':')) == NULLCP) { ! 204: ps_printf (opt,"Seperator missing '%s'. Ignoring..\n",p); ! 205: } ! 206: ! 207: *part2++ = '\0'; ! 208: part2 = TidyString (part2); ! 209: ! 210: if (lexequ(part1, "manager") == 0) ! 211: { ! 212: (void) strcpy(Manager, part2) ; ! 213: } ! 214: else ! 215: if (lexequ(part1, "password") == 0) ! 216: { ! 217: (void) strcpy(Password, part2) ; ! 218: } ! 219: else ! 220: if (lexequ(part1, "local") == 0) ! 221: { ! 222: (void) strcpy(Local, part2) ; ! 223: } ! 224: else ! 225: { ! 226: ps_printf(rps, "Error in tailor. What's a %s?\n", part1) ; ! 227: } ! 228: ! 229: } ! 230: (void) setuid(uid) ; /* Restore Userid to original user. */ ! 231: ! 232: /* create ~/.quipurc file. NB this does eradicate anything in there. ! 233: * (Theoretically nothing.) ! 234: */ ! 235: ! 236: if (Manager[0] == 0) { ! 237: ps_print(rps, "Can't find out the managers name\n") ; ! 238: exit(1) ; ! 239: } ! 240: if (Password[0] == 0) { ! 241: ps_print(rps, "Can't find out the managers password\n") ; ! 242: exit(1) ; ! 243: } ! 244: if (Local[0] == 0) { ! 245: ps_print(rps, "Can't find out where to search\n") ; ! 246: exit(1) ; ! 247: } ! 248: ! 249: um = umask(0177) ; ! 250: if ((fp_quipurc = fopen(quipurc_file, "w")) == 0) ! 251: { ! 252: ps_printf(rps, "Can't open ~/.quipurc. Aborting..\n") ; ! 253: exit(1) ; ! 254: } ! 255: (void) umask(um) ; ! 256: ! 257: if ((fileps = ps_alloc(std_open)) == NULLPS) ! 258: { ! 259: fatal (-66, "ps_alloc 2 failed"); ! 260: } ! 261: if (std_setup (fileps, fp_quipurc) == NOTOK) ! 262: { ! 263: fatal (-67, "std_setup 2 failed"); ! 264: } ! 265: ! 266: ! 267: /* Sorting out the bind section */ ! 268: quipu_syntaxes() ; /* set up the needed function pointers */ ! 269: dsap_init(&i, &vecptr) ; ! 270: ! 271: (void) strcpy(bindarg.dba_passwd, Password) ; ! 272: bindarg.dba_version = DBA_VERSION_V1988; ! 273: bindarg.dba_passwd_len = strlen(bindarg.dba_passwd) ; ! 274: ! 275: if ((bindarg.dba_dn = str2dn (Manager)) == NULLDN) ! 276: { ! 277: ps_printf (opt,"Invalid Manager name %s (???!)\n",Manager) ; ! 278: exit(1) ; ! 279: } ! 280: ! 281: if (ds_bind (&bindarg, &binderr, &bindresult) != OK) ! 282: { ! 283: ps_printf(rps, "Can't bind as the manager.\n") ; ! 284: exit(1); ! 285: } ! 286: /* Hopefully, should be successfully bound */ ! 287: ! 288: /* ! 289: * We now call the search stuff with the right bits, to see if we can get a ! 290: * match of uid='user_name'. Once there, we echo lots of information from ! 291: * their entry out to the .quipurc file. ! 292: * Hopefully there should only be one match. This assumes that ALL dir info ! 293: * up to date, and that SG do not allow multiple users with the same login. ! 294: */ ! 295: ! 296: /* set up the appropriate structures and defaults. */ ! 297: ! 298: search_arg.sra_common = ca; /* struct copy */ ! 299: search_arg.sra_common.ca_servicecontrol.svc_sizelimit = 2 ; ! 300: search_arg.sra_eis.eis_allattributes = FALSE ; ! 301: search_arg.sra_searchaliases = FALSE; ! 302: search_arg.sra_subset = SRA_ONELEVEL; ! 303: search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES ; ! 304: search_arg.sra_eis.eis_select = NULLATTR ; ! 305: search_arg.sra_eis.eis_allattributes = TRUE ; ! 306: search_arg.sra_filter = filter_alloc() ; ! 307: /* Default filter. */ ! 308: search_arg.sra_filter->flt_next = NULLFILTER; ! 309: search_arg.sra_filter->flt_type = FILTER_ITEM; ! 310: search_arg.sra_filter->FUFILT = NULLFILTER; ! 311: ! 312: ! 313: if (*localptr == '@') ! 314: { ! 315: localptr++; ! 316: } ! 317: if ((search_arg.sra_baseobject = str2dn(localptr)) == NULLDN) ! 318: { ! 319: ps_printf (opt,"Invalid sequence in username %s.\n", localptr); ! 320: exit(1) ; ! 321: } ! 322: ! 323: (void) strcat(filterstring, user_name) ; ! 324: ! 325: search_arg.sra_filter->flt_un.flt_un_item.fi_type = FILTERITEM_EQUALITY ; ! 326: ! 327: if ((search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type = AttrT_new ("userid")) == NULLAttrT) ! 328: { ! 329: ps_printf(rps, "Oops, userid is not a valid attr type. ABORT!!\n") ; ! 330: exit(1) ; ! 331: } ! 332: if ((search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = str2AttrV (user_name, search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type->oa_syntax)) == NULLAttrV) ! 333: { ! 334: ps_printf(rps, "%s is not a valid attribute value.\n", user_name) ; ! 335: } ! 336: ! 337: /* call search */ ! 338: /* We now ought to be in the right place, and with the search stuff set, ! 339: * ready to call search, and receive one (or no) entry back, which then ! 340: * gets processed accordingly. ! 341: */ ! 342: ! 343: if (ds_search (&search_arg, &search_error, &search_result) != DS_OK) ! 344: { ! 345: ps_printf(rps, "Search failed...\n") ; ! 346: exit (1) ; ! 347: /* This is not the same as coming back with */ ! 348: /* message "search failed to find anything. */ ! 349: } ! 350: ! 351: /* If the user does not exist in the DIT, print out the limited .quipurc ! 352: * and the warning message, and allow the user to play DISH. ! 353: */ ! 354: ! 355: if (search_result.CSR_entries == NULLENTRYINFO) ! 356: { ! 357: ps_printf(opt, "Unfortunately, you seem to have no entry in\n") ; ! 358: ps_printf(opt, "the directory. Contact '%s' who should be able to help.\n", Manager) ; ! 359: ps_printf(opt, "In the mean time, you can read, but not write.\n") ; ! 360: } ! 361: else ! 362: { ! 363: ptr = search_result.CSR_entries ; ! 364: dn = dn_cpy(ptr->ent_dn) ; /* Essence of move user_name. */ ! 365: ! 366: /* collect the info and put it into current_entry */ ! 367: ! 368: /* Set up the desired attribute type to be read*/ ! 369: /* from read.c */ ! 370: if ((at = AttrT_new ("userPassword")) != NULLAttrT) ! 371: { ! 372: as_flag = as_merge (as_flag, as_comp_new (AttrT_cpy (at), NULLAV, NULLACL_INFO)); ! 373: } ! 374: else ! 375: { ! 376: ps_printf(rps, "Oops, Serious error. unknown attribute type 'userPassword'.\n") ; ! 377: exit(1) ; ! 378: } ! 379: ! 380: if ((current_entry = local_find_entry (dn, FALSE)) == NULLENTRY) ! 381: { ! 382: read_arg.rda_common = ca; /* struct copy */ ! 383: read_arg.rda_object = dn; ! 384: read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; ! 385: read_arg.rda_eis.eis_allattributes = TRUE ; ! 386: read_arg.rda_eis.eis_select = NULLATTR ; ! 387: ! 388: if (ds_read (&read_arg, &read_error, &read_result) != DS_OK) ! 389: { ! 390: ps_printf(rps, "We even seem to be having problems reading\n" ) ; ! 391: ps_printf(rps, "an entry we searched and found!! HELP!!\n") ; ! 392: exit(1) ; ! 393: } ! 394: if (read_result.rdr_entry.ent_attr == NULLATTR) ! 395: { ! 396: ps_printf(rps, "No attributes present. Even though\n") ; ! 397: ps_printf(rps, "we found you by userid attribute!!! HELP!!\n") ; ! 398: exit (1) ; ! 399: } ! 400: cache_entry (&(read_result.rdr_entry), read_arg.rda_eis.eis_allattributes, TRUE) ; ! 401: } ! 402: ! 403: if ((current_entry = local_find_entry (dn, FALSE)) == NULLENTRY) ! 404: { ! 405: ps_printf(rps, "We still have nothing.Even after reading? Abort.\n") ; ! 406: exit(1) ; ! 407: } ! 408: ! 409: ps_printf(fileps, "username: ") ; ! 410: dn_print(fileps, dn, EDBOUT) ; ! 411: ps_printf(fileps, "\n") ; ! 412: ! 413: ps_printf(fileps, "me: ") ; ! 414: dn_print(fileps, dn, EDBOUT) ; ! 415: ps_printf(fileps, "\n") ; ! 416: ! 417: /* now showattribute -nokey to display it. */ ! 418: ! 419: ps_printf(fileps, "password: ") ; ! 420: for (eptr = current_entry->e_attributes; eptr != NULLATTR; ! 421: eptr = eptr->attr_link) ! 422: { ! 423: /* Tiptoe through the list of types until one matches, and then print value. */ ! 424: if (AttrT_cmp (eptr->attr_type, at) == 0) ! 425: { ! 426: avs_print (fileps, eptr->attr_value,print_format); ! 427: break; ! 428: } ! 429: } ! 430: ! 431: if (eptr == NULLATTR) ! 432: { ! 433: while( strcmp(pass1, pass2)) ! 434: { ! 435: ps_printf(opt, "You need a password...\n") ; ! 436: (void) strcpy(pass1, getpassword("Enter Password: ")) ; ! 437: (void) strcpy(pass2, getpassword("Re-enter password: ")) ; ! 438: if (strcmp(pass1, pass2)) ! 439: { ! 440: ps_printf(opt, "\nMismatch - Try again.\n") ; ! 441: } ! 442: } ! 443: ps_printf(fileps, "%s\n", pass1) ; ! 444: ! 445: um = umask(0177) ; ! 446: if ((fp_draft = fopen(tmpdraft, "w")) == 0) ! 447: { ! 448: ps_print(rps, "Can't open draft file... Abort.\n") ; ! 449: exit(1) ; ! 450: } ! 451: (void) umask(um) ; ! 452: ! 453: (void) fprintf(fp_draft, "UserPassword = %s\n", pass1) ; ! 454: (void) fprintf(fp_draft, "acl = self # write # attributes # acl $ userPassword\n") ; ! 455: (void) fprintf(fp_draft, "acl = others # compare # attributes # acl $ userPassword\n\n") ; ! 456: (void) fclose(fp_draft) ; ! 457: ! 458: if ((fp_draft = fopen (tmpdraft, "r")) == NULL) { ! 459: ps_printf (opt, "Can't open draft entry %s\n", tmpdraft); ! 460: exit(1) ; ! 461: } ! 462: ! 463: entry_ptr = get_default_entry (NULLENTRY); ! 464: entry_ptr->e_attributes = get_attributes (fp_draft); ! 465: ! 466: (void) fclose (fp_draft); ! 467: ! 468: mod_arg.mea_common = ca; /* struct copy */ ! 469: mod_arg.mea_object = dn; ! 470: for (moddn = dn ; moddn->dn_parent != NULLDN; moddn=moddn->dn_parent) ! 471: ; ! 472: entry_ptr->e_name = rdn_cpy (moddn->dn_rdn); ! 473: ! 474: /* add rdn as attribute */ ! 475: avst = avs_comp_new (AttrV_cpy (&entry_ptr->e_name->rdn_av)); ! 476: temp = as_comp_new (AttrT_cpy (entry_ptr->e_name->rdn_at), avst, NULLACL_INFO); ! 477: entry_ptr->e_attributes = as_merge (entry_ptr->e_attributes, temp); ! 478: ! 479: for (as = entry_ptr->e_attributes; as != NULLATTR; as = as->attr_link) ! 480: { ! 481: emnew = NULLMOD; ! 482: trail = as->attr_link; ! 483: as->attr_link = NULLATTR; ! 484: temp = current_entry->e_attributes; ! 485: for (; temp != NULLATTR; temp = temp->attr_link) ! 486: if (AttrT_cmp (as->attr_type, temp->attr_type) == 0) ! 487: { ! 488: /* found it - does it need changing ? */ ! 489: if (avs_cmp (as->attr_value, temp->attr_value) != 0) ! 490: emnew = modify_avs (as->attr_value, temp->attr_value,as->attr_type); ! 491: break; ! 492: } ! 493: ! 494: if (temp == NULLATTR) ! 495: { ! 496: emnew = em_alloc (); ! 497: emnew->em_type = EM_ADDATTRIBUTE; ! 498: emnew->em_what = as_cpy(as); ! 499: emnew->em_next = NULLMOD; ! 500: } ! 501: if (emnew != NULLMOD) ! 502: { ! 503: mod_arg.mea_changes = ems_append (mod_arg.mea_changes,emnew); ! 504: } ! 505: as->attr_link = trail; ! 506: } ! 507: ! 508: while (ds_modifyentry (&mod_arg, &mod_error) != DS_OK) ! 509: { ! 510: if (dish_error (opt, &mod_error) == 0) ! 511: { ! 512: ps_printf(rps,"We have a dish error. Bye.\n") ; ! 513: entry_free (entry_ptr); ! 514: exit(1) ; ! 515: } ! 516: mod_arg.mea_object = mod_error.ERR_REFERRAL.DSE_ref_candidates->cr_name; ! 517: } ! 518: ps_print (rps, "Modified "); ! 519: dn_print (rps, dn, EDBOUT); ! 520: ps_print (rps, "\n"); ! 521: delete_cache (dn); /* re-cache when next read */ ! 522: ! 523: entry_free (entry_ptr); ! 524: ems_part_free (mod_arg.mea_changes); ! 525: } ! 526: } ! 527: ! 528: while(fgets(Read_in_Stuff, LINESIZE, fp_tailor) != 0) ! 529: { ! 530: fputs(Read_in_Stuff, fp_quipurc) ; ! 531: } ! 532: ! 533: (void) fclose(fp_quipurc) ; ! 534: (void) fclose(fp_tailor) ; ! 535: ! 536: /* (void) fprintf(fp_quipurc, "dsap: local_dit \"%s\"\n", Local) ; ! 537: (void) fprintf(fp_quipurc, "notype: acl\n") ; ! 538: (void) fprintf(fp_quipurc, "notype: treestructure\n") ; ! 539: (void) fprintf(fp_quipurc, "notype: masterdsa\n") ; ! 540: (void) fprintf(fp_quipurc, "notype: slavedsa\n") ; ! 541: (void) fprintf(fp_quipurc, "notype: objectclass\n") ; ! 542: (void) fprintf(fp_quipurc, "cache_time: 30\n") ; ! 543: (void) fprintf(fp_quipurc, "connect_time: 2\n") ; ! 544: */ ! 545: (void) ds_unbind() ; ! 546: (void) unlink(tmpdraft) ; ! 547: } ! 548: ! 549: void ! 550: advise() ! 551: { ! 552: } ! 553: ! 554: void ! 555: set_sequence() ! 556: { ! 557: } ! 558: ! 559: void ! 560: unset_sequence() ! 561: { ! 562: } ! 563: ! 564: dish_error (ps,error) ! 565: PS ps; ! 566: struct DSError * error; ! 567: { ! 568: ! 569: if (error->dse_type == DSE_ABANDONED) { ! 570: ps_printf (ps,"(DAP call interrupted - abandon successful)\n"); ! 571: return (0); ! 572: } ! 573: ! 574: if (error->dse_type == DSE_ABANDON_FAILED) { ! 575: ps_printf (ps,"(DAP call interrupted - abandon unsuccessful)\n"); ! 576: return (0); ! 577: } ! 578: ! 579: if (error->dse_type == DSE_INTRERROR) { ! 580: ps_printf (ps,"(DAP call interrupted)\n"); ! 581: return (0); ! 582: } ! 583: ! 584: ds_error (ps,error); ! 585: ! 586: return (0); ! 587: } ! 588: ! 589: DN sequence_dn(y) ! 590: int y; ! 591: { ! 592: struct dua_seq_entry * ptr; ! 593: register int x = 1; ! 594: ! 595: if (current_sequence == NULL_DS) ! 596: return (NULLDN); ! 597: ! 598: for (ptr=current_sequence->ds_data; ! 599: (ptr != NULL_DE) && (x<y); ! 600: ptr=ptr->de_next,x++) ! 601: ; ! 602: ! 603: if (ptr == NULL_DE) ! 604: return (NULLDN); ! 605: if ( x == y ) ! 606: return (ptr->de_name); ! 607: return (NULLDN); ! 608: ! 609: } ! 610: ! 611: struct entrymod * ems_append (a,b) ! 612: struct entrymod *a; ! 613: struct entrymod *b; ! 614: { ! 615: struct entrymod *ptr; ! 616: ! 617: if ((ptr = a) == NULLMOD) ! 618: return b; ! 619: ! 620: for ( ; ptr->em_next != NULLMOD; ptr = ptr->em_next) ! 621: ; ! 622: ! 623: ptr->em_next = b; ! 624: return a; ! 625: } ! 626: ! 627: struct entrymod * modify_avs (a,b,ent_mod_at) ! 628: AV_Sequence a; ! 629: AV_Sequence b; ! 630: AttributeType ent_mod_at; ! 631: { ! 632: AV_Sequence x; ! 633: AV_Sequence y; ! 634: struct entrymod *em = NULLMOD, *em_new; ! 635: int removed_all = TRUE; ! 636: ! 637: for (x=b; x != NULLAV; x=x->avseq_next) { ! 638: em_new = NULLMOD; ! 639: for (y=a; y != NULLAV; y=y->avseq_next) ! 640: if (AttrV_cmp (&x->avseq_av,&y->avseq_av) == 0) ! 641: break; ! 642: if (y == NULLAV) { ! 643: em_new = em_alloc (); ! 644: em_new->em_type = EM_REMOVEVALUES; ! 645: em_new->em_what = as_comp_new (ent_mod_at,avs_comp_new(&x->avseq_av),NULLACL_INFO); ! 646: em_new->em_next = NULLMOD; ! 647: } else ! 648: removed_all = FALSE; ! 649: if (em_new != NULLMOD) ! 650: em = ems_append (em,em_new); ! 651: } ! 652: ! 653: if (removed_all) { ! 654: ems_part_free (em); ! 655: em_new = em_alloc (); ! 656: em_new->em_type = EM_REMOVEATTRIBUTE; ! 657: em_new->em_what = as_comp_new (ent_mod_at,b,NULLACL_INFO); ! 658: em_new->em_next = em_alloc(); ! 659: em_new->em_next->em_type = EM_ADDATTRIBUTE; ! 660: em_new->em_next->em_what = as_comp_new (ent_mod_at,avs_cpy(a),NULLACL_INFO); ! 661: em_new->em_next->em_next = NULLMOD; ! 662: return (em_new); ! 663: } ! 664: ! 665: for (x=a; x != NULLAV; x=x->avseq_next) { ! 666: em_new = NULLMOD; ! 667: for (y=b; y != NULLAV; y=y->avseq_next) ! 668: if (AttrV_cmp (&x->avseq_av,&y->avseq_av) == 0) ! 669: break; ! 670: if (y == NULLAV) { ! 671: em_new = em_alloc (); ! 672: em_new->em_type = EM_ADDVALUES; ! 673: em_new->em_what = as_comp_new (ent_mod_at,avs_comp_new(&x->avseq_av),NULLACL_INFO); ! 674: em_new->em_next = NULLMOD; ! 675: } ! 676: if (em_new != NULLMOD) ! 677: em = ems_append (em,em_new); ! 678: } ! 679: ! 680: ! 681: return (em); ! 682: } ! 683: ! 684: ems_part_free(emp) ! 685: struct entrymod *emp; ! 686: { ! 687: if(emp == NULLMOD) ! 688: return; ! 689: ems_part_free(emp->em_next); ! 690: free((char *)emp); ! 691: } ! 692:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.