- nmods = lines - i;
- idn = i;
-
- if ( new_entry ) {
- int fv;
-
- /* Make sure all attributes with multiple values are contiguous */
- for (; i<lines; i++) {
- for (j=i+1; j<lines; j++) {
- if ( !BVICMP( btype+i, btype+j )) {
- nmods--;
- /* out of order, move intervening attributes down */
- if ( j != i+1 ) {
- bv = vals[j];
- fv = freeval[j];
- for (k=j; k>i; k--) {
- btype[k] = btype[k-1];
- vals[k] = vals[k-1];
- freeval[k] = freeval[k-1];
- }
- k++;
- btype[k] = btype[i];
- vals[k] = bv;
- freeval[k] = fv;
- }
- i++;
- }
- }
- }
- /* Allocate space for array of mods, array of pointers to mods,
- * and array of pointers to values, allowing for NULL terminators
- * for the pointer arrays...
- */
- lm = ber_memalloc( nmods * sizeof(LDAPMod) +
- (nmods+1) * sizeof(LDAPMod*) +
- (lines + nmods - idn) * sizeof(struct berval *));
- pmods = (LDAPMod **)(lm+nmods);
- bvl = (struct berval **)(pmods+nmods+1);
-
- j = 0;
- k = -1;
- BER_BVZERO(&bv);
- for (i=idn; i<lines; i++) {
- if ( !BVICMP( btype+i, &BV_DN )) {
- fprintf( stderr, _("%s: attributeDescription \"%s\":"
- " (possible missing newline"
- " after line %d, entry \"%s\"?)\n"),
- prog, btype+i, linenum+i - 1, dn );
- }
- if ( BVICMP(btype+i,&bv)) {
- bvl[k++] = NULL;
- bv = btype[i];
- lm[j].mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
- lm[j].mod_type = bv.bv_val;
- lm[j].mod_bvalues = bvl+k;
- pmods[j] = lm+j;
- j++;
- }
- bvl[k++] = vals+i;
- }
- bvl[k] = NULL;
- pmods[j] = NULL;
- goto doit;
- }
-
- mops = ber_memalloc( lines+1 );
- mops[lines] = M_SEP;
- mops[i-1] = M_SEP;
-
- for ( ; i<lines; i++ ) {
- if ( expect_modop ) {
-#ifdef LIBERAL_CHANGETYPE_MODOP
- /* trim trailing spaces (and log warning ...) */
- int icnt;
- for ( icnt = vals[i].bv_len; --icnt > 0; ) {
- if ( !isspace( (unsigned char) vals[i].bv_val[icnt] ) ) break;
- }
-
- if ( ++icnt != vals[i].bv_len ) {
- fprintf( stderr, _("%s: illegal trailing space after"
- " \"%s: %s\" trimmed (line %d of entry \"%s\")\n"),
- prog, type, vals[i].bv_val, linenum, dn );
- vals[i].bv_val[icnt] = '\0';
- }
-#endif /* LIBERAL_CHANGETYPE_MODOP */
-
- expect_modop = 0;
- expect_sep = 1;
- if ( BVICMP( btype+i, &BV_MODOPADD ) == 0 ) {
- modop = LDAP_MOD_ADD;
- mops[i] = M_SEP;
- nmods--;
- } else if ( BVICMP( btype+i, &BV_MODOPREPLACE ) == 0 ) {
- /* defer handling these since they might have no values.
- * Use the BVALUES flag to signal that these were
- * deferred. If values are provided later, this
- * flag will be switched off.
- */
- modop = LDAP_MOD_REPLACE;
- mops[i] = modop | LDAP_MOD_BVALUES;
- btype[i] = vals[i];
- } else if ( BVICMP( btype+i, &BV_MODOPDELETE ) == 0 ) {
- modop = LDAP_MOD_DELETE;
- mops[i] = modop | LDAP_MOD_BVALUES;
- btype[i] = vals[i];
- } else if ( BVICMP( btype+i, &BV_MODOPINCREMENT ) == 0 ) {
- modop = LDAP_MOD_INCREMENT;
- mops[i] = M_SEP;
- nmods--;
- } else { /* no modify op: use default */
- modop = ldapadd ? LDAP_MOD_ADD : LDAP_MOD_REPLACE;
- mops[i] = modop;
- }
- } else if ( expect_sep && BER_BVISEMPTY( btype+i )) {
- mops[i] = M_SEP;
- expect_sep = 0;
- expect_modop = 1;
- nmods--;
- } else {
- mops[i] = modop;
- /* If prev op was deferred and matches this type,
- * clear the flag
- */
- if ( (mops[i-1]&LDAP_MOD_BVALUES) && !BVICMP(btype+i,
- btype+i-1)) {
- mops[i-1] = M_SEP;
- nmods--;
- }
- }
- }
-
- /* Make sure all modops with multiple values are contiguous */
- for (i=idn; i<lines; i++) {
- if ( mops[i] == M_SEP )
- continue;
- for (j=i+1; j<lines; j++) {
- if ( mops[j] == M_SEP || mops[i] != mops[j] )
- continue;
- if ( !BVICMP( btype+i, btype+j )) {
- nmods--;
- /* out of order, move intervening attributes down */
- if ( j != i+1 ) {
- int c;
- struct berval bv;
- char fv;
-
- c = mops[j];
- bv = vals[j];
- fv = freeval[j];
- for (k=j; k>i; k--) {
- btype[k] = btype[k-1];
- vals[k] = vals[k-1];
- freeval[k] = freeval[k-1];
- mops[k] = mops[k-1];
- }
- k++;
- btype[k] = btype[i];
- vals[k] = bv;
- freeval[k] = fv;
- mops[k] = c;
- }
- i++;
- }
- }
- }
-
- /* Allocate space for array of mods, array of pointers to mods,
- * and array of pointers to values, allowing for NULL terminators
- * for the pointer arrays...
- */
- lm = ber_memalloc( nmods * sizeof(LDAPMod) +
- (nmods+1) * sizeof(LDAPMod*) +
- (lines + nmods - idn) * sizeof(struct berval *));
- pmods = (LDAPMod **)(lm+nmods);
- bvl = (struct berval **)(pmods+nmods+1);
-
- j = 0;
- k = -1;
- BER_BVZERO(&bv);
- mops[idn-1] = M_SEP;
- for (i=idn; i<lines; i++) {
- if ( mops[i] == M_SEP )
- continue;
- if ( mops[i] != mops[i-1] || BVICMP(btype+i,&bv)) {
- bvl[k++] = NULL;
- bv = btype[i];
- lm[j].mod_op = mops[i] | LDAP_MOD_BVALUES;
- lm[j].mod_type = bv.bv_val;
- if ( mops[i] & LDAP_MOD_BVALUES ) {
- lm[j].mod_bvalues = NULL;
- } else {
- lm[j].mod_bvalues = bvl+k;
- }
- pmods[j] = lm+j;
- j++;
- }
- bvl[k++] = vals+i;
- }
- bvl[k] = NULL;
- pmods[j] = NULL;
-
-doit: