/* GnoSamba 0.3.3
 * copyright 1998-9 Perry Piplani
 * redistributable under the terms of the GPL:
 * http://www.gnu.org/copyleft/gpl.html
 */



#include "params.h"
#include "gtksamba.h"
#include <unistd.h>


BOOL sfunc(char *service, void *window){
  char *sublist_titles[2] = {"Parameter","Value"};
  int last_row;
  GtkWidget *label;
  GtkWidget *scrolled;
  GtkWidget *rightnote;
  GtkWidget *servicelist;
  GtkWidget *sublist;

  servicelist=gtk_object_get_data(GTK_OBJECT(window),"servicelist");
  rightnote=gtk_object_get_data(GTK_OBJECT(window),"rightnote");

  last_row = gtk_clist_append(GTK_CLIST(servicelist),&service);
  
  sublist = gtk_clist_new_with_titles( 2, sublist_titles);
  gtk_object_set_data(GTK_OBJECT(window),"sublist",sublist);

  gtk_clist_set_selection_mode(GTK_CLIST(sublist),GTK_SELECTION_BROWSE);
  gtk_clist_set_column_width (GTK_CLIST(sublist),0,125);
  scrolled = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), 
				 GTK_POLICY_AUTOMATIC, 
				 GTK_POLICY_AUTOMATIC);
  gtk_container_add (GTK_CONTAINER (scrolled), sublist);
  gtk_widget_show (sublist);
  gtk_widget_show(scrolled);
  label=gtk_label_new(service);
  gtk_widget_show(label);
  gtk_notebook_append_page (GTK_NOTEBOOK (rightnote),scrolled , label);

  gtk_signal_connect(GTK_OBJECT(sublist),
                         "select_row",
                         GTK_SIGNAL_FUNC(c_select_param),
                         window);
  gtk_clist_set_row_data(GTK_CLIST(servicelist),last_row,
          (gpointer)(sublist));

    
  return True;
}

BOOL pfunc(char *pname, char *pvalue, void *window){
  GtkWidget *sublist;

  char *pair[2];
  
  sublist=gtk_object_get_data(GTK_OBJECT(window),"sublist");

  pair[0]=pname;
  pair[1]=pvalue;

  if (!sublist) {
    if(!sfunc("global", window))
      return False;
    sublist=gtk_object_get_data(GTK_OBJECT(window),"sublist");
    if (!sublist)
      return False;
  }    
  
  gtk_clist_append(GTK_CLIST(sublist),pair);
  return True;
}

void smbwin_open_lists(GtkWidget *window, char *file){
  GtkWidget *servicelist;
  GtkWidget *sublist;
  gchar *filepath;

  servicelist=gtk_object_get_data(GTK_OBJECT(window),"servicelist");  
  sublist=gtk_object_get_data(GTK_OBJECT(window),"sublist");
  filepath=gtk_object_get_data(GTK_OBJECT(window),"filepath");

  if(filepath){
    g_free(filepath);
    gtk_object_set_data(GTK_OBJECT(window),"filepath",NULL);
  }
  smbwin_clear_lists(window);
  
  if(file){
    filepath=g_strdup(file);
    gtk_object_set_data(GTK_OBJECT(window),"filepath",filepath);
    gtk_window_set_title(GTK_WINDOW(window),file);
    if(!pm_process(file,sfunc,pfunc,window)){
      make_user_mesg("Error Processing File:","Error");
      return;
    }
    gtk_clist_select_row(GTK_CLIST(servicelist),0,0);
  }

  return;
  
}

void smbwin_clear_lists(GtkWidget *window){
  int i;
  GtkWidget *rightnote;
  GtkWidget *servicelist;

  servicelist=gtk_object_get_data(GTK_OBJECT(window),"servicelist");

  rightnote=gtk_object_get_data(GTK_OBJECT(window),"rightnote");


  for(i=0; i < GTK_CLIST(servicelist)->rows; i++)
    gtk_notebook_remove_page(GTK_NOTEBOOK(rightnote),0);
  gtk_object_set_data(GTK_OBJECT(window),"sublist",NULL);
  gtk_clist_clear(GTK_CLIST(servicelist));
  
  return;
}

  
void smbwin_delete_service(GtkWidget *window){
  int row;
  GtkWidget *rightnote;
  GtkWidget *servicelist;

  servicelist=gtk_object_get_data(GTK_OBJECT(window),"servicelist");
  rightnote=gtk_object_get_data(GTK_OBJECT(window),"rightnote");

  row = (int)(GTK_CLIST(servicelist)->selection->data);
  gtk_object_set_data(GTK_OBJECT(window),"sublist",NULL);
  gtk_notebook_remove_page(GTK_NOTEBOOK(rightnote),row);
  
  gtk_clist_remove(GTK_CLIST(servicelist),row);
  
  if(row)
    row--;
  gtk_clist_select_row(GTK_CLIST(servicelist),row,0);
  
  
}

void smbwin_insert_service(char *service, GtkWidget *window){
  GtkWidget *sub;
  GtkWidget *scrolled;
  GtkWidget *label;
  char *sublist_titles[2] = {"Parameter","Value"};
  int row;
  GtkWidget *rightnote;
  GtkWidget *servicelist;

  servicelist=gtk_object_get_data(GTK_OBJECT(window),"servicelist");
  rightnote=gtk_object_get_data(GTK_OBJECT(window),"rightnote");
  
  if(GTK_CLIST(servicelist)->selection)
    row = (int)(GTK_CLIST(servicelist)->selection->data)+1;
  else
    row=0;
  
    gtk_clist_insert(GTK_CLIST(servicelist),row,&service);

  
  sub = gtk_clist_new_with_titles( 2, sublist_titles);

  gtk_clist_set_selection_mode(GTK_CLIST(sub),GTK_SELECTION_BROWSE);
  gtk_clist_set_column_width (GTK_CLIST(sub),0,125);
  scrolled = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), 
				 GTK_POLICY_AUTOMATIC, 
				 GTK_POLICY_AUTOMATIC);
  gtk_container_add (GTK_CONTAINER (scrolled), sub);
  gtk_widget_show (sub);
  gtk_widget_show(scrolled);
  label=gtk_label_new(service);
  gtk_widget_show(label);
  gtk_notebook_insert_page (GTK_NOTEBOOK (rightnote),scrolled , label, row);

  gtk_signal_connect(GTK_OBJECT(sub),
                         "select_row",
                         GTK_SIGNAL_FUNC(c_select_param),
                         window);
  gtk_clist_set_row_data(GTK_CLIST(servicelist),row,
          (gpointer)(sub));

  gtk_clist_select_row(GTK_CLIST(servicelist),row,0);

  return;
}
  

void c_select_param(GtkWidget *widget,
          gint row,
          gint column,
          GdkEventButton *event,
          gpointer window){
  if(event && event->type==GDK_2BUTTON_PRESS)
    make_edit_dialog(GTK_WIDGET(window));
  return;
}

void c_select_service(GtkWidget *widget,
          gint row,
          gint column,
          GdkEventButton *event,
          gpointer window){
  GtkWidget *rightnote;
  GtkWidget *servicelist;
  GtkWidget *sublist;

  servicelist=gtk_object_get_data(GTK_OBJECT(window),"servicelist");
  rightnote=gtk_object_get_data(GTK_OBJECT(window),"rightnote");

  gtk_notebook_set_page(GTK_NOTEBOOK(rightnote),row);
  
  sublist=gtk_clist_get_row_data(GTK_CLIST(servicelist),row);
  gtk_object_set_data(GTK_OBJECT(window),"sublist",sublist);
}



void write_smb_file(GtkWidget *servicelist,char *filepath){
  FILE *outfile;
  GtkWidget *params;
  char *text;
  int i, j;

  printf("writing to %s, %d sections\n",filepath,GTK_CLIST(servicelist)->rows);
  
  outfile=fopen(filepath,"w");
  
  if(!outfile)
    outfile=stdout;
  
  for(i=0; i < GTK_CLIST(servicelist)->rows; i++){
    params = gtk_clist_get_row_data(GTK_CLIST(servicelist),i);
    gtk_clist_get_text(GTK_CLIST(servicelist),
             i,0,&text);
    fprintf(outfile,";*******************section %s*****************\n",text);
    fprintf(outfile,"[%s]\n",text);
    
    for(j=0; j < GTK_CLIST(params)->rows; j++){
      
      gtk_clist_get_text(GTK_CLIST(params),
          j,0,&text);
      fprintf(outfile,"%s = ",text);
      
      gtk_clist_get_text(GTK_CLIST(params),
          j,1,&text);
      fprintf(outfile,"%s\n",text);
    }
  }
  if(outfile != stdout)
    fclose(outfile);
  return;
}
/************************************************************/
/************************************************************/

FILE *make_man_pipe(int chap, char *page){
  FILE *man = NULL;
  int i = 0;
  char *manpath, *manlook, *pathentry, *buff;

  if((manpath = g_strdup(getenv("MANPATH")))){
    i=strlen(manpath);
    manpath=g_realloc(manpath,(i+40)*sizeof(char *));
    strcat(manpath,":/usr/man:/usr/local/man");
  }
  else
    manpath=g_strdup("/usr/man:/usr/local/man");

  buff = g_malloc((strlen(manpath)+80)*sizeof(char));
  manlook = g_malloc((strlen(manpath)+32)*sizeof(char));
  if((pathentry=strtok(manpath,":")))
    do{
      sprintf(manlook,"%s/man%d/%s.%d.gz",pathentry,chap,page,chap);
      g_print("searching %s\n",manlook);
      if(!access(manlook, R_OK | F_OK)){
	sprintf(buff,"gunzip %s -c | groff -Tlatin1 -mandoc | col -b", manlook);
	if((man = popen(buff,"r"))){
	  g_free(manpath);
	  g_free(manlook);
	  g_free(buff);
	  return man;
	}
      }
      sprintf(manlook,"%s/man%d/%s.%d",pathentry,chap,page,chap);
      g_print("searching %s\n",manlook);
      if(!access(manlook, R_OK | F_OK)){
	sprintf(buff,"groff -Tlatin1 -mandoc %s | col -b", manlook);
	if((man = popen(buff,"r"))){
	  g_free(manpath);
	  g_free(manlook);
	  g_free(buff);
	  return man;
	}
      }
    }  while ((pathentry=strtok(NULL,":")));
  g_free(manpath);
  g_free(manlook);
  g_free(buff);
  return NULL;
}


void make_param_help(char *param){
  GtkWidget *diag;
  GtkWidget *text;
  GtkWidget *vscrollbar;
  GtkWidget *hbox;
  char buff[256], *s;
  char *paramplus;
  FILE *man;
  int len;

  
 
  man = make_man_pipe(5,"smb.conf");
  if(!man){
    make_user_mesg("Cannot open man page\nVerify you have it installed\nand in your MANPATH","Error");
    return;
  }

  len=strlen(param)+3;
  paramplus=(char *)malloc(sizeof(char)*len+1);
  sprintf(paramplus,"   %s",param);

  while( (s = fgets(buff,256,man)) ){
    if( (strstr(buff,"(G)") || strstr(buff,"(S)")) && 
	strstr(buff,paramplus))
      break;
  }
  if(!s) {
    sprintf(buff,"Can't find '%s' in man page\nYour version of Samba may not support it",param);  
    make_user_mesg(buff,"Warning");
    return;
  }

  diag=gnome_dialog_new ("GtkSamba Parameter Help",
			 GNOME_STOCK_BUTTON_OK,
			 NULL);
  gtk_widget_set_usize(diag, 420, 200);  
  gtk_window_position (GTK_WINDOW (diag),GTK_WIN_POS_CENTER);
  gnome_dialog_button_connect_object(GNOME_DIALOG(diag), 0,
			      GTK_SIGNAL_FUNC(gtk_widget_destroy),
			      GTK_OBJECT(diag));


  hbox=gtk_hbox_new(FALSE,0);
  gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (diag)->vbox), 
            hbox, TRUE, TRUE, 0);
  gtk_widget_show (hbox);
  
  text = gtk_text_new(NULL,NULL);
  gtk_box_pack_start (GTK_BOX (hbox), 
            text, TRUE, TRUE, 0);
 
  vscrollbar = gtk_vscrollbar_new (GTK_TEXT(text)->vadj);
  gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0);
  gtk_widget_show (vscrollbar);

  gtk_widget_realize (text);
  gtk_text_freeze (GTK_TEXT (text));


  gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, 
		   NULL,buff, -1);


  while(fgets(buff,256,man)){
    if(strstr(buff,"(G)") || strstr(buff,"(S)"))
       break;
    if(strstr(buff,"NOTE ABOUT USERNAME/PASSWORD VALIDATION"))
      break;
   if(!strncmp(buff,"smb.conf",8) || !strncmp(buff,"SMB.CONF",8)){
      fgets(buff,256,man);
      fgets(buff,256,man);
    }
    else {
      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, 
             NULL,buff, -1);
    }
  }
  pclose(man);
  
  gtk_widget_show(text);

  gtk_widget_show(diag);

}

void cw_lookup_select(GtkWidget *clist){
  int row;
  char *text, *param;
  
  if(GTK_CLIST(clist)->selection){
    row = (int)(GTK_CLIST(clist)->selection->data);
    gtk_clist_get_text(GTK_CLIST(clist),row,0,&text);

    param=(char *)g_malloc(strlen(text)+1);
    strcpy(param,text);
    text=strchr(param,'(');
    *(text-1)='\0';
    make_param_help(param+3);
    g_free(param);
  }
  return;
}
  

void c_lookup_select(GtkWidget *clist,
                    gint row,
                    gint column,
                    GdkEventButton *event,
                    gpointer data){
  char *text, *param;
  
  if(event && event->type==GDK_2BUTTON_PRESS){

    gtk_clist_get_text(GTK_CLIST(clist),row,0,&text);

    param=(char *)g_malloc(strlen(text)+1);
    strcpy(param,text);
    text=strchr(param,'(');
    *(text-1)='\0';
    make_param_help(param+3);
    g_free(param);
  }
  return;
}


void c_make_param_lookup(GtkWidget *widget, gpointer data){
  GtkWidget *diag;
  GtkWidget *clist;
  char buff[256];
  FILE *man;
  char *text;
  GtkWidget *scrolled;

  
  text=buff;
  man = make_man_pipe(5,"smb.conf");
  if(!man){
    make_user_mesg("Cannot open man page\nVerify you have it installed\nand in your MANPATH","Error");
    return;
  }


  diag=gnome_dialog_new ("parameter lookup",
			 NULL);

  gnome_dialog_append_button_with_pixmap(GNOME_DIALOG(diag),
					 "Look Up",
					 GNOME_STOCK_MENU_INDEX);
  gnome_dialog_append_button(GNOME_DIALOG(diag),
			     GNOME_STOCK_BUTTON_CANCEL);

  gtk_widget_set_usize(diag, 300, 300);  
  gtk_window_position (GTK_WINDOW (diag),GTK_WIN_POS_CENTER);
  
  clist=gtk_clist_new(1);
  gtk_clist_set_selection_mode(GTK_CLIST(clist),
                               GTK_SELECTION_BROWSE);
  gtk_signal_connect(GTK_OBJECT(clist),
                     "select_row",
                     GTK_SIGNAL_FUNC(c_lookup_select),
                     NULL);
  scrolled = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, 
				 GTK_POLICY_AUTOMATIC);
  gtk_container_add (GTK_CONTAINER (scrolled), clist);
  gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (diag)->vbox), 
		      scrolled, TRUE, TRUE, 0);
  gtk_widget_show (clist);
  gtk_widget_show (scrolled);
  gnome_dialog_button_connect_object(GNOME_DIALOG(diag), 0,
				     GTK_SIGNAL_FUNC(cw_lookup_select),
				     GTK_OBJECT(clist));
  gnome_dialog_button_connect_object(GNOME_DIALOG(diag), 1,
				     GTK_SIGNAL_FUNC(gtk_widget_destroy),
				     GTK_OBJECT(diag));
  
  while(fgets(buff,256,man)){
    if( strstr(buff,"(G)") || strstr(buff,"(S)")) 
      gtk_clist_append(GTK_CLIST(clist),&text);
  }

  pclose(man);
  gtk_widget_show(diag);
}
  


void make_less_diag(FILE *infile, char *title){
  GtkWidget *diag;
  GtkWidget *text;

  diag=gnome_dialog_new (title,
			 GNOME_STOCK_BUTTON_OK,
			 NULL);
  gtk_widget_set_usize(diag, 500, 300);  
  gtk_window_position (GTK_WINDOW (diag),GTK_WIN_POS_CENTER);
  gnome_dialog_button_connect_object(GNOME_DIALOG(diag), 0,
			      GTK_SIGNAL_FUNC(gtk_widget_destroy),
			      GTK_OBJECT(diag));
  text=gnome_less_new();
  gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (diag)->vbox),  
		      text, TRUE, TRUE, 0);
  gnome_less_show_filestream(GNOME_LESS(text),infile);
  gtk_widget_show(text);
  gtk_widget_show(diag);
}


void c_make_overview(GtkWidget *widget, gpointer data){
  gnome_url_show("man:smb.conf(5)#index");
  return;
}

void c_man_testparm(GtkWidget *widget, gpointer data){
  gnome_url_show("man:testparm(1)#index");
  return;
}

void c_man_smbstatus(GtkWidget *widget, gpointer data){
  gnome_url_show("man:smbstatus(1)#index");
  return;
}

void c_run_testparm(GtkWidget *menu_item, gpointer window){ 
  FILE *tpout;
  char tempath[256];
  char buff[256];
  GtkWidget *servicelist;
  servicelist=gtk_object_get_data(GTK_OBJECT(window),"servicelist");

  
  if(!(GTK_CLIST(servicelist)->rows)){
    make_user_mesg("Nothing to test","Warning");
    return;
  }
  
  tmpnam(tempath);
  write_smb_file(servicelist,tempath);
  
  
  sprintf(buff,"echo | testparm %s", tempath);
  
  tpout = popen(buff,"r");
  if(!tpout){
    make_user_mesg("Can't execute testparm","Warning");
    return;
  }

  make_less_diag(tpout,"testparm results");

  pclose(tpout);
  unlink(tempath);
  return;
}


void c_run_smbstatus(GtkWidget *widget, gpointer data){
  FILE *ssout;
  
  ssout = popen("smbstatus","r");
  if(!ssout){
     make_user_mesg("Can't execute smbstatus","Warning");
     
     return;
  }
  make_less_diag(ssout,"Samba status");
  pclose(ssout);
  return;
}





void c_restart_samba(GtkWidget *widget, gpointer data){
  char *command;

  command=get_config_val("smblocal","restart");
  if(command){
    if(system(command))
      make_user_mesg("Command returned\nnon-zero status","Warning");
    else
      make_user_mesg("Command returned\nsuccessfull exit code","Sucsess!");
    g_free(command);
  }

  return;
}



syntax highlighted by Code2HTML, v. 0.9.1