 /* 
 *  apt-fsearch - My fast replacement for apt-list (perl)
 *  Copyright © 2000 JCB <jcb@chez.com>
 *
 *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


/* TODO : use regex */

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

#define VERSION "0.1"
#define LISTDIR "/var/state/apt/lists"
#define FPATTERN "_Packages"
#define SPATTERN "Package: "
#define BUFSIZE 512


void search_package(char *pattern)
{
	DIR *dir;
	FILE *file;
	struct dirent *dt;
	struct stat st;
	char buf[BUFSIZE];
	char *s;

	chdir(LISTDIR);
	dir = opendir(".");
	while ((dt = readdir(dir))) {
		stat(dt->d_name, &st);
		if (!S_ISREG(st.st_mode))
			continue;
		if (!strstr(dt->d_name, FPATTERN))
			continue;

		file = fopen(dt->d_name, "r");
		while (fgets(buf, BUFSIZE - 1, file)) {
			if (strstr(buf, SPATTERN)) {
				s = buf;
				while (*s != ' ')
					s++;
				if (strstr(s, pattern))
					printf(s);
			}
		}
		fclose(file);
	}

	closedir(dir);
}



void desc_package(char *package)
{
	DIR *dir;
	FILE *file;
	struct dirent *dt;
	struct stat st;
	char buf[BUFSIZE];
	char *pattern;
	
	/* prepare pattern to search */
	pattern = (char*)malloc(sizeof(char)*(strlen(SPATTERN)+strlen(package)+1));
	sprintf(pattern, "%s%s", SPATTERN, package);
	
	chdir(LISTDIR);
	dir = opendir(".");
	while ((dt = readdir(dir))) {
		stat(dt->d_name, &st);
		if (!S_ISREG(st.st_mode))
			continue;
		if (!strstr(dt->d_name, FPATTERN))
			continue;

		file = fopen(dt->d_name, "r");
		while (fgets(buf, BUFSIZE - 1, file)) {
			if (strstr(buf, pattern)) {		
				printf("%s", buf);
				break;
			}
		}
		while (fgets(buf, BUFSIZE - 1, file)) {
			if (*buf == '\n') {
				fclose(file);
				goto end_goto;
			}
			printf("%s", buf);
		}
		fclose(file);
	}

	end_goto:
	
	free(pattern);
	closedir(dir);
}




int main(int argc, char *argv[])
{
        int c;
        int tmp;
        extern int optind;
        extern char *optarg;
        extern int opterr;
        
        static struct option long_options[] = 
        {
                {"search", 1, 0, 's'},
                {"desc", 1, 0, 'd'},
                {"help", 0, 0, 'h'},
                {"version", 0, 0, 'v'},
                {0, 0, 0, 0}
        };
        static char help[] =    
		"apt-fsearch options :\n"
		"\t--search    -s    search a package\n"
		"\t--desc      -d    show description for a package\n"
		"\t--help      -h    show this message\n"
		"\t--version   -v    show version\n";
        
	if (argc < 2 || (argv[1][0] != '-')) {
                printf("%s", help);
                exit(1);
        }

        /* do not complain about err */
        opterr = 0;
        
        while (1) {
                int opt_index = 0;

                c = getopt_long_only(argc, argv, "", long_options, &opt_index);
                
                /* no more options */
                if (c == -1)
                        break;

                switch (c) {
                        case 'h':
                                printf("%s", help);
                                exit(1);
                        case 'v':
                                printf("apt-fsearch version %s\n", VERSION);
                                exit(1);
                        case 'd':
				desc_package(optarg);
                                break;
                        case 's':
				search_package(optarg);
                                break;
                        case '?':
				printf("%s", help);
				exit(1);
                }
        }
	return 0;
}       
