File: dpkg_popen.cc

package info (click to toggle)
cruft-ng 0.4.7
  • links: PTS, VCS
  • area: main
  • in suites: buster, sid
  • size: 152 kB
  • sloc: cpp: 779; ansic: 92; makefile: 37; sh: 9
file content (116 lines) | stat: -rw-r--r-- 2,987 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <iostream>
#include <fstream>
#include <algorithm>
#include <stdio.h>
#include <sys/stat.h>
#include "dpkg.h"
#include "usr_merge.h"

int read_dpkg_header(vector<string>& packages)
{
	bool debug=getenv("DEBUG") != NULL;

	// TODO: read DPKG database directly instead of using dpkg-query
	if (debug) cerr << "DPKG DATA\n";
	FILE* fp;
	if ((fp = popen("dpkg-query --show --showformat '${binary:Package}\n'", "r")) == NULL) return 1;
	const int SIZEBUF = 4096;
	char buf[SIZEBUF];
	string package;
	while (fgets(buf, sizeof(buf),fp))
	{
		package=buf;
		package=package.substr(0,package.size() - 1); // remove '/n'
		//cerr << package << endl;
		packages.push_back(package);
	}
	pclose(fp);
	if (debug) cerr << packages.size() << " packages installed"  << endl << endl;
	return 0;
}

struct Diversion{
	string oldfile;
	string newfile;
	string package;
	Diversion(string oldfile,string newfile,string package)
	{
		this->oldfile=oldfile;
		this->newfile=newfile;
		this->package=package;
	}
};

int read_diversions(vector<Diversion>& diversions)
{
	ifstream txt("/var/lib/dpkg/diversions");
	while(!txt.eof())
	{
		string oldfile,newfile,package;
		getline(txt,oldfile);
		getline(txt,newfile);
		getline(txt,package);
		diversions.push_back(Diversion(oldfile,newfile,package));
	}
	txt.close();
	return 0;
}

int read_dpkg_items(vector<string>& dpkg)
{
	bool debug=getenv("DEBUG") != NULL;

	if (debug) cerr << "READING FILES IN DPKG DATABASE" << endl;
	vector<Diversion> diversions;
	read_diversions(diversions);

	// TODO: read DPKG database instead of using dpkg-query
	// cat /var/lib/dpkg/info/ *.list |sort -u
        string command="dpkg-query --listfiles $(dpkg-query --show --showformat '${binary:Package} ')|sort -u";
	const int SIZEBUF = 200;
	char buf[SIZEBUF];
	FILE* fp;
	if ((fp = popen(command.c_str(), "r")) == NULL) return 1;
	while (fgets(buf, sizeof(buf),fp))
	{
		string filename=buf;
		if (filename.substr(0,1)!="/") continue;
		filename=filename.substr(0,filename.size() - 1);
		// TODO: ignore ${prunepaths} here also
		vector<Diversion>::iterator it=diversions.begin();
		struct stat stat_buffer;
		for(;it !=diversions.end();it++) {
			if (filename==(*it).oldfile
		            && stat(filename.c_str(),&stat_buffer)!= 0) filename=(*it).newfile;
		}

		dpkg.push_back(usr_merge(filename));


		// also consider all intermediate subdirectories under /etc
		if (filename.substr(0,5)!="/etc/")
			continue;

		if (stat(filename.c_str(),&stat_buffer) == 0)
			if ((stat_buffer.st_mode & S_IFDIR) != 0)
				continue;

		while (1)
		{
			size_t found;
			found=filename.find_last_of("/");
			filename=filename.substr(0,found);
			if (filename == "/etc")
				break;

			dpkg.push_back(filename);
		}
	}
        pclose(fp);
	if (debug) cerr << "done"  << endl;
	sort(dpkg.begin(), dpkg.end());
	// remove duplicates
	dpkg.erase( unique( dpkg.begin(), dpkg.end() ), dpkg.end() );
	if (debug) cerr << dpkg.size() << " files in DPKG database" << endl;
	return 0;
}