]> git.saurik.com Git - apt.git/blame - cmdline/apt-sortpkgs.cc
fix file ownership tests to work on kfreebsd
[apt.git] / cmdline / apt-sortpkgs.cc
CommitLineData
b2e465d6
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
8f312f45 3// $Id: apt-sortpkgs.cc,v 1.5 2003/01/11 07:18:44 jgg Exp $
b2e465d6
AL
4/* ######################################################################
5
6 APT Sort Packages - Program to sort Package and Source files
7
8 This program is quite simple, it just sorts the package files by
9 package and sorts the fields inside by the internal APT sort order.
10 Input is taken from a named file and sent to stdout.
11
12 ##################################################################### */
13 /*}}}*/
14// Include Files /*{{{*/
ea542140
DK
15#include <config.h>
16
b2e465d6
AL
17#include <apt-pkg/tagfile.h>
18#include <apt-pkg/error.h>
19#include <apt-pkg/configuration.h>
20#include <apt-pkg/cmndline.h>
21#include <apt-pkg/init.h>
22#include <apt-pkg/strutl.h>
472ff00e
DK
23#include <apt-pkg/fileutl.h>
24#include <apt-pkg/pkgsystem.h>
b2e465d6 25
ad7e0941
DK
26#include <apt-private/private-cmndline.h>
27
b2e465d6
AL
28#include <vector>
29#include <algorithm>
453b82a3
DK
30#include <stdio.h>
31#include <iostream>
32#include <string>
ea542140
DK
33
34#include <apti18n.h>
b2e465d6
AL
35 /*}}}*/
36
8f312f45
AL
37using namespace std;
38
92fcbfc1 39struct PkgName /*{{{*/
b2e465d6
AL
40{
41 string Name;
42 string Ver;
43 string Arch;
44 unsigned long Offset;
45 unsigned long Length;
46
47 inline int Compare3(const PkgName &x) const
48 {
49 int A = stringcasecmp(Name,x.Name);
50 if (A == 0)
51 {
52 A = stringcasecmp(Ver,x.Ver);
53 if (A == 0)
54 A = stringcasecmp(Arch,x.Arch);
55 }
56 return A;
57 }
58
59 bool operator <(const PkgName &x) const {return Compare3(x) < 0;};
60 bool operator >(const PkgName &x) const {return Compare3(x) > 0;};
61 bool operator ==(const PkgName &x) const {return Compare3(x) == 0;};
62};
92fcbfc1 63 /*}}}*/
b2e465d6
AL
64// DoIt - Sort a single file /*{{{*/
65// ---------------------------------------------------------------------
66/* */
c3ccac92 67static bool DoIt(string InFile)
b2e465d6
AL
68{
69 FileFd Fd(InFile,FileFd::ReadOnly);
70 pkgTagFile Tags(&Fd);
71 if (_error->PendingError() == true)
72 return false;
73
74 // Parse.
75 vector<PkgName> List;
76 pkgTagSection Section;
77 unsigned long Largest = 0;
78 unsigned long Offset = Tags.Offset();
79 bool Source = _config->FindB("APT::SortPkgs::Source",false);
80 while (Tags.Step(Section) == true)
81 {
82 PkgName Tmp;
83
84 /* Fetch the name, auto-detecting if this is a source file or a
85 package file */
86 Tmp.Name = Section.FindS("Package");
87 Tmp.Ver = Section.FindS("Version");
88 Tmp.Arch = Section.FindS("Architecture");
89
90 if (Tmp.Name.empty() == true)
91 return _error->Error(_("Unknown package record!"));
92
93 Tmp.Offset = Offset;
94 Tmp.Length = Section.size();
95 if (Largest < Tmp.Length)
96 Largest = Tmp.Length;
97
98 List.push_back(Tmp);
99
100 Offset = Tags.Offset();
101 }
102 if (_error->PendingError() == true)
103 return false;
104
105 // Sort it
106 sort(List.begin(),List.end());
107
108 const char **Order = TFRewritePackageOrder;
109 if (Source == true)
110 Order = TFRewriteSourceOrder;
111
112 // Emit
113 unsigned char *Buffer = new unsigned char[Largest+1];
91c03d37 114 for (vector<PkgName>::iterator I = List.begin(); I != List.end(); ++I)
b2e465d6
AL
115 {
116 // Read in the Record.
117 if (Fd.Seek(I->Offset) == false || Fd.Read(Buffer,I->Length) == false)
118 {
119 delete [] Buffer;
120 return false;
121 }
122
123 Buffer[I->Length] = '\n';
124 if (Section.Scan((char *)Buffer,I->Length+1) == false)
125 {
126 delete [] Buffer;
127 return _error->Error("Internal error, failed to scan buffer");
128 }
129
130 // Sort the section
131 if (TFRewrite(stdout,Section,Order,0) == false)
132 {
133 delete [] Buffer;
134 return _error->Error("Internal error, failed to sort fields");
135 }
136
137 fputc('\n',stdout);
138 }
139
140 delete [] Buffer;
141 return true;
142}
143 /*}}}*/
144// ShowHelp - Show the help text /*{{{*/
145// ---------------------------------------------------------------------
146/* */
ad7e0941 147static bool ShowHelp(CommandLine &)
b2e465d6 148{
9179f697 149 ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION,
5b28c804 150 COMMON_ARCH,__DATE__,__TIME__);
b2e465d6 151 if (_config->FindB("version") == true)
ad7e0941 152 return true;
b2e465d6
AL
153
154 cout <<
155 _("Usage: apt-sortpkgs [options] file1 [file2 ...]\n"
156 "\n"
157 "apt-sortpkgs is a simple tool to sort package files. The -s option is used\n"
158 "to indicate what kind of file it is.\n"
159 "\n"
160 "Options:\n"
161 " -h This help text\n"
162 " -s Use source file sorting\n"
163 " -c=? Read this configuration file\n"
a2884e32 164 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n");
b2e465d6 165
ad7e0941 166 return true;
b2e465d6
AL
167}
168 /*}}}*/
92fcbfc1 169int main(int argc,const char *argv[]) /*{{{*/
b2e465d6
AL
170{
171 CommandLine::Args Args[] = {
172 {'h',"help","help",0},
173 {'v',"version","version",0},
174 {'s',"source","APT::SortPkgs::Source",0},
175 {'c',"config-file",0,CommandLine::ConfigFile},
176 {'o',"option",0,CommandLine::ArbItem},
177 {0,0,0,0}};
67111687
AL
178
179 // Set up gettext support
180 setlocale(LC_ALL,"");
181 textdomain(PACKAGE);
182
b2e465d6 183 // Parse the command line and initialize the package library
ad7e0941
DK
184 CommandLine::Dispatch Cmds[] = {{NULL, NULL}};
185 CommandLine CmdL;
186 ParseCommandLine(CmdL, Cmds, Args, &_config, &_system, argc, argv, ShowHelp);
b2e465d6
AL
187
188 // Match the operation
189 for (unsigned int I = 0; I != CmdL.FileSize(); I++)
190 if (DoIt(CmdL.FileList[I]) == false)
191 break;
192
193 // Print any errors or warnings found during parsing
194 if (_error->empty() == false)
195 {
196 bool Errors = _error->PendingError();
197 _error->DumpErrors();
198 return Errors == true?100:0;
199 }
200
201 return 0;
202}
92fcbfc1 203 /*}}}*/