00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <kdebug.h>
00022
#include <kmdcodec.h>
00023
00024
#include "ldif.h"
00025
00026
using namespace KABC;
00027
00028 LDIF::LDIF()
00029 {
00030
startParsing();
00031 }
00032
00033 LDIF::~LDIF()
00034 {
00035 }
00036
00037 QCString LDIF::assembleLine(
const QString &fieldname,
const QByteArray &value,
00038 uint linelen,
bool url )
00039 {
00040
bool safe =
false;
00041
bool isDn;
00042
QCString result;
00043 uint i;
00044
00045
if ( url ) {
00046 result = fieldname.utf8() +
":< " +
QCString( value.data(), value.size()+1 );
00047 }
else {
00048 isDn = fieldname.lower() ==
"dn";
00049
00050
if ( value.size() > 0 && value[0] > 0 && value[0] !=
'\n' &&
00051 value[0] !=
'\r' && value[0] !=
':' && value[0] !=
'<' ) safe =
true;
00052
00053
00054
if ( safe ) {
00055
for ( i=1; i < value.size(); i++ ) {
00056
00057
if ( ( isDn && value[i] == 0 ) ||
00058 ( !isDn && value[i] <= 0 ) ||
00059 value[i] ==
'\r' || value[i] ==
'\n' ) {
00060 safe =
false;
00061
break;
00062 }
00063 }
00064 }
00065
00066
if ( value.size() == 0 ) safe =
true;
00067
00068
if( safe ) {
00069 result = fieldname.utf8() +
": " +
QCString( value.data(), value.size()+1 );
00070 }
else {
00071 result = fieldname.utf8() +
":: " +
KCodecs::base64Encode( value,
false );
00072 }
00073
00074
if ( linelen > 0 ) {
00075 i = (fieldname.length()+2) > linelen ? fieldname.length()+2 : linelen;
00076
while ( i < result.length() ) {
00077 result.insert( i,
"\n " );
00078 i += linelen+2;
00079 }
00080 }
00081 }
00082
return result;
00083 }
00084
00085 QCString LDIF::assembleLine(
const QString &fieldname,
const QCString &value,
00086 uint linelen,
bool url )
00087 {
00088
QCString ret;
00089
QByteArray tmp;
00090 uint valuelen = value.length();
00091 tmp.setRawData( value, valuelen );
00092 ret =
assembleLine( fieldname, tmp, linelen, url );
00093 tmp.resetRawData( value, valuelen );
00094
return ret;
00095
00096 }
00097
00098 QCString LDIF::assembleLine(
const QString &fieldname,
const QString &value,
00099 uint linelen,
bool url )
00100 {
00101
return assembleLine( fieldname, value.utf8(), linelen, url );
00102 }
00103
00104 bool LDIF::splitLine(
const QCString &line,
QString &fieldname,
QByteArray &value )
00105 {
00106
int position;
00107
QByteArray tmp;
00108
int linelen;
00109
00110
00111
00112 position = line.find(
":" );
00113
if ( position == -1 ) {
00114
00115 fieldname =
"";
00116
QCString str;
00117 str = line.stripWhiteSpace();
00118 linelen = str.length();
00119 tmp.setRawData( str.data(), linelen );
00120 value = tmp.copy();
00121 tmp.resetRawData( str.data(), linelen );
00122
00123
return false;
00124 }
00125
00126 linelen = line.length();
00127
00128
if ( linelen > ( position + 1 ) && line[ position + 1 ] ==
':' ) {
00129
00130 fieldname = QString::fromUtf8(
00131 line.left( position ).stripWhiteSpace() );
00132
if ( linelen <= ( position + 3 ) ) {
00133 value.resize( 0 );
00134
return false;
00135 }
00136 tmp.setRawData( &line.data()[ position + 3 ], linelen - position - 3 );
00137
KCodecs::base64Decode( tmp, value );
00138 tmp.resetRawData( &line.data()[ position + 3 ], linelen - position - 3 );
00139
return false;
00140 }
00141
00142
if ( linelen > ( position + 1 ) && line[ position + 1 ] ==
'<' ) {
00143
00144 fieldname = QString::fromUtf8(
00145 line.left( position ).stripWhiteSpace() );
00146
if ( linelen <= ( position + 3 ) ) {
00147 value.resize( 0 );
00148
return false;
00149 }
00150 tmp.setRawData( &line.data()[ position + 3 ], linelen - position - 3 );
00151 value = tmp.copy();
00152 tmp.resetRawData( &line.data()[ position + 3 ], linelen - position - 3 );
00153
return true;
00154 }
00155
00156 fieldname = QString::fromUtf8(line.left( position ).stripWhiteSpace());
00157
if ( linelen <= ( position + 2 ) ) {
00158 value.resize( 0 );
00159
return false;
00160 }
00161 tmp.setRawData( &line.data()[ position + 2 ], linelen - position - 2 );
00162 value = tmp.copy();
00163 tmp.resetRawData( &line.data()[ position + 2 ], linelen - position - 2 );
00164
return false;
00165 }
00166
00167 bool LDIF::splitControl(
const QCString &line,
QString &oid,
bool &critical,
00168
QByteArray &value )
00169 {
00170
QString tmp;
00171 critical =
false;
00172
bool url =
splitLine( line, tmp, value );
00173
00174
kdDebug(5700) <<
"splitControl: value: " << QString::fromUtf8(value, value.size()) <<
endl;
00175
if ( tmp.isEmpty() ) {
00176 tmp = QString::fromUtf8( value, value.size() );
00177 value.resize( 0 );
00178 }
00179
if ( tmp.right( 4 ) ==
"true" ) {
00180 critical =
true;
00181 tmp.truncate( tmp.length() - 5 );
00182 }
else if ( tmp.right( 5 ) ==
"false" ) {
00183 critical =
false;
00184 tmp.truncate( tmp.length() - 6 );
00185 }
00186 oid = tmp;
00187
return url;
00188 }
00189
00190 LDIF::ParseVal
LDIF::processLine()
00191 {
00192
00193
if ( mIsComment )
return None;
00194
00195 ParseVal retval = None;
00196
if ( mLastParseVal == EndEntry ) mEntryType = Entry_None;
00197
00198 mUrl =
splitLine( line, mAttr, mVal );
00199
00200
QString attrLower = mAttr.lower();
00201
00202
switch ( mEntryType ) {
00203
case Entry_None:
00204
if ( attrLower ==
"version" ) {
00205
if ( !mDn.isEmpty() ) retval = Err;
00206 }
else if ( attrLower ==
"dn" ) {
00207
kdDebug(5700) <<
"ldapentry dn: " << QString::fromUtf8( mVal, mVal.size() ) <<
endl;
00208 mDn = QString::fromUtf8( mVal, mVal.size() );
00209 mModType = Mod_None;
00210 retval = NewEntry;
00211 }
else if ( attrLower ==
"changetype" ) {
00212
if ( mDn.isEmpty() )
00213 retval = Err;
00214
else {
00215
QString tmpval = QString::fromUtf8( mVal, mVal.size() );
00216
kdDebug(5700) <<
"changetype: " << tmpval <<
endl;
00217
if ( tmpval ==
"add" ) mEntryType = Entry_Add;
00218
else if ( tmpval ==
"delete" ) mEntryType = Entry_Del;
00219
else if ( tmpval ==
"modrdn" || tmpval ==
"moddn" ) {
00220 mNewRdn =
"";
00221 mNewSuperior =
"";
00222 mDelOldRdn =
true;
00223 mEntryType = Entry_Modrdn;
00224 }
00225
else if ( tmpval ==
"modify" ) mEntryType = Entry_Mod;
00226
else retval = Err;
00227 }
00228 }
else if ( attrLower ==
"control" ) {
00229 mUrl =
splitControl(
QCString( mVal, mVal.size() + 1 ), mOid, mCritical, mVal );
00230 retval = Control;
00231 }
else if ( !mAttr.isEmpty() && mVal.size() > 0 ) {
00232 mEntryType = Entry_Add;
00233 retval = Item;
00234 }
00235
break;
00236
case Entry_Add:
00237
if ( mAttr.isEmpty() && mVal.size() == 0 )
00238 retval = EndEntry;
00239
else
00240 retval = Item;
00241
break;
00242
case Entry_Del:
00243
if ( mAttr.isEmpty() && mVal.size() == 0 )
00244 retval = EndEntry;
00245
else
00246 retval = Err;
00247
break;
00248
case Entry_Mod:
00249
if ( mModType == Mod_None ) {
00250
kdDebug(5700) <<
"kio_ldap: new modtype " << mAttr <<
endl;
00251
if ( mAttr.isEmpty() && mVal.size() == 0 ) {
00252 retval = EndEntry;
00253 }
else if ( attrLower ==
"add" ) {
00254 mModType = Mod_Add;
00255 }
else if ( attrLower ==
"replace" ) {
00256 mModType = Mod_Replace;
00257 mAttr = QString::fromUtf8( mVal, mVal.size() );
00258 mVal.resize( 0 );
00259 retval = Item;
00260 }
else if ( attrLower ==
"delete" ) {
00261 mModType = Mod_Del;
00262 mAttr = QString::fromUtf8( mVal, mVal.size() );
00263 mVal.resize( 0 );
00264 retval = Item;
00265 }
else {
00266 retval = Err;
00267 }
00268 }
else {
00269
if ( mAttr.isEmpty() ) {
00270
if ( QString::fromUtf8( mVal, mVal.size() ) ==
"-" ) {
00271 mModType = Mod_None;
00272 }
else if ( mVal.size() == 0 ) {
00273 retval = EndEntry;
00274 }
else
00275 retval = Err;
00276 }
else
00277 retval = Item;
00278 }
00279
break;
00280
case Entry_Modrdn:
00281
if ( mAttr.isEmpty() && mVal.size() == 0 )
00282 retval = EndEntry;
00283
else if ( attrLower ==
"newrdn" )
00284 mNewRdn = QString::fromUtf8( mVal, mVal.size() );
00285
else if ( attrLower ==
"newsuperior" )
00286 mNewSuperior = QString::fromUtf8( mVal, mVal.size() );
00287
else if ( attrLower ==
"deleteoldrdn" ) {
00288
if ( mVal.size() > 0 && mVal[0] ==
'0' )
00289 mDelOldRdn =
false;
00290
else if ( mVal.size() > 0 && mVal[0] ==
'1' )
00291 mDelOldRdn =
true;
00292
else
00293 retval = Err;
00294 }
else
00295 retval = Err;
00296
break;
00297 }
00298
return retval;
00299 }
00300
00301 LDIF::ParseVal
LDIF::nextItem()
00302 {
00303 ParseVal retval = None;
00304
char c=0;
00305
00306
while( retval == None ) {
00307
if ( mPos < mLdif.size() ) {
00308 c = mLdif[mPos];
00309 mPos++;
00310
if ( mIsNewLine && c ==
'\r' )
continue;
00311
if ( mIsNewLine && ( c ==
' ' || c ==
'\t' ) ) {
00312 mIsNewLine =
false;
00313
continue;
00314 }
00315
if ( mIsNewLine ) {
00316 mIsNewLine =
false;
00317 retval =
processLine();
00318 mLastParseVal = retval;
00319 line.resize( 0 );
00320 mIsComment = ( c ==
'#' );
00321 }
00322
if ( c ==
'\n' || c ==
'\r' ) {
00323 mLineNo++;
00324 mIsNewLine =
true;
00325
continue;
00326 }
00327 }
else {
00328 retval = MoreData;
00329
break;
00330 }
00331
00332
if ( !mIsComment ) line += c;
00333 }
00334
return retval;
00335 }
00336
00337 void LDIF::endLDIF()
00338 {
00339 mLdif.resize( 3 );
00340 mLdif[ 0 ] =
'\n';
00341 mLdif[ 1 ] =
'\n';
00342 mLdif[ 2 ] =
'\n';
00343 mPos = 0;
00344 }
00345
00346 void LDIF::startParsing()
00347 {
00348 mPos = mLineNo = 0;
00349 mDelOldRdn =
false;
00350 mEntryType = Entry_None;
00351 mModType = Mod_None;
00352 mDn = mNewRdn = mNewSuperior =
"";
00353 line =
"";
00354 mIsNewLine =
false;
00355 mIsComment =
false;
00356 mLastParseVal = None;
00357 }