/********************** modified from t2.c *******************/
/********************* kman.c ********************************/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#ifdef SYS_DIR
#include <sys_dir.h>
#else
#ifdef NDIR
#include <ndir.h>
#else
#include <dirent.h>
#endif
#endif
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include "mandata.h"
#include "mandatadef.h"
#include "util.h"
#include "context.h"
#include "gman.h"
#include <stdlib.h>
#include <glib.h>
void attach (char *dest, const char *dirname, const char *name);
static int section_translate_c_to_n(const char* c);
static int ManItemComp(ManItem ** a,ManItem ** b);
static int is_zip_suffix(char* c);
char buffer1[BUFFER_SIZE];
char buffer2[BUFFER_SIZE];
/************************* ManPath ************************/
ManPath::ManPath(char* _path_name)
{
int i;
int len;
active = 1;
path_name = my_strdup(_path_name);
for (i=0;i<MAX_MAN_SECTION;i++) section[i] = new List();
LoadManPath(path_name);
}
ManPath::~ManPath()
{
int i,j,k;
for (i = 0;i<MAX_MAN_SECTION;i++) {
k = section[i]->get_size();
for(j = 0;j<k;j++) delete ((ManItem*)(section[i]->get_item(j)));
delete(section[i]);
}
if(path_name) free(path_name);
}
int ManPath::GetSize(int section_ID)
{
int count;
int i;
for (count = i = 0;i<MAX_MAN_SECTION;i++)
if (1<<i & section_ID) count += section[i]->get_size();
return count;
}
int ManPath::GetItems(int section_ID, ManItem * buffer[])
{
int count;
int i;
for (count = i = 0;i<MAX_MAN_SECTION;i++)
if (1<<i & section_ID) count += section[i]->get_items((void*)(buffer + count));
return count;
}
const char * ManPath::GetPath() {return (const char*) path_name;}
struct stat state;
int ManPath::LoadManPath(char * path_name)
{
DIR *dirp;
#if defined(SYS_DIR)||defined(NDIR)
struct direct *item;
#else
struct dirent *item;
#endif
ManItem * man_item;
int val,i;
// printf("LoadManPath: %s\n",path_name);
dirp = opendir(path_name);
if (!dirp)
{
fprintf(stderr,"Can not open man path %s\n",path_name);
return 1;
}
for (item = readdir(dirp);item != NULL;item = readdir(dirp))
{
if(item->d_name[0] == '.' && (item->d_name[1] == 0 ||(item->d_name[1] == '.'&&item->d_name[2]==0)))
continue;
attach(buffer1,path_name,item->d_name);
//printf("LoadManPath: %s\n",name);
val = stat (buffer1, &state);
if (val < 0) fprintf(stderr,"error number %d, in get state %s",errno,buffer1);
else if (S_ISDIR(state.st_mode) && !strncmp(item->d_name,"man",3)) LoadManSubPath(item->d_name);
else
{
man_item = new ManItem(this,item -> d_name);
val = man_item->get_section_ID();
if(!val) delete(man_item);
else{
for(i = 0;!(1<<i & val);i++);
section[i]->add_item(man_item);
}
//printf("%d\n",n);
}
}
closedir(dirp);
return 0;
}
int ManPath::LoadManSubPath(char * sub_name)
{
DIR *dirp;
#if defined(SYS_DIR)||defined(NDIR)
struct direct *item;
#else
struct dirent *item;
#endif
int val,i;
ManItem * man_item;
attach(buffer2,path_name,sub_name);
//printf("LoadManSubPath: %s\n",buffer2);
dirp = opendir(buffer2);
if (!dirp)
{
fprintf(stderr,"Can not open man path %s\n",buffer2);
}
for (item = readdir(dirp);item != NULL;item = readdir(dirp))
{
if(item->d_name[0] == '.' && (item->d_name[1] == 0 ||(item->d_name[1] == '.'&&item->d_name[2]==0)))
continue;
attach(buffer1,buffer2,item->d_name);
//printf("LoadManSubPath: %s\n",full_name);
val = stat (buffer1, &state);
if (val < 0) fprintf(stderr,"error number %d, in get state %s\n",errno,buffer1);
else if (S_ISDIR(state.st_mode)) continue;
else
{
attach(buffer1,sub_name,item->d_name);
man_item = new ManItem(this,buffer1);
val = man_item->get_section_ID();
if(!val) delete(man_item);
else{
for(i = 0;!(1<<i & val);i++);
section[i]->add_item(man_item);
}
}
}
closedir(dirp);
}
ManItem * ManPath::search_man_item(char * name, char * sect)
{
int i,j,k;
int len;
ManItem * a;
char buffer[100];
len = strlen(name);
if(section) {
j = section_translate_c_to_n(sect);
//printf("point0.1\n");
if(!j) return NULL;
for(i = 0;!(1<<i & j);i++);
//printf("point0.2, section = %x,%d: section[i] = %x\n", j,i,section[i]);
k = section[i]->get_size();
//printf("point0.25, k = %d\n",k);
for(j = 0;j<k;j++) {
a=(ManItem*)(section[i]->get_item(j));
if(!strcmp(name,a->get_display_name(buffer))) return a;
}
a = NULL;
}
return NULL;
}
/************************* ManItem ************************/
inline ManItem::ManItem(ManPath* _man_path, char* _file_name)
{
file_name = my_strdup(_file_name);
man_path = _man_path;
display_name = strrchr(file_name,'/');
display_name = display_name? display_name + sizeof('/'):file_name;
section_name = strrchr(display_name,'.');
if (!section_name) { section_ID = 0; return;}
for (;is_zip_suffix(section_name) && section_name != display_name;)
for(section_name--;section_name != display_name && *section_name != '.';section_name --);
if (section_name == display_name) {section_ID = 0; return;}
section_ID = section_translate_c_to_n(++section_name);
//if(!section_ID) printf("%s\n",display_name);
}
inline ManItem::~ManItem()
{
if(file_name) free(file_name);
}
char * ManItem::get_display_name(char * buffer)
{
char * p2 = buffer;
for(char * p = display_name;p+1 != section_name && *p != '\0';) *buffer++ = *p++;
*buffer = '\0';
return p2;
}
char * ManItem::get_section_name(char * buffer)
{
char * p2 = buffer;
for(char * p = section_name;*p != '.' && *p != '\0';) *buffer++ = *p++;
*buffer = '\0';
return p2;
}
int ManItem::get_section_ID() {return section_ID;}
void * ManItem::get_man_path() {return (void *)man_path;}
void ManItem::active_man_page(void)
{
int i;
int len;
char buffer[2*BUFFER_SIZE];
char loc_name[BUFFER_SIZE];
char buffer2[BUFFER_SIZE];
switch ((int)context->get_value("show_mode")) {
case 0:
sprintf(buffer,"%s -T '%s manual page' -n GMan -e man ",
(char*)context->get_value("xterm_command"),
get_display_name(buffer1));
len = strlen(buffer);
attach(buffer+len,man_path->GetPath(),file_name);
//g_warning(buffer);
if(!fork())
{
//printf(buffer);
system(buffer);
_exit(0);
}
break;
case 1:
sprintf(loc_name," ~/.gman.%s.ps ",get_display_name(buffer1));
sprintf(buffer,"man -t ");
len = strlen(buffer);
attach(buffer+len,man_path->GetPath(),file_name);
strcat(buffer," >> ");
strcat(buffer,loc_name);
strcat(buffer," ; ");
strcat(buffer,(char*)context->get_value("gv_command"));
strcat(buffer,loc_name);
strcat(buffer," ; rm ");
strcat(buffer,loc_name);
//g_warning(buffer);
if(!fork())
{
//printf(buffer);
system(buffer);
_exit(0);
}
break;
/*
case 2:
sprintf(loc_name," ~/.gman.%s.html ",get_display_name(buffer1));
if(strstr(file_name,".gz")) sprintf(buffer,"gunzip -c ");
else sprintf(buffer,"cat ");
len = strlen(buffer);
attach(buffer+len,man_path->GetPath(),file_name);
strcat(buffer," > ~/.gman.tmp ;");
strcat(buffer," man2html ~/.gman.tmp -M ");
strcat(buffer,(char*)context->get_value("cgi_location"));
strcat(buffer," -H ");
strcat(buffer,(char*)context->get_value("cgi_host"));
strcat(buffer," >> ");
strcat(buffer,loc_name);
strcat(buffer," ; ");
strcat(buffer,(char*)context->get_value("browser_command"));
strcat(buffer,loc_name);
strcat(buffer," ; rm ~/.gman.tmp ; sleep 120; rm ");
strcat(buffer,loc_name);
g_warning(buffer);
if(!fork())
{
//printf(buffer);
system(buffer);
_exit(0);
}
break;
*/
case 2:
sprintf(loc_name," ~/.gman.%s.html ",get_display_name(buffer1));
//g_warning(loc_name);
strcpy(buffer,"gman.cgi ");
strcat(buffer," ");
strcat(buffer,get_section_name(buffer2));
strcat(buffer," ");
strcat(buffer,get_display_name(buffer2));
strcat(buffer," >> ");
strcat(buffer,loc_name);
strcat(buffer," ; ");
strcat(buffer,(char*)context->get_value("browser_command"));
//if (strstr((char*)context->get_value("browser_command"),"mozilla")) strcat(buffer," -chrome ");
strcat(buffer,loc_name);
strcat(buffer," ; sleep 120; rm ");
strcat(buffer,loc_name);
//g_warning(buffer);
if(!fork())
{
//printf(buffer);
system(buffer);
_exit(0);
}
break;
case 3:
sprintf(buffer,(char*)context->get_value("browser_command"));
len = strlen(buffer);
strcat(buffer," \"http://");
strcat(buffer,(char*)context->get_value("cgi_host"));
strcat(buffer,(char*)context->get_value("cgi_location"));
strcat(buffer,"?");
strcat(buffer,get_section_name(loc_name));
strcat(buffer,"+");
strcat(buffer,get_display_name(loc_name));
strcat(buffer,"\"");
//g_warning(buffer);
if(!fork())
{
//printf(buffer);
system(buffer);
_exit(0);
}
break;
default:
if(context->get_value("show_warning"))
g_print("unexpected \'show_mode\' : %d ",(int)context->get_value("show_mode"));
return;
}
//g_warning(buffer);
return;
}
/************************* init global data ************************/
/* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */
void attach (char *dest, const char *dirname, const char *name)
{
const char *dirnamep = dirname;
/* Copy dirname if it is not ".". */
if (dirname[0] != '.' || dirname[1] != 0)
{
while (*dirnamep) *dest++ = *dirnamep++;
/* Add '/' if `dirname' doesn't already end with it. */
if (dirnamep > dirname && dirnamep[-1] != '/') *dest++ = '/';
}
while (*name) *dest++ = *name++;
*dest = 0;
}
int section_translate_c_to_n(const char *c)
{
int i;
for(i=0;sections[i].name && strncmp(sections[i].name,c,sections[i].n);i++);
if(sections[i].name == NULL) return 0; // no match
return 1<<i;
}
int is_zip_suffix(char * s)
{
int i;
for (i=0;suffix[i].name && strncmp(suffix[i].name,s,suffix[i].n);i++);
return suffix[i].n;
}
int man_item_compare(ManItem ** a,ManItem ** b)
{
return (strcmp((*a)->get_display_name(buffer1),(*b)->get_display_name(buffer2)));
}
/*
int ItemMatch(char * name)
{
int i;
for (i=0;i<item_list_count && strcmp(name,item_list[i]->display_name)>0 ;i++);
return (i >= item_list_count)? i-1:i;
}
*/