/*
		    GNU GENERAL PUBLIC LICENSE
		       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
 		59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

			    Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

		    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,

    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

			    NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

		     END OF TERMS AND CONDITIONS

	Appendix: How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) 19yy  <name of author>

    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; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) 19yy name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  `Gnomovision' (which makes passes at compilers) written by James Hacker.

  <signature of Ty Coon>, 1 April 1989
  Ty Coon, President of Vice

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Library General
Public License instead of this License.
*/


#ifndef LIB_CARDS_INCLUDED
#define LIB_CARDS_INCLUDED


#include <string>
#include <iterator>
#include <iostream>

#include <syslog.h>
#include <stdio.h>
#include <sys/utsname.h>
#include <locale.h>
#include <libintl.h>

#define _ gettext

/**
 Return the same as 'uname -m' commands
 */
std::string getMachineType ();




#include <cstring>

#define RED "\033[1;31m"
#define GREEN "\033[1;32m"
#define YELLOW "\033[1;33m"
#define BLUE "\033[1;34m"
#define MAGENTA "\033[1;35m"
#define CYAN "\033[1;36m"
#define WHITE "\033[1;37m"
#define NORMAL "\033[1;0m"

#define ACTION _("\033[1;33maction:\033[1;0m")
#define USAGE _("\033[1;33musage: \033[1;0m")
#define OPTIONS _("\033[1;33moptions\033[1;0m")
#define REQUIRED _("\033[1;33mrequired\033[1;0m")
#define DESCRIPTION  _("\033[1;33mdescription: \033[1;0m")
#define COMMAND _("\033[1;34mcommand\033[1;0m")


enum error
{
CANNOT_FIND_DEPOT,
CANNOT_DOWNLOAD_FILE,
CANNOT_CREATE_FILE,
CANNOT_OPEN_FILE,
CANNOT_FIND_FILE,
CANNOT_READ_FILE,
CANNOT_COPY_FILE,
CANNOT_PARSE_FILE,
CANNOT_READ_DIRECTORY,
CANNOT_WRITE_FILE,
CANNOT_SYNCHRONIZE,
CANNOT_RENAME_FILE,
CANNOT_DETERMINE_NAME_BUILDNR,
WRONG_ARCHITECTURE,
EMPTY_PACKAGE,
CANNOT_FORK,
WAIT_PID_FAILED,
DATABASE_LOCKED,
CANNOT_LOCK_DIRECTORY,
CANNOT_REMOVE_FILE,
CANNOT_CREATE_DIRECTORY,
CANNOT_RENAME_DIRECTORY,
OPTION_ONE_ARGUMENT,
INVALID_OPTION,
OPTION_MISSING,
TOO_MANY_OPTIONS,
ONLY_ROOT_CAN_INSTALL_UPGRADE_REMOVE,
PACKAGE_IN_USE,
PACKAGE_NOT_EXIST,
PACKAGE_NOT_FOUND,
PACKAGE_ALLREADY_INSTALL,
PACKAGE_NOT_INSTALL,
PACKAGE_NOT_PREVIOUSLY_INSTALL,
LISTED_FILES_ALLREADY_INSTALLED,
PKGADD_CONFIG_LINE_TOO_LONG,
PKGADD_CONFIG_WRONG_NUMBER_ARGUMENTS,
PKGADD_CONFIG_UNKNOWN_ACTION,
PKGADD_CONFIG_UNKNOWN_EVENT,
CANNOT_COMPILE_REGULAR_EXPRESSION,
CANNOT_GENERATE_LEVEL,
NOT_INSTALL_PACKAGE_NEITHER_PACKAGE_FILE
};

class RunTimeErrorWithErrno : public std::runtime_error
{
	public:
		explicit RunTimeErrorWithErrno(const std::string& msg) throw();
		explicit RunTimeErrorWithErrno(const std::string& msg, int e) throw();
};


#include <string.h>

#define uint8  unsigned char
#define uint32 unsigned long int

struct md5_context
{
    uint32 total[2];
    uint32 state[4];
    uint8 buffer[64];
};

void md5_starts( struct md5_context *ctx );
void md5_update( struct md5_context *ctx, uint8 *input, uint32 length );
void md5_finish( struct md5_context *ctx, uint8 digest[16] );




#include <fstream>
#include <map>
#include <set>
#include <vector>

#include <sys/stat.h>

#define GIGA 1e9
#define MEGA 1e6
#define KILO 1e3
#define PACKAGE_LOCALE_DIR "/usr/share/locale"
#define GETTEXT_PACKAGE "cards"

typedef std::map<std::string, std::string> alias_t;

void *Malloc(size_t s);

struct keyValue 
{
	std::string parameter;
	std::string value;
};

/**
 itemList is a list of char* dynamically allocated
 */
typedef struct
{
	char **items;
	unsigned int count;
} itemList;

/**
  initItemList: Create an item List
*/
itemList *initItemList(void);

/**
 addItemToItemList: Add an item to an already created itemList
*/
void addItemToItemList(itemList *list, const char *item);

/**
freeItemList: Destroy the itemList created and free the allocated memory
*/
 
void freeItemList(itemList *list);

/**
 splitKeyValue: Split a string value into a keyValue structure
*/
keyValue splitKeyValue
(std::string s, char delimiter);

std::set<std::string> getKeysList
(std::string file, std::string delimiter);

std::string getValueOfKey
(std::string file, std::string delimiter,std::string parameter);

std::string getValue(const std::string& s, char delimiter);
std::string getValueBefore( const std::string& s, char del );
std::string getValueBeforeLast( const std::string& s, char del );

std::string itos(unsigned int value);
std::string ultos(unsigned long int value);

std::string mtos(mode_t mode);
std::string trimFileName(const std::string& filename);
std::string sizeHumanRead(int value);

/*param s the string to be searched, param delimiter the delimiter char 
return the value after the first occurance of a delimiter */
std::string getFirstValueOfKeyAfterDelim(const std::string& s, char delimiter);

/* strip whitespace in the beginning and end of string, return a stripped string */
std::string stripWhiteSpace(const std::string& s);

/* populate a vector of string with delimited characters */
std::vector<std::string> parseDelimitedVectorList
(const std::string& s, const char *delimiter);

/* populate a set of string with delimited characters */
std::set<std::string> parseDelimitedSetList
(const std::string& s, const char *delimiter);

/* make sure s1 starts with s2 */
bool startsWith(const std::string& s, const std::string& with);

/**
 startsWithNoCase
 make sure s1 starts with s2
*/
bool startsWithNoCase(const std::string& s1, const std::string& s2);

std::string convertToLowerCase(const std::string& s);
std::string convertToUpperCase(const std::string& s);

std::string replaceAll
( std::string& in, const std::string& oldString, const std::string& newString );

/**
  Split a string into parts
	param s string to be split
	param del delimter
	param startPos position to start at
	param useEmpty include empty (whitespace only9 results in the result

	return a list of string 
*/
template <class T>
void split( const std::string& s, char del,
            T& target,
            int startPos, bool useEmpty )
{
	std::string line = s;
	std::string ss;
	std::string::size_type pos;
	int offset = startPos;
	while ( ( pos = line.find( del, offset ) ) != std::string::npos ) {
		offset = 0;
		if ( line[pos-1] == '\\'  ) {
			line.erase(pos-1,1);
			ss = ss + line.substr(0,pos);
			line.erase(0,pos);
			continue;
		}
		std::string val = line.substr( 0, pos );
		if ( ( useEmpty || !stripWhiteSpace( val ).empty() ) ||
			( ss.length() > 0 ) ) {
			target.push_back( ss + val );
		}
		line.erase( 0, pos+1 );
	}

	if ( ( line.length() > 0 ) || ( ss.length() > 0 ) ) {
		target.push_back( ss + line );
	}
}




#include <utime.h>
#include <dirent.h>
#include <sys/param.h>
#include <sys/file.h>
#include <unistd.h>
#include <libgen.h>
#include <err.h>

#define S_CARDS_MODE  0755

#define WS_NONE         0
#define WS_RECURSIVE    (1 << 0)
#define WS_DEFAULT      WS_RECURSIVE
#define WS_FOLLOWLINK   (1 << 1)        /* follow symlinks */
#define WS_DOTFILES     (1 << 2)        /* per unix convention, .file is hidden */
#define WS_MATCHDIRS    (1 << 3)        /* if pattern is used on dir names too */

enum {
        WALK_OK = 0,
        WALK_BADPATTERN,
        WALK_NAMETOOLONG,
        WALK_BADIO
};

struct InfoFile
{
	std::string url;
	std::string filename;
	std::string dirname;
	std::string md5sum;
	long int filetime;
	utimbuf acmodtime;
	FILE *stream;
};

struct DirUrl {
	std::string Dir;
	std::string Url;
};

struct Config {
	Config() {}
	std::string hostname;
	std::string database;
	std::string username;
	std::string password;
	std::string socket;
	std::string collection;
	std::string name;
	std::string version;
	std::string arch;
	std::string url;
	std::string logdir;
	std::vector<std::string> group;
	std::vector<DirUrl> dirUrl;
	std::vector<std::string> baseDir;
	std::vector<std::string> archs;
};

int getConfig(const char *fileName, Config& config);
void * getDatas ( void * var, FILE * file, long offset, size_t size, size_t nmemb);
std::string trimFileName(const std::string& filename);
time_t getEpochModifyTimeFile(const std::string& filename);
std::string getDateFromEpoch(const time_t& epoch);
std::string getModifyTimeFile(const std::string& filename);
bool checkFileExist(const std::string& filename);
bool checkFileEmpty(const std::string& filename);
bool checkRegularFile(const std::string& filename);
bool checkFileSignature(const std::string& filename, const std::string& signature);
bool checkFilesEqual(const std::string& file1, const std::string& file2);
bool checkPermissionsEqual(const std::string& file1, const std::string& file2);
bool createRecursiveDirs(const std::string& pathname);
void cleanupMetaFiles(const std::string& basedir);
void removeFile(const std::string& basedir, const std::string& filename);
int copyFile(const char *  destFile, const char *  origFile);
int findFile(std::set<std::string>& filesList, const std::string& basedir);
int findDir(itemList *filenameList, const char *path);
int findRecursiveFile(std::set<std::string>& filenameList, const char *filename, int spec);
int readFileStripSpace(itemList *fileContent, const char *fileName);
int readFile(itemList *fileContent, const char *fileName);
int parseFile(std::set<std::string>& fileContent, const char* fileName);
int parseFile(std::vector<std::string>& fileContent, const char* fileName);
int parseFile(std::string& Depends, const char* key, const char* fileName);
bool findMD5sum(const std::string& fileName, unsigned char* result);
bool checkMD5sum(const char * fileName, const char * MD5Sum);
/* read a file
   return it into a template container */
template <class T>
int parseFile( T& target, const char* fileName)
{
	FILE *fp = fopen (fileName, "r");
	if (!fp)
		return -1;
	const int length = BUFSIZ;
	char input[length];
	std::string line;
	while (fgets(input, length, fp)) {
		input[strlen(input)-1] = '\0';
		line = input;
		target.push_back(line);
	}
	fclose(fp);
	return 0;
}





#include <archive.h>
#include <archive_entry.h>


#if ARCHIVE_VERSION_NUMBER >= 3000000
#define INIT_ARCHIVE(ar) \
	archive_read_support_filter_gzip((ar)); \
	archive_read_support_filter_bzip2((ar)); \
	archive_read_support_filter_xz((ar)); \
	archive_read_support_filter_zstd((ar)); \
	archive_read_support_format_tar((ar))
#define FREE_ARCHIVE(ar) \
	archive_read_free((ar))
#else
#define INIT_ARCHIVE(ar) \
	archive_read_support_compression_gzip((ar)); \
	archive_read_support_compression_bzip2((ar)); \
	archive_read_support_compression_xz((ar)); \
	archive_read_support_format_tar((ar))
#define FREE_ARCHIVE(ar) \
	archive_read_finish((ar))
#endif

#define DEFAULT_BYTES_PER_BLOCK (20 * 512)
#define METAFILE ".META"
#define INFOFILE ".INFO"
#define MTREEFILE ".MTREE"

enum archive_error
{
CANNOT_OPEN_ARCHIVE,
CANNOT_READ_ARCHIVE,
CANNOT_FIND_META_FILE,
CANNOT_FIND_MTREE_FILE,
CANNOT_FIND_NAME,
CANNOT_FIND_ARCH,
EMPTY_ARCHIVE
};


class ArchiveUtils
{
	public:


	ArchiveUtils(const std::string& fileName);
	virtual ~ArchiveUtils();

	virtual void treatErrors(const std::string& s) const;

	void printDeps();        // Print Out the dependencies
	void printMeta();        // Print Out the .META file
	void printInfo();        // the .INFO file
	void list();             // list the files to stdio
	

	unsigned int long size();              	// Numbers of files in the archive
	std::set<std::string> setofFiles(); 		// return a order set of string
	std::set<std::string> listofDependencies(); // return an order set of dependencies
	std::set<std::string> listofAlias(); // return the alias list
	std::set<std::pair<std::string,time_t> > listofDependenciesBuildDate(); // return an order set of dependencies,BuildDate
	std::string arch();       // return the arch of the package
	std::string version();    // return the version of the package
	int  release();		// return the release of the package
	std::string description();// return the description	of the package
	std::string url();        // return the url of the package
	std::string contributors(); // return the Contributor(s) of the package
	std::string maintainer(); // return the Maintainer(s) of the package
	std::string collection(); // return the collection of the package
	std::string packager();   // return the Packager(s) of the package
	std::string builddate();  // return the date like Mon Mar 24 10:16:00 2014
	std::string name();				// return the name of the package
	std::string group();  // return the group of the package
	std::string namebuildn();	// return the name + epochvalue
	std::string epochBuildDate();		// return the epochvalue in string format
	time_t buildn();    // return the epoch value

	private:
	
	std::string getPackageName();
	std::string getPackageArch();
	std::vector<std::string>  extractFileContent(const char * fileName);
	void getRunTimeDependencies();
	void getRunTimeDependenciesEpoch();
	void getAliasList();

	unsigned int long m_size;

	std::vector<std::string> m_contentMtree;
	std::vector<std::string> m_contentMeta;
	std::vector<std::string> m_contentInfo;

	std::set<std::string> m_rtDependenciesList;
	std::set<std::pair<std::string,time_t> > m_rtDependenciesEpochList;
	std::string m_fileName;
	std::string m_packageName;
	std::string m_packageArch;
	std::set<std::string> m_filesList;
	std::set<std::string> m_aliasList;

	archive_error m_actualError;
};

int openArchive(const char *fileName);

/*
 * pkg.h
 *
 * Copyright 2017 - 2022 NuTyX <tnut@nutyx.org>
 *
 * 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; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 *
 */

#define  PKG_H


enum CPSTATUS
{
	INSTALLED = 0x01,
	TO_INSTALL = 0x02,
	TO_REMOVE = 0x04,
	TO_UPGRADE = 0x08
};

class Pkg
{
public:
	Pkg();
	~Pkg();
	std::string getName();
	std::string getVersion();
	std::string getPackager();
	std::string getDescription();
	std::string getCollection();
	std::vector<std::string> getSet();
	std::string getPrimarySet();
	void setName(std::string& name);
	void setDescription(std::string& description);
	void setVersion(std::string& version);
	void setCollection(std::string& collection);
	void setSet(std::string& set);
	void setPackager(std::string& packager);
	bool isInstalled();
	bool isToBeInstalled();
	bool isToBeRemoved();
	void setStatus(CPSTATUS pstatus);
	void unSetStatus(CPSTATUS pstatus);
	CPSTATUS getStatus();

private:
	std::string m_collection;
	std::string m_set;
	std::vector<std::string> m_setList;
	std::string m_name;
	std::string m_version;
	std::string m_packager;
	std::string m_description;
	CPSTATUS m_status;
};




struct PortFilesList {
	std::string md5SUM;
	std::string name;
	std::string arch;
};

/**
 * representation of the .PKGREPO file which belong to the collection directory
 * define in the configuration file cards.conf.
 *
 */

/*
 **************************************************
 * 73193bfc1cb30fe02a880ed088ed7590#1414192958#aalib#1.4rc5##n.a#n.a#n.a#n.a#.cards.tar.xz
 * 650ed499ce78791d45b91aaf7f91b445#1428615787#firefox#37.0.1#1#Standalone web browser from mozilla.org#http://www.mozilla.com/firefox/#n.a#pierre at nutyx dot org,tnut at nutyx dot org#.cards.tar.xz
 *************************************************
 */
struct BasePackageInfo {
	std::string md5SUM;
	std::string s_buildDate;
	std::string basePackageName;
	std::string extention;
	std::string version;
	int release;
	std::string description;
	std::string categories;
	std::string URL;
	std::string contributors;
	std::string maintainer;
	std::string packager;
	std::string fileDate;
	std::string alias;
	std::string set;
	std::string group;
	time_t buildDate;
	alias_t aliasList;
	std::vector<PortFilesList> portFilesList;
};

struct PortsDirectory {
	std::string Dir;
	std::string Url;
	std::vector<BasePackageInfo> basePackageList;
};
/**
 * representation of the Repo mainly for the website
**/
struct RepoInfo {
	std::string branch;
	std::string arch;
	std::string collection;
	std::vector<BasePackageInfo> basePackageList;
};

class Pkgrepo
{
public:

		Pkgrepo(const std::string& fileName);
		virtual ~Pkgrepo() { clearPackagesList(); }

		static int parseConfig(const char *fileName,
			Config& config);

		void throwError(const std::string& s) const;

/**
 *
 *  return a list of ports which has to be compiled OR
 *  has to be updated
 *
 * Depends on: parsePkgRepoCollectionFile
 *
 * Populate: nothing
 *
 */
		std::set<std::string> getListOutOfDate();

/**
 *	return the folder of the port name
 *
 */
		std::string getPortDir (const std::string& portName);


/**
 *
 * 	return the basename of the portname
 *
 */
		std::string getBasePortName (const std::string& portName);
/**
 *      return the basename of the packagename
 *
 */
		std::string getBasePackageName(const std::string& packageName);
/**
 *
 *	return the version of the packagename
 */

		std::string getBasePackageVersion(const std::string& packageName);
/**
 *  return the version of the port name
 */
		std::string getPortVersion (const std::string& portName);

/**
 *  return the release of the packagename
 *
 */
		int getBasePackageRelease (const std::string& packageName);

/**
 *  return the release of the port name
 */
		int getPortRelease(const std::string& portName);
/**
 *  return true if port name exist
 */ 
		bool checkPortExist(const std::string& portName);

/**
 *  retun list of packages of the collection
 */
		std::set<std::string> getListOfPackagesFromCollection(const std::string& collectionName);

/**
 *  retun list of packages of a set
 */
		std::set<std::string> getListOfPackagesFromSet(const std::string& collectionName);

/**
 *	return the build time of the binary 
 */
		time_t getBinaryBuildTime (const std::string& portName);

/**
 *  return the list of available binaries packages
 *
 */
		std::set<std::string> getBinaryPackageList();

/**
 *  return a Pkg set List of available binaries packages
 *
 */
		std::set<Pkg*> getBinaryPackageSet();
/**
 * populate RepoInfo List
 *
 */
		std::vector<RepoInfo> getRepoInfo();
/**
 * printout the list of available ports which are compiled
 *  return a list of name version
 *
 */
    unsigned int getPortsList();

		bool getBinaryPackageInfo(const std::string& packageName);
		bool getPortInfo(const std::string& portName);

protected:
/**
 *
 * parse the config file
 **/
    int parseConfig(const char *fileName);

/**
 * parse the .PKGREPO file which belong to the collection found
 * in the configuration file cards.conf. It populate the
 * the m_packageList.basePackageName part by looking
 * the downloaded .PKGREPO file of each activate collection
 *
 * Depends on: m_config.dirUrl
 *
 * populate: m_portsDirectoryList (Dir, Url, BasePackageInfo for each possible port found in Dir)
 * with the contents of the collection .PKGREPO file
 *
 **/
    void parsePkgRepoCollectionFile();

/**
 * parse the directory directly based on what we have locally.
 * This method is used in the case of synchronisation with the mirror
 * is NOT possible. If they are no directories, they will be nothing add
 *
 * Depends on: m_config.dirUrl
 *
 * populate:  m_portsDirectoryList  ( Dir, BasePackageInfo->basePackageName only )
 *
 **/
    void parseCollectionDirectory();

/**
 * parse the ".PKGREPO" file of a port directory
 * if it found a first line with the date of construction
 * and the extension of the archive then it populate
 * the list of packages
 *
 * Depends on: parsePkgRepoCollectionFile
 *
 * Populate: m_portFilesList (md5SUM.name,arch)
 *
 */
    void parseCurrentPackagePkgRepoFile();

/**
 * parse the "Pkgfile" file for each basePackage
 * add the version of the port found in the Pkgfile
 *
 */
    void parsePackagePkgfileFile();


		bool m_parsePkgRepoCollectionFile;
		bool m_parseCollectionDirectory;
		bool m_parsePackagePkgfileFile;

		std::vector<PortsDirectory>::iterator m_PortsDirectory_i;
		std::vector<BasePackageInfo>::iterator m_BasePackageInfo_i;
		std::vector<PortFilesList>::iterator m_PortFilesList_i;

		std::vector<PortFilesList> m_portFilesList;

		std::string m_configFileName;
		Config m_config;

		std::vector<PortsDirectory> m_portsDirectoryList;
private:
		error m_ErrorCond;
		void clearPackagesList();
		std::set<Pkg*> m_packagesList;
};
#define REPODWL_H


class Repodwl: public Pkgrepo {
public:
	Repodwl(const char *fileName);
/**
 * download the .PKGREPO of packageName
 *
 * Depends on: parsePkgRepoCollectionFile
 *
 * populate: nothing
 *
 * add: the .PKGREPO of the packageName port from the mirror
 *
 */
	void downloadPortsPkgRepo(const std::string& packageName);

/**
 * download the packagefileName
 *
 * Depends on: parsePkgRepoCollectionFile
 *
 * populater: nothing
 *
 * add: The packageFileName from the mirror
 *
 */
	void downloadPackageFileName(const std::string& packageName);
	bool checkBinaryExist(const std::string& packageName);
	std::string getPackageFileName(const std::string& packageName);
	std::string getPackageFileNameSignature(const std::string& packageName);

	void setPackageFileName(const std::string& packageFileName);

private:
	std::string m_packageFileName;
	std::string m_packageFileNameSignature;
};

/**
 * FileDownload class.
 */



#include <curl/curl.h>



/**
 * \brief File Download State class
 *
 * This class provide container to provide progress update datas
 * to client who suscribe to the progress event
 *
 */

class FileDownloadState
{
	public:
	double dlnow;
	double dltotal;
	double dlspeed;
	std::string filename;
};

class FileDownload;

/**
 * \brief File Download Event class
 *
 * This abstract class provide inherit definition for a callback
 * suscriber to be callable by FileDownload Progress Update
 *
 */

class FileDownloadEvent
{
	friend FileDownload;
public:
	FileDownloadEvent();
	~FileDownloadEvent();

	protected:

	/**
	 * Callback called when new progress data are available
	 *
	 * \param state Class container datas for current download
	 */
	virtual void OnFileDownloadProgressInfo(FileDownloadState state){};
};

/**
 * \brief File Download class
 *
 * This class takes care of the download process of the binaries and
 * other important files
 *
 */

class FileDownload
{
	public:

	/**
	 * Download a file without the need to check the signature of the file
	 *
	 * \param url Complete downloading address including the file
	 * \param dirName Destination folder
	 * \param fileName file where to store the downloaded datas
	 * \param progress If true, show what's going on
	 */
	FileDownload(std::string url, std::string dirName, std::string fileName, bool progress);

	/**
	 * Download a file with the possibility of checking the signature of the file
	 *
	 * \param fileInfo Destination file
	 * \param url Complete downloading address including the file
	 * \param dirName Destination folder
	 * \param fileName file where to store the downloaded datas
	 * \param MD5Sum Signature to use for checking the download file
	 * \param progress If true, show what's going on
	 */
	FileDownload(std::string fileInfo, std::string url, std::string dirName, std::string fileName, std::string MD5Sum , bool progress);

	/**
	 * Download a list of InfoFile (a vector of InfoFile type)
	 * InfoFile consist of (amount other fields.. ) Name of the file and the signature of the file to download
	 *
	 * \param destinationFiles List of files to download
	 * \param progress If true, show what's going on
	 */
	FileDownload(std::vector<InfoFile> destinationFiles,bool progress);

	/**
	 * Destructor need to cleanup all the created pointers for the internal cook
	 */
	~FileDownload()
	{
		curl_slist_free_all(m_slist);
		curl_global_cleanup();
		curl_easy_cleanup(m_curl);
	}

	static void SuscribeToEvents(FileDownloadEvent* callback);
	static void UnSuscribeFromEvents(FileDownloadEvent* callback);


	private:

	/**
	 * \return check if signature is OK
	 */
	bool checkMD5sum();

	/**
	 * download effectively the request file
	 */
	void downloadFile();

	static int updateProgressHandle(void *p, double dltotal, double dlnow, double ultotal, double ulnow);
	static size_t writeToStreamHandle(void *buffer, size_t size, size_t nmemb, void *stream);
	int updateProgress(void *p, double dltotal, double dlnow, double ultotal, double ulnow);
	size_t writeToStream(void *buffer, size_t size, size_t nmemb, void *stream);
	void initFileToDownload(std::string _url, std::string _file);

	/**
	 * \return true if package is uptodate else false
	 */
	bool checkUpToDate();
	void SendProgressEvent(FileDownloadState event);
	struct dwlProgress
	{
		std::string name;
		double lastruntime;
		CURL *curl;
	};
	struct curl_slist *m_slist;

	CURL*		m_curl;
	CURLcode	m_curlCode;
	dwlProgress	m_downloadProgress;
	InfoFile	m_destinationFile;
	std::string	m_url;
	std::string	m_downloadFileName;
	std::string	m_fileInfo;
	bool		m_checkMD5;
	bool		m_progress;
	std::string	m_MD5Sum;
	static std::set<FileDownloadEvent*> m_arrCallBacks;
};




#include <list>
#include <cassert>
#include <cstddef>
#include <cstdlib>
#include <cstdio>

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>

  
/**
  * To execute a process
	* Arguments:
	* 1. Application to run
	* 2. Arguments to pass to the application
	* 3. File descriptor of the log file
*/

class process
{
public:
	process();
	process( const std::string& app, const std::string& args, int fileDescriptorLog=0 );

	void execute(const std::string& app, const std::string& arguments, int fileDescriptorLog=0  );

	/**
		* execute the process
		* return the exit status of the application
		*/
	int execute();

	/**
		*  execute the process using the shell
		*  return the exit status of the application
		*/
	int executeShell();

	/**
		*  return the name of the application
		*/
	std::string name();

	/**
		*  return the arguments of the application
		*/
	std::string args();

private:

	int exec(const int argc, char** argv);
	int execLog(const int argc, char** argv);

	int execShell(const char* shell);
	int execShellLog(const char* shell);

	std::string m_application;
	std::string m_arguments;
	int m_fileDescriptorLog;
};




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>


int getRuntimeLibrariesList (std::set<std::string>& runtimeLibrariesList, const std::string& filename);


/**
 * Pkgdbh class.
 */



#include <stdexcept>
#include <csignal>
#include <algorithm>

#include <regex.h>
#include <ext/stdio_filebuf.h>
#include <pwd.h>
#include <grp.h>



#define LDCONFIG         "sbin/ldconfig"
#define LDCONFIG_CONF    "etc/ld.so.conf"
#define LDCONFIG_CONF_ARGS "-r "
#define SHELL            "bin/sh"

#define INSTALL_INFO      "usr/bin/install-info"
#define INSTALL_INFO_ARGS "--info-dir=usr/share/info "

#define UPDATE_ICON       "usr/bin/gtk-update-icon-cache"
#define UPDATE_ICON_ARGS  "-f -t "

#define COMPILE_SCHEMAS       "usr/bin/glib-compile-schemas"
#define COMPILE_SCHEMAS_ARGS  ""

#define UPDATE_DESKTOP_DB      "usr/bin/update-desktop-database"
#define UPDATE_DESKTOP_DB_ARGS "-q "

#define UPDATE_MIME_DB  "usr/bin/update-mime-database"
#define UPDATE_MIME_DB_ARGS  "-n "

#define GDK_PIXBUF_QUERY_LOADER "usr/bin/gdk-pixbuf-query-loaders"
#define GDK_PIXBUF_QUERY_LOADER_ARGS "--update-cache"

#define GIO_QUERYMODULES "usr/bin/gio-querymodules"
#define GIO_QUERYMODULES_ARGS "usr/lib/gio/modules"

#define QUERY_IMMODULES_3 "usr/bin/gtk-query-immodules-3.0"
#define QUERY_IMMODULES_3_ARGS "--update-cache"

#define QUERY_IMMODULES_2 "usr/bin/gtk-query-immodules-2.0"
#define QUERY_IMMODULES_2_ARGS "--update-cache"

#define MKFONTDIR       "usr/bin/mkfontdir"
#define MKFONTDIR_ARGS  ""

#define MKFONTSCALE     "usr/bin/mkfontscale"
#define MKFONTSCALE_ARGS  ""

#define FC_CACHE     "usr/bin/fc-cache"
#define FC_CACHE_ARGS  ""

enum action
{
PKG_DOWNLOAD_START,
PKG_DOWNLOAD_RUN,
PKG_DOWNLOAD_END,
DB_OPEN_START,
DB_OPEN_RUN,
DB_OPEN_END,
PKG_PREINSTALL_START,
PKG_PREINSTALL_END,
PKG_INSTALL_START,
PKG_INSTALL_END,
PKG_INSTALL_RUN,
PKG_POSTINSTALL_START,
PKG_POSTINSTALL_END,
PKG_MOVE_META_START,
PKG_MOVE_META_END,
DB_ADD_PKG_START,
DB_ADD_PKG_END,
LDCONFIG_START,
LDCONFIG_END,
RM_PKG_FILES_START,
RM_PKG_FILES_RUN,
RM_PKG_FILES_END
};

struct pkginfo_t {
	std::string group;
	std::string collection;
	std::string description;
	std::string signature;
	time_t build; // date of build
	std::string version;
	int release;
	std::string url;
	std::string contributors;
	std::string packager;
	std::string maintainer;
	time_t install; // date of last installation
	std::string arch;
	int size;
	bool dependency; // true it's a dependency: automaticaly install
	std::set< std::pair<std::string,time_t> > dependencies;
	std::set<std::string> alias;
	std::set<std::string> set;
	std::set<std::string> categories;
	std::set<std::string> files;
};
typedef std::map<std::string, pkginfo_t> packages_t;

enum rule_event_t {
	LDCONF,
	UPGRADE,
	INSTALL,
	INFO,
	ICONS,
	FONTS,
	SCHEMAS,
	DESKTOP_DB,
	MIME_DB,
	QUERY_PIXBUF,
	GIO_QUERY,
	QUERY_IMOD3,
	QUERY_IMOD2
};

struct rule_t {
	rule_event_t event;
	std::string pattern;
	bool action;
};

class Pkgdbh {
public:

	explicit Pkgdbh(const std::string& name);
	virtual ~Pkgdbh();

	/* Following methods can be redefined in derivated class */
	virtual void parseArguments(int argc, char** argv);
	virtual void run(int argc, char** argv) {};
	virtual void run() {};

	virtual void printHelp() const {};

	virtual void progressInfo();
	virtual void treatErrors(const std::string& s) const;


	void print_version() const;
	std::set<std::string> getListOfPackageName();

	bool checkPackageNameExist(const std::string& name) const;
	bool checkDependency(const std::string& name);
	void setDependency();
	void resetDependency();

	unsigned int getFilesNumber();
	unsigned int getInstalledFilesNumber();
	std::set<std::string> getFilesList();

protected:
	// Database

	std::set<std::string> getFilesOfPackage(const std::string& packageName);
	int getListOfPackageNames(const std::string& path);
	std::pair<std::string, pkginfo_t> getInfosPackage(const std::string& packageName);
	void buildSimpleDatabase();
	void buildSimpleDependenciesDatabase();

	void buildCompleteDatabase(const bool& silent);
	void buildDatabase(const bool& progress,
	const bool& simple,
	const bool& all,
	const bool& files,
	const std::string& packageName);


	void addPackageFilesRefsToDB(const std::string& name,
		const pkginfo_t& info);

	bool checkPackageNameUptodate(const std::pair<std::string,
		pkginfo_t>& archiveName);
	bool checkPackageNameBuildDateSame(const std::pair<std::string,
		time_t>& dependencieNameBuild);

	/*
	 * Remove the physical files after followings some rules
	 */
	void removePackageFiles(const std::string& name);
	void removePackageFiles(const std::string& name,
		const std::set<std::string>& keep_list);

	/*
	 * Remove meta data about the removed package
	 */
	void removePackageFilesRefsFromDB(const std::string& name);
	void removePackageFilesRefsFromDB(std::set<std::string> files,
		const std::set<std::string>& keep_list);
	std::set<std::string> getConflictsFilesList(const std::string& name,
		const pkginfo_t& info);

	// Tar.gz
	std::pair<std::string, pkginfo_t> openArchivePackage(const std::string& filename);
	std::set< std::pair<std::string, time_t> > getPackageDependencies(const std::string& filename);
	void extractAndRunPREfromPackage(const std::string& filename);
	void installArchivePackage(const std::string& filename,
	const std::set<std::string>& keep_list,
	const std::set<std::string>& non_install_files);

	/*
	 * The folder holding the meta datas is going to be create here
	 */
	void moveMetaFilesPackage(const std::string& name, pkginfo_t& info);


	void readRulesFile();
	void getInstallRulesList(const std::vector<rule_t>& rules,
		rule_event_t event, std::vector<rule_t>& found) const;
	bool checkRuleAppliesToFile(const rule_t& rule,
		const std::string& file);

	void getFootprintPackage(std::string& filename);

	std::string m_packageArchiveName;
	std::string m_packageName;
	std::string m_packageArchiveVersion;
	std::string m_packageArchiveRelease;
	std::string m_packageArchiveCollection;
	std::string m_packageVersion;
	std::string m_packageRelease;
	std::string m_packageCollection;
	std::string m_utilName;
	std::string m_root;
	std::string m_build;
	std::vector<rule_t> m_actionRules;
	std::set< std::pair<std::string, int> > m_postInstallList;
	alias_t	m_listOfAlias;

	packages_t m_listOfInstPackages;
	packages_t m_listOfDepotPackages;

	std::set<std::pair<std::string,std::set<std::string> > > m_listOfInstalledPackagesWithDeps;

	action m_actualAction;
	error m_actualError;

private:

	void runLastPostInstall();

	std::set<std::string> m_runtimeLibrariesList;
	std::set<std::string> m_filesList;
	std::set<std::string> m_packageNamesList;
	unsigned int m_filesNumber;
	unsigned int m_installedFilesNumber;

	bool m_dependency;

	bool m_DB_Empty;
	bool m_miniDB_Empty;
};

class Db_lock {
public:
	Db_lock(const std::string& m_root, bool exclusive);
	~Db_lock();

private:
	DIR* m_dir;
	struct sigaction m_sa;
};

void assertArgument(char** argv, int argc, int index);
void rotatingCursor();

/**
 * Pkgadd class.
 */



/**
 * \brief Pkgadd class
 *
 * This class takes care of adding binaries package into the database
 *
 */

class Pkgadd : public Pkgdbh {
public:
	/**
	 * Default constructor without any argument
	 */
	Pkgadd();
	/**
	 * Alternative constructor for derivated classes
	 * 
	 * \param commandName Name of the command used in derivated class
	 */
	Pkgadd(const std::string& commandName);
	void parseArguments(int argc, char** argv);
	void preRun();
	void postRun();
	virtual void run();
	virtual void run(int argc, char** argv);
	virtual void printHelp() const;

protected:
	bool m_runPrePost;
	bool m_upgrade;
	bool m_force;
private:
	std::set<std::string> getKeepFileList(const std::set<std::string>& files,
		const std::vector<rule_t>& rules);
	std::set<std::string> applyInstallRules(const std::string& name,
		pkginfo_t& info,
		const std::vector<rule_t>& rules);
	void applyPostInstallRules(const std::string& name,
		pkginfo_t& info,
		const std::vector<rule_t>& rules);
	void getInstallRulesList(const std::vector<rule_t>& rules,
		rule_event_t event,
		std::vector<rule_t>& found) const;
	void getPostInstallRulesList(const std::vector<rule_t>& rules,
		std::vector<rule_t>& found) const;
};

/**
 * Pkgrm class.
 */



class Pkgrm : public Pkgdbh {
public:
	Pkgrm(const std::string& commandName) : Pkgdbh(commandName) {}
	Pkgrm();
	void run();
	void run(int argc, char** argv);
	void printHelp() const;

protected:
	void getListOfManInstalledPackages ();
	std::set<std::string> m_listOfManInstalledPackages;
	std::set<std::string> m_listofDependencies;
private:
	void getDirectDependencies(std::string& name);

};


/**
 * Pkginfo class.
 */



#include <sstream>
#include <iomanip>


class Pkginfo : public Pkgdbh {
public:
	Pkginfo(const std::string& commandName);
	Pkginfo();
	virtual void run(int argc, char** argv);
	virtual void parseArguments(int argc, char** argv);
	virtual void run();
	virtual void finish();
	virtual void printHelp() const;

protected:
	std::string m_arg;
	int m_runtimedependencies_mode;
	int m_footprint_mode;
	int m_archiveinfo;
	int m_installed_mode;
	int m_list_mode;
	int m_owner_mode;
	int m_details_mode;
	int m_libraries_mode;
	int m_runtime_mode;
	int m_epoc;
	bool m_fulllist_mode;

};





class Pkginst : public Pkgadd, public Repodwl {
public:
	Pkginst(const std::string& commandName, const char *configFileName);
	void generateDependencies(const std::pair<std::string,time_t>& packageName);
	void generateDependencies();

protected:
	std::vector< std::pair<std::string,time_t> > m_dependenciesList;
};


#include <cstring>
#include <cstdlib>
#include <iostream>


#include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libgen.h>
#include <dirent.h>

class Pkgsync
{
public:
		/**
		 * Default constructor
		 * 
		 */
		Pkgsync();
		Pkgsync(const std::string& url,
			const std::string& directory,
			const std::string& repoFile);

		virtual void treatErrors(const std::string& s) const;

		virtual void run();
		virtual void purge();
		static const std::string DEFAULT_REPOFILE;

		void setRootPath(const std::string& path);
		void setConfigFile(const std::string& file);

private:

	unsigned int getLocalPackages(const std::string& path);
	unsigned int getRemotePackages(const std::string& pkgrepoFile);

	void deleteFolder(const std::string& folderName);

	std::set<std::string> m_localPackagesList;
	std::set<std::string> m_remotePackagesList;
	const std::string m_baseDirectory;
	const std::string m_remoteUrl;
	std::string m_repoFile;
	std::string m_root;
  std::string m_configFile;
	error m_actualError;

	
};

#endif
// vim:set ts=2 :
