00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <opie2/oprocess.h>
00031
00032 #ifdef QWS
00033 #include <qpe/qpeapplication.h>
00034 #else
00035 #include <qapplication.h>
00036 #endif
00037 #include <qdir.h>
00038 #include <qfile.h>
00039 #include <qtextstream.h>
00040
00041 #include "utils.h"
00042 #include "ipkg.h"
00043 #include "global.h"
00044
00045 using namespace Opie::Core;
00046 Ipkg :: Ipkg()
00047 {
00048 proc = 0;
00049 }
00050
00051 Ipkg :: ~Ipkg()
00052 {
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 void Ipkg :: runIpkg()
00065 {
00066 error = false;
00067 QStringList commands;
00068
00069 QDir::setCurrent( "/tmp" );
00070
00071 if ( runtimeDir != "" )
00072 {
00073 commands << "cd ";
00074 commands << runtimeDir;
00075 commands << ";";
00076 }
00077 commands << "ipkg" << "-V" << QString::number( infoLevel ) << "-force-defaults";
00078
00079
00080 if ( option == "install" )
00081 commands << "-dest" << destination;
00082
00083
00084 if ( option != "update" && option != "download" )
00085 {
00086 if ( flags & FORCE_DEPENDS )
00087 commands << "-force-depends";
00088 if ( flags & FORCE_REINSTALL )
00089 commands << "-force-reinstall";
00090 if ( flags & FORCE_REMOVE )
00091 commands << "-force-removal-of-essential-packages";
00092 if ( flags & FORCE_OVERWRITE )
00093 commands << "-force-overwrite";
00094 if ( infoLevel == 3 )
00095 commands << "-verbose_wget";
00096
00097
00098
00099
00100 if ( flags & MAKE_LINKS )
00101 {
00102
00103
00104 if ( destDir == "/" )
00105 flags ^= MAKE_LINKS;
00106 }
00107 }
00108
00109 #ifdef X86
00110 commands << "-f";
00111 commands << IPKG_CONF;
00112 #endif
00113
00114
00115 if ( option == "reinstall" )
00116 commands << "install";
00117 else
00118 commands << option;
00119 if ( package != "" )
00120 commands << package;
00121
00122
00123 if ( package != "" )
00124 emit outputText( tr( "Dealing with package %1" ).arg( package) );
00125
00126 qApp->processEvents();
00127
00128
00129
00130 if ( option == "remove" || option == "reinstall" || option == "upgrade" )
00131 {
00132 createLinks = false;
00133 if ( flags & MAKE_LINKS )
00134 {
00135 emit outputText( tr( "Removing symbolic links...\n" ) );
00136 linkPackage( Utils::getPackageNameFromIpkFilename( package ), destination, destDir );
00137 emit outputText( QString( " " ) );
00138 }
00139 }
00140
00141
00142 dependantPackages = new QList<QString>;
00143 dependantPackages->setAutoDelete( true );
00144
00145 executeIpkgCommand( commands, option );
00146 }
00147
00148 void Ipkg :: createSymLinks()
00149 {
00150 if ( option == "install" || option == "reinstall" || option == "upgrade" )
00151 {
00152
00153
00154 createLinks = true;
00155 if ( flags & MAKE_LINKS )
00156 {
00157 emit outputText( " " );
00158 emit outputText( tr( "Creating symbolic links for %1." ).arg( package) );
00159
00160 linkPackage( Utils::getPackageNameFromIpkFilename( package ), destination, destDir );
00161
00162
00163 QString *pkg;
00164 for ( pkg = dependantPackages->first(); pkg != 0; pkg = dependantPackages->next() )
00165 {
00166 if ( *pkg == package )
00167 continue;
00168 emit outputText( " " );
00169 emit outputText( tr( "Creating symbolic links for %1" ).arg( *pkg ) );
00170 linkPackage( Utils::getPackageNameFromIpkFilename( *pkg ), destination, destDir );
00171 }
00172 }
00173 }
00174
00175 delete dependantPackages;
00176
00177 emit outputText( tr("Finished") );
00178 emit outputText( "" );
00179 }
00180
00181 void Ipkg :: removeStatusEntry()
00182 {
00183 QString statusFile = destDir;
00184 if ( statusFile.right( 1 ) != "/" )
00185 statusFile.append( "/" );
00186 statusFile.append( "usr/lib/ipkg/status" );
00187 QString outStatusFile = statusFile;
00188 outStatusFile.append( ".tmp" );
00189
00190 emit outputText( "" );
00191 emit outputText( tr("Removing status entry...") );
00192 QString tempstr = tr("status file - ");
00193 tempstr.append( statusFile );
00194 emit outputText( tempstr );
00195 tempstr = tr("package - ");
00196 tempstr.append( package );
00197 emit outputText( tempstr );
00198
00199 QFile readFile( statusFile );
00200 QFile writeFile( outStatusFile );
00201
00202 if ( !readFile.open( IO_ReadOnly ) )
00203 {
00204 tempstr = tr("Couldn't open status file - ");
00205 tempstr.append( statusFile );
00206 emit outputText( tempstr );
00207 return;
00208 }
00209
00210 if ( !writeFile.open( IO_WriteOnly ) )
00211 {
00212 tempstr = tr("Couldn't create tempory status file - ");
00213 tempstr.append( outStatusFile );
00214 emit outputText( tempstr );
00215 return;
00216 }
00217
00218 int i = 0;
00219
00220 QTextStream readStream( &readFile );
00221 QTextStream writeStream( &writeFile );
00222 QString line;
00223
00224 char k[21];
00225 char v[1001];
00226 QString key;
00227 QString value;
00228
00229 while ( !readStream.atEnd() )
00230 {
00231
00232 line = readStream.readLine();
00233
00234 if ( line.contains( ":", TRUE ) )
00235 {
00236
00237 k[0] = '\0';
00238 v[0] = '\0';
00239 sscanf( line, "%[^:]: %[^\n]", k, v );
00240 key = k;
00241 value = v;
00242 key = key.stripWhiteSpace();
00243 value = value.stripWhiteSpace();
00244 } else {
00245 key = "";
00246 value = "";
00247 }
00248
00249 if ( key == "Package" && value == package )
00250 {
00251
00252 while ( ( !readStream.atEnd() ) && ( line.stripWhiteSpace() != "" ) )
00253 {
00254 line = readStream.readLine();
00255 }
00256 } else {
00257
00258
00259 writeStream << line << "\n";
00260
00261
00262 i++;
00263 if ( ( i % 50 ) == 0 )
00264 qApp->processEvents();
00265 }
00266 }
00267
00268 readFile.close();
00269 writeFile.close();
00270
00271
00272 remove( statusFile );
00273 rename( outStatusFile, statusFile );
00274 }
00275
00276 int Ipkg :: executeIpkgLinkCommand( QStringList *cmd )
00277 {
00278
00279 if ( proc )
00280 {
00281 delete proc;
00282 proc = 0;
00283 }
00284
00285
00286 proc = new OProcess();
00287 aborted = false;
00288
00289
00290 connect(proc, SIGNAL(processExited(Opie::Core::OProcess*)),
00291 this, SLOT( linkProcessFinished()));
00292 connect(proc, SIGNAL(receivedStdout(Opie::Core::OProcess*,char*,int)),
00293 this, SLOT(linkCommandStdout(Opie::Core::OProcess*,char*,int)));
00294
00295 *proc << *cmd;
00296
00297 if(!proc->start(OProcess::NotifyOnExit, OProcess::All))
00298 {
00299 emit outputText( tr("Couldn't start ipkg-link process" ) );
00300 }
00301
00302 return 0;
00303 }
00304
00305 void Ipkg::linkProcessFinished()
00306 {
00307
00308
00309 if ( error )
00310 emit outputText( tr("Symbolic linking failed!\n") );
00311 else
00312 emit outputText( tr("Symbolic linking succeeded.\n") );
00313
00314 delete proc;
00315 proc = 0;
00316 finished = true;
00317 }
00318
00319 void Ipkg::linkCommandStdout(OProcess*, char *buffer, int buflen)
00320 {
00321 QString lineStr = buffer;
00322 if ( lineStr[buflen-1] == '\n' )
00323 buflen --;
00324 lineStr = lineStr.left( buflen );
00325 emit outputText( lineStr );
00326
00327 if ( lineStr.find( " not found." ) != -1 )
00328 {
00329
00330 error = true;
00331 }
00332
00333 buffer[0] = '\0';
00334 }
00335
00336 int Ipkg :: executeIpkgCommand( QStringList &cmd, const QString )
00337 {
00338
00339 if ( proc )
00340 {
00341 delete proc;
00342 proc = 0;
00343 }
00344
00345
00346 proc = new OProcess();
00347 aborted = false;
00348
00349
00350
00351 connect(proc, SIGNAL(processExited(Opie::Core::OProcess*)),
00352 this, SLOT( processFinished()));
00353
00354 connect(proc, SIGNAL(receivedStdout(Opie::Core::OProcess*,char*,int)),
00355 this, SLOT(commandStdout(Opie::Core::OProcess*,char*,int)));
00356
00357 connect(proc, SIGNAL(receivedStderr(Opie::Core::OProcess*,char*,int)),
00358 this, SLOT(commandStderr(Opie::Core::OProcess*,char*,int)));
00359
00360 for ( QStringList::Iterator it = cmd.begin(); it != cmd.end(); ++it )
00361 {
00362 *proc << (*it).latin1();
00363 }
00364
00365
00366 finished = false;
00367 if(!proc->start(OProcess::NotifyOnExit, OProcess::All))
00368 {
00369 emit outputText( tr("Couldn't start ipkg process" ) );
00370 }
00371
00372 return 0;
00373 }
00374
00375 void Ipkg::commandStdout(OProcess*, char *buffer, int buflen)
00376 {
00377 QString lineStr = buffer;
00378 if ( lineStr[buflen-1] == '\n' )
00379 buflen --;
00380 lineStr = lineStr.left( buflen );
00381 emit outputText( lineStr );
00382
00383
00384 if ( option == "install" || option == "reinstall" )
00385 {
00386
00387
00388 if ( lineStr.startsWith( "Installing " ) )
00389 {
00390 int start = lineStr.find( " " ) + 1;
00391 int end = lineStr.find( " ", start );
00392 QString *package = new QString( lineStr.mid( start, end-start ) );
00393 dependantPackages->append( package );
00394 }
00395 }
00396 else if ( option == "remove" && !( flags & FORCE_DEPENDS ) &&
00397 lineStr.find( "is depended upon by packages:" ) != -1 )
00398 {
00399
00400 error = true;
00401 }
00402
00403 buffer[0] = '\0';
00404 }
00405
00406 void Ipkg::commandStderr(OProcess*, char *buffer, int buflen)
00407 {
00408 QString lineStr = buffer;
00409 if ( lineStr[buflen-1] == '\n' )
00410 buflen --;
00411 lineStr=lineStr.left( buflen );
00412 emit outputText( lineStr );
00413 buffer[0] = '\0';
00414 error = true;
00415 }
00416
00417 void Ipkg::processFinished()
00418 {
00419
00420
00421
00422 if ( !error && option == "remove" )
00423 removeStatusEntry();
00424
00425 delete proc;
00426 proc = 0;
00427 finished = true;
00428
00429 emit ipkgFinished();
00430 }
00431
00432
00433 void Ipkg :: abort()
00434 {
00435 if ( proc )
00436 {
00437 proc->kill();
00438 aborted = true;
00439 }
00440 }
00441
00442 void Ipkg :: linkPackage( const QString &packFileName, const QString &dest, const QString &destDir )
00443 {
00444 Q_CONST_UNUSED( destDir )
00445 if ( dest == "root" || dest == "/" )
00446 return;
00447
00448 if( option == "remove" || option == "reinstall" || option == "upgrade" )
00449 {
00450 QStringList commands;
00451
00452 if ( runtimeDir != "" )
00453 {
00454 commands << "cd ";
00455 commands << runtimeDir;
00456 commands << ";";
00457 }
00458 commands << "ipkg-link" << "remove" << packFileName;
00459 executeIpkgLinkCommand( &commands );
00460 }
00461
00462 if( option == "install" || option == "reinstall" || option == "upgrade" )
00463 {
00464 QStringList commands;
00465 if ( runtimeDir != "" )
00466 {
00467 commands << "cd ";
00468 commands << runtimeDir;
00469 commands << ";";
00470 }
00471 commands << "ipkg-link" << "add" << packFileName;
00472 executeIpkgLinkCommand( &commands );
00473 }
00474
00475
00476
00477
00478
00479
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611