• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

kabc

  • sources
  • kde-4.12
  • kdepimlibs
  • kabc
ldif.cpp
1 /*
2  A temporary copy to break dependency to KLDAP
3 
4  This file is part of libkldap.
5  Copyright (c) 2004-2006 Szombathelyi György <gyurco@freemail.hu>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include "ldif_p.h"
24 
25 #include <kdebug.h>
26 
27 class Ldif::LdifPrivate
28 {
29  public:
30  int mModType;
31  bool mDelOldRdn, mUrl;
32  LdapDN mDn;
33  QString mAttr, mNewRdn, mNewSuperior, mOid;
34  QByteArray mLdif, mValue;
35  EntryType mEntryType;
36 
37  bool mIsNewLine, mIsComment, mCritical;
38  ParseValue mLastParseValue;
39  uint mPos, mLineNumber;
40  QByteArray mLine;
41 };
42 
43 Ldif::Ldif() : d( new LdifPrivate )
44 {
45  startParsing();
46 }
47 
48 Ldif::Ldif( const Ldif &that ) : d( new LdifPrivate )
49 {
50  *d = *that.d;
51 
52  startParsing();
53 }
54 
55 Ldif &Ldif::operator=( const Ldif &that )
56 {
57  if ( this == &that ) {
58  return *this;
59  }
60 
61  *d = *that.d;
62 
63  return *this;
64 }
65 
66 Ldif::~Ldif()
67 {
68  delete d;
69 }
70 
71 QByteArray Ldif::assembleLine( const QString &fieldname,
72  const QByteArray &value,
73  uint linelen, bool url )
74 {
75  bool safe = false;
76  bool isDn;
77  QByteArray result;
78 
79  if ( url ) {
80  result = fieldname.toUtf8() + ":< " + value;
81  } else {
82  isDn = fieldname.toLower() == QLatin1String( "dn" );
83  //SAFE-INIT-CHAR
84  if ( value.size() > 0 && value[0] > 0 && value[0] != '\n' &&
85  value[0] != '\r' && value[0] != ':' && value[0] != '<' ) {
86  safe = true;
87  }
88 
89  //SAFE-CHAR
90  if ( safe ) {
91  for ( int i=1; i < value.size(); i++ ) {
92  //allow utf-8 in Distinguished Names
93  if ( ( isDn && value[i] == 0 ) ||
94  ( !isDn && value[i] <= 0 ) ||
95  value[i] == '\r' || value[i] == '\n' ) {
96  safe = false;
97  break;
98  }
99  }
100  }
101 
102  if ( value.size() == 0 ) {
103  safe = true;
104  }
105 
106  if ( safe ) {
107  result = fieldname.toUtf8() + ": " + value;
108  } else {
109  result = fieldname.toUtf8() + ":: " + value.toBase64();
110  }
111 
112  if ( linelen > 0 ) {
113  int i = (uint)( fieldname.length() + 2 ) > linelen ? fieldname.length() + 2 : linelen;
114  while ( i < result.length() ) {
115  result.insert( i, "\n " );
116  i += linelen+2;
117  }
118  }
119  }
120  return result;
121 }
122 
123 QByteArray Ldif::assembleLine( const QString &fieldname, const QString &value,
124  uint linelen, bool url )
125 {
126  return assembleLine( fieldname, value.toUtf8(), linelen, url );
127 }
128 
129 bool Ldif::splitLine( const QByteArray &line, QString &fieldname, QByteArray &value )
130 {
131  int position;
132  QByteArray tmp;
133  int linelen;
134 
135 // kDebug() << "line:" << QString::fromUtf8(line);
136 
137  position = line.indexOf( ":" );
138  if ( position == -1 ) {
139  // strange: we did not find a fieldname
140  fieldname = QLatin1String( "" );
141  value = line.trimmed();
142 // kDebug() << "value :" << value[0];
143  return false;
144  }
145 
146  linelen = line.size();
147  fieldname = QString::fromUtf8( line.left( position ).trimmed() );
148 
149  if ( linelen > ( position + 1 ) && line[ position + 1 ] == ':' ) {
150  // String is BASE64 encoded -> decode it now.
151  if ( linelen <= ( position + 3 ) ) {
152  value.resize( 0 );
153  return false;
154  }
155  value = QByteArray::fromBase64( line.mid( position + 3 ) );
156  return false;
157  }
158 
159  if ( linelen > ( position + 1 ) && line[ position + 1 ] == '<' ) {
160  // String is an URL.
161  if ( linelen <= ( position + 3 ) ) {
162  value.resize( 0 );
163  return false;
164  }
165  value = QByteArray::fromBase64( line.mid( position + 3 ) );
166  return true;
167  }
168 
169  if ( linelen <= ( position + 2 ) ) {
170  value.resize( 0 );
171  return false;
172  }
173  value = line.mid( position + 2 );
174  return false;
175 }
176 
177 bool Ldif::splitControl( const QByteArray &line, QString &oid, bool &critical,
178  QByteArray &value )
179 {
180  QString tmp;
181  critical = false;
182  bool url = splitLine( line, tmp, value );
183 
184  kDebug() << "value:" << QString::fromUtf8( value, value.size() );
185  if ( tmp.isEmpty() ) {
186  tmp = QString::fromUtf8( value, value.size() );
187  value.resize( 0 );
188  }
189  if ( tmp.endsWith( QLatin1String( "true" ) ) ) {
190  critical = true;
191  tmp.truncate( tmp.length() - 5 );
192  } else if ( tmp.endsWith( QLatin1String( "false" ) ) ) {
193  critical = false;
194  tmp.truncate( tmp.length() - 6 );
195  }
196  oid = tmp;
197  return url;
198 }
199 
200 Ldif::ParseValue Ldif::processLine()
201 {
202 
203  if ( d->mIsComment ) {
204  return None;
205  }
206 
207  ParseValue retval = None;
208  if ( d->mLastParseValue == EndEntry ) {
209  d->mEntryType = Entry_None;
210  }
211 
212  d->mUrl = splitLine( d->mLine, d->mAttr, d->mValue );
213 
214  QString attrLower = d->mAttr.toLower();
215 
216  switch ( d->mEntryType ) {
217  case Entry_None:
218  if ( attrLower == QLatin1String( "version" ) ) {
219  if ( !d->mDn.isEmpty() ) {
220  retval = Err;
221  }
222  } else if ( attrLower == QLatin1String( "dn" ) ) {
223  kDebug() << "ldapentry dn:" << QString::fromUtf8( d->mValue, d->mValue.size() );
224  d->mDn = LdapDN( QString::fromUtf8( d->mValue, d->mValue.size() ) );
225  d->mModType = Mod_None;
226  retval = NewEntry;
227  } else if ( attrLower == QLatin1String( "changetype" ) ) {
228  if ( d->mDn.isEmpty() ) {
229  retval = Err;
230  } else {
231  QString tmpval = QString::fromUtf8( d->mValue, d->mValue.size() );
232  kDebug() << "changetype:" << tmpval;
233  if ( tmpval == QLatin1String( "add" ) ) {
234  d->mEntryType = Entry_Add;
235  } else if ( tmpval == QLatin1String( "delete" ) ) {
236  d->mEntryType = Entry_Del;
237  } else if ( tmpval == QLatin1String( "modrdn" ) || tmpval == QLatin1String( "moddn" ) ) {
238  d->mNewRdn = QLatin1String( "" );
239  d->mNewSuperior = QLatin1String( "" );
240  d->mDelOldRdn = true;
241  d->mEntryType = Entry_Modrdn;
242  } else if ( tmpval == QLatin1String( "modify" ) ) {
243  d->mEntryType = Entry_Mod;
244  } else {
245  retval = Err;
246  }
247  }
248  } else if ( attrLower == QLatin1String( "control" ) ) {
249  d->mUrl = splitControl( d->mValue, d->mOid, d->mCritical, d->mValue );
250  retval = Control;
251  } else if ( !d->mAttr.isEmpty() && d->mValue.size() > 0 ) {
252  d->mEntryType = Entry_Add;
253  retval = Item;
254  }
255  break;
256  case Entry_Add:
257  if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
258  retval = EndEntry;
259  } else {
260  retval = Item;
261  }
262  break;
263  case Entry_Del:
264  if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
265  retval = EndEntry;
266  } else {
267  retval = Err;
268  }
269  break;
270  case Entry_Mod:
271  if ( d->mModType == Mod_None ) {
272  kDebug() << "new modtype" << d->mAttr;
273  if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
274  retval = EndEntry;
275  } else if ( attrLower == QLatin1String( "add" ) ) {
276  d->mModType = Mod_Add;
277  } else if ( attrLower == QLatin1String( "replace" ) ) {
278  d->mModType = Mod_Replace;
279  d->mAttr = QString::fromUtf8( d->mValue, d->mValue.size() );
280  d->mValue = QByteArray();
281  retval = Item;
282  } else if ( attrLower == QLatin1String( "delete" ) ) {
283  d->mModType = Mod_Del;
284  d->mAttr = QString::fromUtf8( d->mValue, d->mValue.size() );
285  d->mValue = QByteArray();
286  retval = Item;
287  } else {
288  retval = Err;
289  }
290  } else {
291  if ( d->mAttr.isEmpty() ) {
292  if ( QString::fromUtf8( d->mValue, d->mValue.size() ) == QLatin1String( "-" ) ) {
293  d->mModType = Mod_None;
294  } else if ( d->mValue.size() == 0 ) {
295  retval = EndEntry;
296  } else {
297  retval = Err;
298  }
299  } else {
300  retval = Item;
301  }
302  }
303  break;
304  case Entry_Modrdn:
305  if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
306  retval = EndEntry;
307  } else if ( attrLower == QLatin1String( "newrdn" ) ) {
308  d->mNewRdn = QString::fromUtf8( d->mValue, d->mValue.size() );
309  } else if ( attrLower == QLatin1String( "newsuperior" ) ) {
310  d->mNewSuperior = QString::fromUtf8( d->mValue, d->mValue.size() );
311  } else if ( attrLower == QLatin1String( "deleteoldrdn" ) ) {
312  if ( d->mValue.size() > 0 && d->mValue[0] == '0' ) {
313  d->mDelOldRdn = false;
314  } else if ( d->mValue.size() > 0 && d->mValue[0] == '1' ) {
315  d->mDelOldRdn = true;
316  } else {
317  retval = Err;
318  }
319  } else {
320  retval = Err;
321  }
322  break;
323  }
324  return retval;
325 }
326 
327 Ldif::ParseValue Ldif::nextItem()
328 {
329  ParseValue retval = None;
330  char c=0;
331 
332  while ( retval == None ) {
333  if ( d->mPos < (uint)d->mLdif.size() ) {
334  c = d->mLdif[d->mPos];
335  d->mPos++;
336  if ( d->mIsNewLine && c == '\r' ) {
337  continue; //handle \n\r line end
338  }
339  if ( d->mIsNewLine && ( c == ' ' || c == '\t' ) ) { //line folding
340  d->mIsNewLine = false;
341  continue;
342  }
343  if ( d->mIsNewLine ) {
344  d->mIsNewLine = false;
345  retval = processLine();
346  d->mLastParseValue = retval;
347  d->mLine.resize( 0 );
348  d->mIsComment = ( c == '#' );
349  }
350  if ( c == '\n' || c == '\r' ) {
351  d->mLineNumber++;
352  d->mIsNewLine = true;
353  continue;
354  }
355  } else {
356  retval = MoreData;
357  break;
358  }
359 
360  if ( !d->mIsComment ) {
361  d->mLine += c;
362  }
363  }
364  return retval;
365 }
366 
367 void Ldif::endLdif()
368 {
369  QByteArray tmp( 3, '\n' );
370  d->mLdif = tmp;
371  d->mPos = 0;
372 }
373 
374 void Ldif::startParsing()
375 {
376  d->mPos = d->mLineNumber = 0;
377  d->mDelOldRdn = false;
378  d->mEntryType = Entry_None;
379  d->mModType = Mod_None;
380  d->mDn = LdapDN();
381  d->mNewRdn.clear();
382  d->mNewSuperior.clear();
383  d->mLine = QByteArray();
384  d->mIsNewLine = false;
385  d->mIsComment = false;
386  d->mLastParseValue = None;
387 }
388 
389 void Ldif::setLdif( const QByteArray &ldif )
390 {
391  d->mLdif = ldif;
392  d->mPos = 0;
393 }
394 
395 Ldif::EntryType Ldif::entryType() const
396 {
397  return d->mEntryType;
398 }
399 
400 int Ldif::modType() const
401 {
402  return d->mModType;
403 }
404 
405 LdapDN Ldif::dn() const
406 {
407  return d->mDn;
408 }
409 
410 QString Ldif::newRdn() const
411 {
412  return d->mNewRdn;
413 }
414 
415 QString Ldif::newSuperior() const
416 {
417  return d->mNewSuperior;
418 }
419 
420 bool Ldif::delOldRdn() const
421 {
422  return d->mDelOldRdn;
423 }
424 
425 QString Ldif::attr() const
426 {
427  return d->mAttr;
428 }
429 
430 QByteArray Ldif::value() const
431 {
432  return d->mValue;
433 }
434 
435 bool Ldif::isUrl() const
436 {
437  return d->mUrl;
438 }
439 
440 bool Ldif::isCritical() const
441 {
442  return d->mCritical;
443 }
444 
445 QString Ldif::oid() const
446 {
447  return d->mOid;
448 }
449 
450 uint Ldif::lineNumber() const
451 {
452  return d->mLineNumber;
453 }
Ldif::value
QByteArray value() const
Returns the attribute value.
Definition: ldif.cpp:430
Ldif::endLdif
void endLdif()
Indicates the end of the Ldif file/stream.
Definition: ldif.cpp:367
Ldif::lineNumber
uint lineNumber() const
Returns the line number which the parser processes.
Definition: ldif.cpp:450
Ldif::isCritical
bool isCritical() const
Returns the criticality level when modType() returned Control.
Definition: ldif.cpp:440
Ldif::nextItem
ParseValue nextItem()
Process the Ldif until a complete item can be returned.
Definition: ldif.cpp:327
Ldif::splitControl
static bool splitControl(const QByteArray &line, QString &oid, bool &critical, QByteArray &value)
Splits a control specification (without the "control:" directive)
Definition: ldif.cpp:177
Ldif::assembleLine
static QByteArray assembleLine(const QString &fieldname, const QByteArray &value, uint linelen=0, bool url=false)
Assembles fieldname and value into a valid Ldif line, BASE64 encodes the value if necessary and optio...
Definition: ldif.cpp:71
Ldif::newSuperior
QString newSuperior() const
Returns the new parent of the entry if modType() returned Entry_Modrdn.
Definition: ldif.cpp:415
Ldif::setLdif
void setLdif(const QByteArray &ldif)
Sets a chunk of Ldif.
Definition: ldif.cpp:389
Ldif::modType
int modType() const
Returns the LDAP modify request type if entryType() returned Entry_Mod.
Definition: ldif.cpp:400
Ldif::attr
QString attr() const
Returns the attribute name.
Definition: ldif.cpp:425
Ldif::processLine
ParseValue processLine()
Process one Ldif line.
Definition: ldif.cpp:200
Ldif::startParsing
void startParsing()
Starts the parsing of a new Ldif.
Definition: ldif.cpp:374
Ldif::isUrl
bool isUrl() const
Returns if val() is an url.
Definition: ldif.cpp:435
Ldif::oid
QString oid() const
Returns the OID when modType() returned Control.
Definition: ldif.cpp:445
Ldif::dn
LdapDN dn() const
Returns the Distinguished Name of the current entry.
Definition: ldif.cpp:405
Ldif::newRdn
QString newRdn() const
Returns the new Relative Distinguished Name if modType() returned Entry_Modrdn.
Definition: ldif.cpp:410
Ldif::entryType
EntryType entryType() const
Returns the requested LDAP operation extracted from the current entry.
Definition: ldif.cpp:395
Ldif
Ldif.
Definition: ldif_p.h:38
Ldif::delOldRdn
bool delOldRdn() const
Returns if the delete of the old RDN is required.
Definition: ldif.cpp:420
Ldif::splitLine
static bool splitLine(const QByteArray &line, QString &fieldname, QByteArray &value)
Splits one line from an Ldif file to attribute and value components.
Definition: ldif.cpp:129
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:01:05 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kabc

Skip menu "kabc"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal