- if( version && lines == 1 ) {
- rc = 0;
- goto leave;
- }
-
- i = idn+1;
- /* Check for "control" tag after dn and before changetype. */
- if ( BV_CASEMATCH( btype+i, &BV_CONTROL )) {
- /* Parse and add it to the list of controls */
- rc = parse_ldif_control( vals+i, &pctrls );
- if (rc != 0) {
- fprintf( stderr,
- _("%s: Error processing %s line, line %d: %s\n"),
- prog, BV_CONTROL.bv_val, linenum+i, ldap_err2string(rc) );
- }
- i++;
- if ( i>= lines ) {
-short_input:
- fprintf( stderr,
- _("%s: Expecting more input after %s line, line %d\n"),
- prog, btype[i-1].bv_val, linenum+i );
-
- rc = LDAP_PARAM_ERROR;
- goto leave;
- }
- }
-
- /* Check for changetype */
- if ( BV_CASEMATCH( btype+i, &BV_CHANGETYPE )) {
-#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, entry \"%s\")\n"),
- prog, BV_CHANGETYPE.bv_val, vals[i].bv_val, linenum+i, dn );
- vals[i].bv_val[icnt] = '\0';
- }
-#endif /* LIBERAL_CHANGETYPE_MODOP */
-
- if ( BV_CASEMATCH( vals+i, &BV_MODIFYCT )) {
- new_entry = 0;
- expect_modop = 1;
- } else if ( BV_CASEMATCH( vals+i, &BV_ADDCT )) {
- new_entry = 1;
- modop = LDAP_MOD_ADD;
- } else if ( BV_CASEMATCH( vals+i, &BV_MODRDNCT )
- || BV_CASEMATCH( vals+i, &BV_MODDNCT )
- || BV_CASEMATCH( vals+i, &BV_RENAMECT ))
- {
- i++;
- if ( i >= lines )
- goto short_input;
- if ( !BV_CASEMATCH( btype+i, &BV_NEWRDN )) {
- fprintf( stderr, _("%s: expecting \"%s:\" but saw"
- " \"%s:\" (line %d, entry \"%s\")\n"),
- prog, BV_NEWRDN.bv_val, btype[i].bv_val, linenum+i, dn );
- rc = LDAP_PARAM_ERROR;
- goto leave;
- }
- newrdn = vals[i].bv_val;
- i++;
- if ( i >= lines )
- goto short_input;
- if ( !BV_CASEMATCH( btype+i, &BV_DELETEOLDRDN )) {
- fprintf( stderr, _("%s: expecting \"%s:\" but saw"
- " \"%s:\" (line %d, entry \"%s\")\n"),
- prog, BV_DELETEOLDRDN.bv_val, btype[i].bv_val, linenum+i, dn );
- rc = LDAP_PARAM_ERROR;
- goto leave;
- }
- deleteoldrdn = ( vals[i].bv_val[0] == '0' ) ? 0 : 1;
- i++;
- if ( i < lines ) {
- if ( !BV_CASEMATCH( btype+i, &BV_NEWSUP )) {
- fprintf( stderr, _("%s: expecting \"%s:\" but saw"
- " \"%s:\" (line %d, entry \"%s\")\n"),
- prog, BV_NEWSUP.bv_val, btype[i].bv_val, linenum+i, dn );
- rc = LDAP_PARAM_ERROR;
- goto leave;
- }
- newsup = vals[i].bv_val;
- i++;
- }
- got_all = 1;
- } else if ( BV_CASEMATCH( vals+i, &BV_DELETECT )) {
- got_all = delete_entry = 1;
- } else {
- fprintf( stderr,
- _("%s: unknown %s \"%s\" (line %d, entry \"%s\")\n"),
- prog, BV_CHANGETYPE.bv_val, vals[i].bv_val, linenum+i, dn );
- rc = LDAP_PARAM_ERROR;
- goto leave;
- }
- i++;
- } else if ( ldapadd ) { /* missing changetype => add */
- new_entry = 1;
- modop = LDAP_MOD_ADD;
- } else {
- expect_modop = 1; /* missing changetype => modify */
- }
-
- if ( got_all ) {
- if ( i < lines ) {
- fprintf( stderr,
- _("%s: extra lines at end (line %d, entry \"%s\")\n"),
- prog, linenum+i, dn );
- rc = LDAP_PARAM_ERROR;
- goto leave;
- }
- goto doit;
- }
-
- 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 ( BV_CASEMATCH( 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 ( BV_CASEMATCH( btype+i, &BV_DN )) {
- fprintf( stderr, _("%s: attributeDescription \"%s\":"
- " (possible missing newline"
- " after line %d, entry \"%s\"?)\n"),
- prog, btype[i].bv_val, linenum+i - 1, dn );
- }
- if ( !BV_CASEMATCH( 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, entry \"%s\")\n"),
- prog, type, vals[i].bv_val, linenum+i, dn );
- vals[i].bv_val[icnt] = '\0';
- }
-#endif /* LIBERAL_CHANGETYPE_MODOP */
-
- expect_modop = 0;
- expect_sep = 1;
- if ( BV_CASEMATCH( btype+i, &BV_MODOPADD )) {
- modop = LDAP_MOD_ADD;
- mops[i] = M_SEP;
- nmods--;
- } else if ( BV_CASEMATCH( btype+i, &BV_MODOPREPLACE )) {
- /* 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 ( BV_CASEMATCH( btype+i, &BV_MODOPDELETE )) {
- modop = LDAP_MOD_DELETE;
- mops[i] = modop | LDAP_MOD_BVALUES;
- btype[i] = vals[i];
- } else if ( BV_CASEMATCH( btype+i, &BV_MODOPINCREMENT )) {
- modop = LDAP_MOD_INCREMENT;
- mops[i] = M_SEP;
- nmods--;
- } else { /* no modify op: invalid LDIF */
- fprintf( stderr, _("%s: modify operation type is missing at"
- " line %d, entry \"%s\"\n"),
- prog, linenum+i, dn );
- rc = LDAP_PARAM_ERROR;
- goto leave;
- }
- bv = vals[i];
- } else if ( expect_sep && BER_BVISEMPTY( btype+i )) {
- mops[i] = M_SEP;
- expect_sep = 0;
- expect_modop = 1;
- nmods--;
- } else {
- if ( !BV_CASEMATCH( btype+i, &bv )) {
- fprintf( stderr, _("%s: wrong attributeType at"
- " line %d, entry \"%s\"\n"),
- prog, linenum+i, dn );
- rc = LDAP_PARAM_ERROR;
- goto leave;
- }
- mops[i] = modop;
- /* If prev op was deferred and matches this type,
- * clear the flag
- */
- if ( (mops[i-1] & LDAP_MOD_BVALUES)
- && BV_CASEMATCH( btype+i, btype+i-1 ))
- {
- mops[i-1] = M_SEP;
- nmods--;
- }
- }
- }
-
-#if 0 /* we should faithfully encode the LDIF, not combine */
- /* 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 ( BV_CASEMATCH( 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++;
- }
- }
- }
-#endif
-
- /* 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] || !BV_CASEMATCH( 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: