You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
692 lines
17 KiB
692 lines
17 KiB
/*
|
|
** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au>
|
|
**
|
|
*/
|
|
|
|
/*
|
|
** This program is free software; you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation; either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program in a file called COPYING; if not, write to
|
|
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
** MA 02110-1301, USA.
|
|
*/
|
|
|
|
/*
|
|
** Bug reports and questions can be sent to kde-devel@kde.org
|
|
*/
|
|
|
|
#include "../config.h"
|
|
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <ctype.h>
|
|
|
|
#include <setjmp.h>
|
|
|
|
#include <tqdir.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqregexp.h>
|
|
|
|
#include <kurl.h>
|
|
#include <kglobal.h>
|
|
#include <kiconloader.h>
|
|
#include <kdebug.h>
|
|
|
|
#include "packageInfo.h"
|
|
#include "slackInterface.h"
|
|
#include "updateLoc.h"
|
|
#include "kpackage.h"
|
|
#include "managementWidget.h"
|
|
#include "utils.h"
|
|
#include "procbuf.h"
|
|
#include "options.h"
|
|
#include "cache.h"
|
|
#include <klocale.h>
|
|
|
|
|
|
#define DIR "/var/log/packages/"
|
|
#define FILELIST "FILE LIST:\n"
|
|
|
|
enum {INITIAL, INSTALLED, UNINSTALLED};
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
SLACK::SLACK():pkgInterface()
|
|
{
|
|
head = "SLACK";
|
|
name = i18n("Slackware");
|
|
icon = "slack";
|
|
|
|
pict = UserIcon(icon);
|
|
updated_pict = UserIcon("supdated");
|
|
new_pict = UserIcon("snew");
|
|
|
|
packagePattern = "*.tgz *.tar.gz";
|
|
typeID = "/slack";
|
|
|
|
locatedialog = 0;
|
|
|
|
queryMsg = i18n("Querying SLACK package list: ");
|
|
procMsg = i18n("KPackage: Waiting on SLACK");
|
|
|
|
locatedialog = new Locations(i18n("Location of Slackware Package Archives"));
|
|
locatedialog->pLocations(1, 1, this, i18n("Install location", "I"),
|
|
"Slackware", "*.TXT *.txt *.tgz *.tar.gz",
|
|
i18n("Location of a 'PACKAGES.TXT' File for Extended Information"));
|
|
locatedialog->pLocations(4, 1, this, i18n("Packages file", "P"),
|
|
"Slackware", "*.tgz *.tar.gz",
|
|
i18n("Location of 'PACKAGES.TXT' File for Slackware Distribution"),
|
|
i18n("Location of Base Folder of Slackware Distribution"));
|
|
locatedialog->dLocations(2, 6, this, i18n("Folders", "F"),
|
|
"Slackware", "*.tgz *.tar.gz",
|
|
i18n("Location of Folders Containing Slackware Packages"));
|
|
|
|
connect(locatedialog,TQT_SIGNAL(returnVal(LcacheObj *)),
|
|
this,TQT_SLOT(setAvail(LcacheObj *)));
|
|
locatedialog->apply_slot();
|
|
|
|
paramsInst.append(new param(i18n("Test (do not install)"),FALSE,FALSE,"-warn"));
|
|
|
|
paramsUninst.append(new param(i18n("Test (do not uninstall)"),FALSE,FALSE,"-warn"));
|
|
|
|
hasProgram = ifExe("installpkg");
|
|
|
|
initTranslate();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
SLACK::~SLACK()
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void SLACK::initTranslate()
|
|
{
|
|
trl = new TQDict<TQString>(53);
|
|
|
|
trl->insert("a",new TQString(i18n("Base System")));
|
|
trl->insert("ap",new TQString(i18n("Linux Applications")));
|
|
trl->insert("d",new TQString(i18n("Program Development")));
|
|
trl->insert("e",new TQString(i18n("GNU EMacs")));
|
|
trl->insert("f",new TQString(i18n("FAQs")));
|
|
trl->insert("k",new TQString(i18n("Kernel Source")));
|
|
trl->insert("n",new TQString(i18n("Networking")));
|
|
trl->insert("t",new TQString(i18n("TeX Distribution")));
|
|
trl->insert("tcl",new TQString(i18n("TCL Script Language")));
|
|
trl->insert("x",new TQString(i18n("X Window System")));
|
|
trl->insert("xap",new TQString(i18n("X Applications")));
|
|
trl->insert("xd",new TQString(i18n("X Development Tools")));
|
|
trl->insert("xv",new TQString(i18n("XView and OpenLook")));
|
|
trl->insert("y",new TQString(i18n("Games")));
|
|
}
|
|
|
|
// check if slack file
|
|
bool SLACK::isType(char *buf, const TQString &)
|
|
{
|
|
if (hasProgram) {
|
|
if ((unsigned char)buf[0] == 037 && (unsigned char)buf[1] == 0213 ) {
|
|
return true;
|
|
} else
|
|
return false;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool SLACK::parseName(const TQString &name, TQString *n, TQString *v)
|
|
{
|
|
int s1;
|
|
s1 = name.tqfindRev('.');
|
|
if (s1 > 0) {
|
|
*n = name.left(s1);
|
|
v = new TQString("");
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void SLACK::listPackages(TQPtrList<packageInfo> *pki)
|
|
{
|
|
TQString s;
|
|
cacheObj *cp;
|
|
|
|
if (packageLoc) {
|
|
for (cp = packageLoc->first(); cp != 0; cp = packageLoc->next()) {
|
|
// first entry is special
|
|
if (cp->cacheFile == "SLACK_0_0") {
|
|
s = getPackList(cp);
|
|
if (!s.isEmpty()) {
|
|
listPackList(pki, s, cp, INITIAL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
listInstalledPackages(pki);
|
|
|
|
if (packageLoc) {
|
|
for (cp = packageLoc->first(); cp != 0; cp = packageLoc->next()) {
|
|
if (cp->cacheFile == "SLACK_0_0") {
|
|
// already done
|
|
} else if ( !cp->base.isEmpty() ) {
|
|
s = getPackList(cp);
|
|
if (!s.isEmpty()) {
|
|
listPackList(pki, s, cp, UNINSTALLED);
|
|
}
|
|
} else {
|
|
s = getDir(cp);
|
|
if (!s.isEmpty()) {
|
|
listDir(pki,s,cp->location);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SLACK::listInstalledPackages(TQPtrList<packageInfo> *pki)
|
|
{
|
|
FILE *file;
|
|
char linebuf[1024];
|
|
TQString vb;
|
|
packageInfo *p;
|
|
TQString fn, dr = DIR;
|
|
|
|
TQDir d(DIR);
|
|
if (d.exists()) {
|
|
TQString sline = i18n("Querying SLACK package list: ");
|
|
kpackage->settqStatus(sline);
|
|
|
|
const TQFileInfoList *list = d.entryInfoList();
|
|
int count = list->count();
|
|
TQFileInfoListIterator it( *list ); // create list iterator
|
|
TQFileInfo *fi; // pointer for traversing
|
|
|
|
kpackage->setPercent(0);
|
|
int cnt = 0;
|
|
while ( (fi=it.current()) ) { // for each file...
|
|
int n = (cnt*100)/count;
|
|
if (!(n % 5))
|
|
kpackage->setPercent(n);
|
|
|
|
if (!fi->isDir() && fi->isReadable()) {
|
|
fn = dr + fi->fileName();
|
|
file = fopen(TQFile::encodeName(fn),"r");
|
|
if (file) {
|
|
vb = TQString();
|
|
while (fgets(linebuf,sizeof(linebuf),file)) {
|
|
if (strcmp(linebuf,FILELIST)) {
|
|
vb += linebuf;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
fclose(file);
|
|
p = collectInfo(vb.ascii(), INSTALLED);
|
|
if (p) {
|
|
smerge(p);
|
|
if (!p->pkgInsert(pki, typeID, TRUE))
|
|
delete p;
|
|
}
|
|
}
|
|
}
|
|
cnt++;
|
|
++it; // goto next list element
|
|
}
|
|
kpackage->setPercent(100);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void SLACK::listPackList(TQPtrList<packageInfo> *pki, const TQString &s, cacheObj *cp, int insState)
|
|
{
|
|
int np;
|
|
TQString vb;
|
|
char linebuf[1024];
|
|
FILE *file;
|
|
packageInfo *p;
|
|
|
|
TQString sline = i18n("Querying SLACK package list: ");
|
|
sline += cp->location;
|
|
|
|
kpackage->settqStatus(sline);
|
|
kpackage->setPercent(0);
|
|
|
|
np = 0;
|
|
file= fopen(TQFile::encodeName(s), "r");
|
|
vb = "";
|
|
|
|
if (file) {
|
|
while (fgets(linebuf,sizeof(linebuf),file)) {
|
|
int len = strlen(linebuf);
|
|
if (len > 1) {
|
|
if (linebuf[len - 2] == '\r') {
|
|
linebuf[len - 2] = '\n';
|
|
linebuf[len - 1] = 0;
|
|
}
|
|
}
|
|
if (strcmp(linebuf,"\n")) {
|
|
vb += linebuf;
|
|
} else if ( !vb.isEmpty() ) {
|
|
p = collectInfo(vb.ascii(), insState);
|
|
if (p) {
|
|
if (!p->pkgInsert(pki, typeID, insState == INITIAL, insState == INITIAL)) {
|
|
delete p;
|
|
} else if (cp && insState != INITIAL) {
|
|
p->info.insert("base", cp->base);
|
|
}
|
|
if (p && insState == INITIAL) {
|
|
p->packageState = packageInfo::NOLIST;
|
|
p->info.remove("summary");
|
|
}
|
|
}
|
|
vb.truncate(0);
|
|
}
|
|
}
|
|
fclose(file);
|
|
}
|
|
kpackage->setPercent(100);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// mode: i = query installed u = query uninstalled
|
|
packageInfo *SLACK::getPackageInfo(char mode, const TQString &name, const TQString &)
|
|
{
|
|
char linebuf[1024];
|
|
packageInfo *pki = 0;
|
|
TQString vb, search, fn;
|
|
TQString n,v;
|
|
FILE *file;
|
|
|
|
switch(mode) {
|
|
////////////////////////////////////////////////////////////////////////
|
|
// query an installed package!
|
|
case 'i':
|
|
fn = DIR + name;
|
|
file = fopen(TQFile::encodeName(fn),"r");
|
|
if (file) {
|
|
vb = TQString();
|
|
while (fgets(linebuf,sizeof(linebuf),file)) {
|
|
if (strcmp(linebuf,FILELIST)) {
|
|
vb += linebuf;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
fclose(file);
|
|
pki = collectInfo(vb.ascii(), INSTALLED);
|
|
if (pki) {
|
|
smerge(pki);
|
|
}
|
|
}
|
|
break;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// query an uninstalled package
|
|
case 'u':
|
|
TQFile f(name);
|
|
if (f.exists()) {
|
|
TQMap<TQString, TQString> a;
|
|
|
|
a.insert("group", i18n("OTHER"));
|
|
a.insert("filename", name);
|
|
|
|
TQFileInfo f(name);
|
|
a.insert("name", f.baseName());
|
|
|
|
TQString st;
|
|
st.setNum(f.size());
|
|
a.insert("file-size", st);
|
|
|
|
pki = new packageInfo(a,this);
|
|
if (pki) {
|
|
smerge(pki);
|
|
pki->updated = TRUE;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return pki;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
packageInfo *SLACK::collectInfo(const char *_inp, int insState)
|
|
{
|
|
TQString stmp, fn = "";
|
|
TQMap<TQString, TQString> a;
|
|
|
|
char *str, *xstr;
|
|
TQString qstr;
|
|
|
|
char *inp = qstrdup(_inp);
|
|
str = strtok(inp,"\n");
|
|
|
|
if (str) {
|
|
do {
|
|
if (str[0] == 0)
|
|
break;
|
|
|
|
xstr = strchr(str,':');
|
|
if (xstr) {
|
|
*xstr++ = 0;
|
|
xstr++;
|
|
while (*xstr == ' ') {
|
|
xstr++;
|
|
}
|
|
|
|
for( int i = 0; str[ i ] != '\0'; ++i )
|
|
str[ i ] = tolower( str[ i ] );
|
|
|
|
if (*str == ' ')
|
|
str++;
|
|
|
|
if (!strcmp("package name",str)) {
|
|
fn = xstr;
|
|
TQString st = xstr;
|
|
if (st.right(4) == ".tgz")
|
|
a.insert("name", st.left(st.length() - 4));
|
|
else
|
|
a.insert("name", st);
|
|
} else if (!strcmp("package description",str)) {
|
|
int i = 0;
|
|
TQString qstr = "";
|
|
|
|
while ((str = strtok(NULL,"\n"))) {
|
|
xstr = strchr(str,':');
|
|
if (xstr) {
|
|
*xstr++ = 0;
|
|
if (*(xstr) != 0)
|
|
xstr++;
|
|
while (*xstr == ' ') {
|
|
xstr++;
|
|
}
|
|
if (i == 0) {
|
|
a.insert("summary", xstr);
|
|
} else {
|
|
if (!strcmp(xstr,"") && (i != 1)) {
|
|
qstr += "\n";
|
|
} else {
|
|
qstr += xstr;
|
|
qstr += " ";
|
|
}
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
a.insert("description", qstr);
|
|
} else if (!strcmp("package location",str)) {
|
|
TQString sl = xstr;
|
|
if (insState != INSTALLED) {
|
|
int sls = sl.tqfindRev("/");
|
|
if (sls >= 0) {
|
|
TQRegExp num("[0-9][0-9]*");
|
|
int slf = sl.tqfind(num,sls);
|
|
if (slf >= 0) {
|
|
sls++;
|
|
TQString gt = sl.mid(sls,slf-sls);
|
|
if (trl->tqfind(gt)) {
|
|
gt = *trl->tqfind(gt);
|
|
}
|
|
a.insert("group",gt);
|
|
}
|
|
}
|
|
sl = sl.right(sl.length() - 2);
|
|
sl += "/";
|
|
sl += fn;
|
|
}
|
|
if (insState == UNINSTALLED) {
|
|
a.insert("filename", sl);
|
|
}
|
|
} else if (!strcmp("section",str)) {
|
|
a.insert("group", xstr);
|
|
} else if (!strcmp("compressed package size",str) ||
|
|
!strcmp("package size (compressed)",str)) {
|
|
TQString stmp = xstr;
|
|
stmp.truncate(stmp.length() - 2);
|
|
stmp += "000";
|
|
a.insert("file-size", stmp);
|
|
} else if (!strcmp("uncompressed package size",str) ||
|
|
!strcmp("package size (uncompressed)",str)) {
|
|
TQString stmp = xstr;
|
|
stmp.truncate(stmp.length() - 2);
|
|
stmp += "000";
|
|
a.insert("size", stmp);
|
|
} else {
|
|
a.insert(str, xstr);
|
|
}
|
|
}
|
|
} while ((str = strtok(NULL,"\n")));
|
|
}
|
|
|
|
delete [] inp;
|
|
|
|
if (a["name"].isEmpty()) {
|
|
return 0;
|
|
} else {
|
|
packageInfo *i = new packageInfo(a,this);
|
|
i->packageState = packageInfo::INSTALLED;
|
|
i->fixup();
|
|
return i;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
TQStringList SLACK::getChangeLog(packageInfo *) {
|
|
return 0;
|
|
}
|
|
|
|
bool SLACK::filesTab(packageInfo *) {
|
|
return TRUE;
|
|
}
|
|
|
|
bool SLACK::changeTab(packageInfo *) {
|
|
return FALSE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
TQStringList SLACK::getFileList(packageInfo *p)
|
|
{
|
|
char linebuf[1024];
|
|
TQString st, fn;
|
|
FILE *file;
|
|
TQString name;
|
|
char mode;
|
|
|
|
fn = p->getFilename();
|
|
if(!fn.isEmpty())
|
|
mode = 'u';
|
|
else
|
|
mode = 'i';
|
|
|
|
TQStringList filelist;
|
|
|
|
switch(mode) {
|
|
////////////////////////////////////////////////////////////////////////
|
|
// query an installed package!
|
|
case 'i':
|
|
name = p->getProperty("name");
|
|
|
|
fn = DIR + name;
|
|
file = fopen(TQFile::encodeName(fn),"r");
|
|
if (file) {
|
|
while (fgets(linebuf,sizeof(linebuf),file)) {
|
|
if (!strcmp(linebuf,FILELIST)) {
|
|
break;
|
|
}
|
|
}
|
|
while (fgets(linebuf,sizeof(linebuf),file)) {
|
|
st = "/";
|
|
st += linebuf;
|
|
st.truncate(st.length() -1);
|
|
if (st.left(8) != "/install") {
|
|
filelist.append(st);
|
|
}
|
|
}
|
|
fclose(file);
|
|
}
|
|
break;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// query an uninstalled package
|
|
case 'u':
|
|
name = fn;
|
|
|
|
TQString s = "sh -c 'cat ";
|
|
s += fn;
|
|
s += "|gunzip |tar -t -f -'";
|
|
|
|
filelist = kpty->run(s);
|
|
break;
|
|
}
|
|
|
|
return filelist;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Call the script to uninstall packages setting parameters
|
|
// to slack dependent on flags, returning whether everyting worked
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
TQString SLACK::doUninstall(int uninstallFlags, const TQString &packs, bool &)
|
|
{
|
|
TQString s = "removepkg ";
|
|
s += setOptions(uninstallFlags, paramsUninst);
|
|
s += packs;
|
|
|
|
kdDebug() << "uCMD=" << s << "\n";
|
|
|
|
return s;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Call the script to install packages setting parameters
|
|
// to slack dependent on flags, returning whether everyting worked
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
TQString SLACK::install(int installFlags, TQPtrList<packageInfo> *plist, bool &test)
|
|
{
|
|
packageInfo *pk;
|
|
int i = 0;
|
|
TQString packs = "";
|
|
for (pk = plist->first(); pk != 0; pk = plist->next()) {
|
|
TQString fname = pk->fetchFilename();
|
|
if ( !fname.isEmpty() ) {
|
|
packs += fname + " ";
|
|
i++;
|
|
}
|
|
}
|
|
return doInstall(installFlags, packs, test);
|
|
}
|
|
|
|
TQString SLACK::doInstall(int installFlags, const TQString &packs, bool &)
|
|
{
|
|
|
|
TQString s = "installpkg ";
|
|
s += setOptions(installFlags, paramsInst);
|
|
s += packs;
|
|
|
|
kdDebug() << "iCMD=" << s << "\n";
|
|
|
|
return s;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
TQStringList SLACK::FindFile(const TQString &name, bool)
|
|
{
|
|
FILE *file;
|
|
char linebuf[1024];
|
|
TQString buf, st;
|
|
TQString fn, dr = DIR;
|
|
TQStringList filelist;
|
|
|
|
TQDir d(DIR);
|
|
if (d.exists()) {
|
|
TQString sline = i18n("Querying SLACK package list: ");
|
|
kpackage->settqStatus(sline);
|
|
|
|
const TQFileInfoList *list = d.entryInfoList();
|
|
int count = list->count();
|
|
TQFileInfoListIterator it( *list ); // create list iterator
|
|
TQFileInfo *fi; // pointer for traversing
|
|
|
|
kpackage->setPercent(0);
|
|
int cnt = 0;
|
|
while ( (fi=it.current()) ) { // for each file...
|
|
int n = (cnt*100)/count;
|
|
if (!(n % 5))
|
|
kpackage->setPercent(n);
|
|
|
|
if (!fi->isDir() && fi->isReadable()) {
|
|
fn = dr + fi->fileName();
|
|
file = fopen(TQFile::encodeName(fn),"r");
|
|
if (file) {
|
|
while (fgets(linebuf,sizeof(linebuf),file)) {
|
|
if (!strcmp(linebuf,FILELIST)) {
|
|
break;
|
|
}
|
|
}
|
|
while (fgets(linebuf,sizeof(linebuf),file)) {
|
|
if (TQString(TQString::fromLocal8Bit(linebuf)).tqfind(name) != -1) {
|
|
st = "/";
|
|
st += linebuf;
|
|
st.truncate(st.length() -1);
|
|
if (st.left(8) != "/install") {
|
|
TQString s = fi->fileName();
|
|
s += "\t";
|
|
s += st;
|
|
filelist.append(s);
|
|
}
|
|
}
|
|
}
|
|
fclose(file);
|
|
}
|
|
}
|
|
cnt++;
|
|
++it; // goto next list element
|
|
}
|
|
}
|
|
return filelist;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void SLACK::setLocation()
|
|
{
|
|
locatedialog->restore();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void SLACK::setAvail(LcacheObj *slist)
|
|
{
|
|
delete packageLoc;
|
|
packageLoc = slist;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
void SLACK::smerge(packageInfo *p)
|
|
{
|
|
p->smerge(typeID);
|
|
}
|
|
#include "slackInterface.moc"
|