helpfile.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:9k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 2000  Dizzy (dizzy@roedu.net)
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  */
  18. #include "common/setup_before.h"
  19. #include <stdio.h>
  20. #ifdef HAVE_STDDEF_H
  21. # include <stddef.h>
  22. #else
  23. # ifndef NULL
  24. #  define NULL ((void *)0)
  25. # endif
  26. #endif
  27. #ifdef STDC_HEADERS
  28. # include <stdlib.h>
  29. #else
  30. # ifdef HAVE_MALLOC_H
  31. #  include <malloc.h>
  32. # endif
  33. #endif
  34. #ifdef HAVE_STRING_H
  35. # include <string.h>
  36. #else
  37. # ifdef HAVE_STRINGS_H
  38. #  include <strings.h>
  39. # endif
  40. #endif
  41. #include "compat/strcasecmp.h"
  42. #include <ctype.h>
  43. #include <errno.h>
  44. #include "compat/strerror.h"
  45. #include "message.h"
  46. #include "connection.h"
  47. #include "common/util.h"
  48. #include "common/eventlog.h"
  49. #include "helpfile.h"
  50. #include "common/setup_after.h"
  51. #include "account_wrap.h"
  52. #include "command_groups.h"
  53. static FILE* hfd=NULL; /* helpfile descriptor */
  54. static int list_commands(t_connection *);
  55. static int describe_command(t_connection *, char const *);
  56. extern int helpfile_init(char const *filename)
  57. {
  58.     if (!filename)
  59.     {
  60.         eventlog(eventlog_level_error,"helpfile_init","got NULL filename");
  61. return -1;
  62.     }
  63.     if (!(hfd = fopen(filename,"r")))
  64.     {
  65.         eventlog(eventlog_level_error,"helpfile_init","could not open help file "%s" for reading (fopen: %s)",filename,strerror(errno));
  66.         return -1;
  67.     }
  68.     return 0;
  69. }
  70. extern int helpfile_unload(void)
  71. {
  72.     if (hfd!=NULL)
  73.     {
  74. if (fclose(hfd)<0)
  75.     eventlog(eventlog_level_error,"helpfile_unload","could not close help file after reading (fclose: %s)",strerror(errno));
  76. hfd = NULL;
  77.     }
  78.     return 0;
  79. }
  80. extern int handle_help_command(t_connection * c, char const * text)
  81. {
  82.     unsigned int i,j;
  83.     char         comm[MAX_COMMAND_LEN];
  84.         
  85.     if (hfd == NULL)
  86.     { /* an error ocured opening readonly the help file, helpfile_unload was called, or helpfile_init hasn't been called */
  87.         message_send_text(c,message_type_error,c,"Oops ! There is a problem with the help file. Please contact the administrator of the server.");
  88.         return 0;
  89.     }
  90.     
  91.     rewind(hfd);
  92.     for (i=0; text[i]!=' ' && text[i]!=''; i++); /* skip command */
  93.     for (; text[i]==' '; i++);
  94.     if (text[i]=='/') /* skip / in front of command (if present) */
  95.         i++;
  96.     for (j=0; text[i]!=' ' && text[i]!=''; i++) /* get comm */
  97.     if (j<sizeof(comm)-1) comm[j++] = text[i];
  98.     comm[j] = '';
  99.         
  100.     /* just read the whole file and dump only the commands */
  101.     if (comm[0]=='')
  102.     {
  103.         list_commands(c);
  104.         return 0;
  105.     }
  106.     
  107.     if (describe_command(c,comm)==0) return 0;
  108.     /* no description was found for this command. inform the user */
  109.     message_send_text(c,message_type_error,c," no help available for that command");
  110.     return 0;
  111. }
  112. static int list_commands(t_connection * c)
  113. {
  114.     char * line;
  115.     int    i;
  116.     
  117.     message_send_text(c,message_type_info,c,"Chat commands:");
  118.     while ((line=file_get_line(hfd))!=NULL)
  119.     {
  120.         for (i=0;line[i]==' ' && line[i]!='';i++); /* skip spaces in front of %command */
  121.         if (line[i]=='%')  /* is this a command ? */
  122.         {
  123.             char *p,*buffer;
  124.             int al;
  125.     int skip;
  126.     unsigned int length,position;
  127.     
  128.             /* ok. now we must see if there are any aliases */
  129.             length=MAX_COMMAND_LEN+1; position=0;
  130.             buffer=malloc(length+1); /* initial memory allocation = pretty fair */
  131.             if (buffer==NULL) { /* out of memory ? */
  132.                 eventlog(eventlog_level_error,"list_commands","could not allocate memory using malloc of size %u for printing aliases (malloc)",length+1);
  133.                 message_send_text(c,message_type_error,c," Not Enough Memory!");
  134. free(line);
  135.                 return 0;
  136.             }
  137.             p=line+i;
  138.             do
  139.     {
  140.                 al=0;
  141. skip = 0;
  142.                 for (i=1;p[i]!=' ' && p[i]!='' && p[i]!='#';i++); /* skip command */
  143.                 if (p[i]==' ') al=1; /* we have something after the command.. must remember that */
  144.                 p[i]=''; /* end the string at the end of the command */
  145.                 p[0]='/'; /* change the leading character (% or space) read from the help file to / */
  146. if (!(command_get_group(p) & account_get_command_groups(conn_get_account(c)))) skip=1;
  147.                 if (length<strlen(p)+position+1)
  148. {
  149.                     char * aux;
  150.     
  151.                     /* if we don't have enough space in the buffer then get some */
  152.                     length=strlen(p)+position+1; /* the new length */
  153.                     aux=realloc(buffer,length+1);
  154.                     if (aux==NULL)
  155.     { /* out of memory ? */
  156.                         eventlog(eventlog_level_error,"list_commands","could not allocate memory using malloc of size %u for printing aliases (malloc)",length+1);
  157.                         message_send_text(c,message_type_error,c," Not Enough Memory!");
  158.                         free(buffer);
  159. free(line); /* free the memory allocated in file_get_line */
  160.                         return 0;
  161.                     }
  162.                     buffer = aux;
  163.                 }
  164.                 buffer[position++]=' '; /* put a space before each alias */
  165.                 /* add the alias to the output string */
  166.                 strcpy(buffer+position,p); position+=strlen(p);
  167.                 if (al)
  168. {
  169.                     for (;p[i+1]==' ' && p[i+1]!='' && p[i+1]!='#';i++); /* skip spaces */
  170.                     if (p[i+1]=='' || p[i+1]=='#')
  171.     {
  172. al=0; continue;
  173.                     }
  174.                     p+=i; /* jump to the next command */
  175.                 }
  176.             } while (al);
  177.             if (!skip) message_send_text(c,message_type_info,c,buffer); /* print out the buffer */
  178.             free(buffer);
  179.         }
  180.         free(line); /* free the memory allocated in file_get_line */
  181.     }
  182.     return 0;
  183. }
  184. static int describe_command(t_connection * c, char const * comm)
  185. {
  186.     char * line;
  187.     int    i;
  188.     
  189.     /* ok. the client requested help for a specific command */
  190.     while ((line=file_get_line(hfd))!=NULL)
  191.     {
  192.         for (i=0;line[i]==' ' && line[i]!='';i++); /* skip spaces in front of %command */
  193.         if (line[i]=='%') /* is this a command ? */
  194.         {
  195.             char *p;
  196.             int al;
  197.             /* ok. now we must see if there are any aliases */
  198.             p=line+i;
  199.             do
  200.     {
  201.                 al=0;
  202.                 for (i=1;p[i]!=' ' && p[i]!='' && p[i]!='#';i++); /* skip command */
  203.                 if (p[i]==' ') al=1; /* we have something after the command.. must remember that */
  204.                 p[i]=''; /* end the string at the end of the command */
  205.                 if (strcasecmp(comm,p+1)==0) /* is this the command the user asked for help ? */
  206.                 {
  207.                     free(line);
  208.                     while ((line=file_get_line(hfd))!=NULL)
  209.                     { /* write everything until we get another % or EOF */
  210.                         for (i=0;line[i]==' ';i++); /* skip spaces in front of a possible % */
  211.                         if (line[i]=='%')
  212. {
  213.                             free(line); break; /* we reached another command */
  214.                         }
  215.                         if (line[0]!='#')
  216. { /* is this a whole line comment ? */
  217.                             /* truncate the line when a comment starts */
  218.                             for (;line[i]!='' && line[i]!='#';i++);
  219.                             if (line[i]=='#') line[i]='';
  220.                             message_send_text(c,message_type_info,c,line);
  221.                         }
  222.                         free(line);
  223.                     }
  224.                     return 0;
  225.                 }
  226.                 if (al)
  227. {
  228.                     for (;p[i+1]==' ' && p[i+1]!='';i++); /* skip spaces */
  229.                     if (p[i+1]=='')
  230.     {
  231.                         al=0; continue;
  232.                     }
  233.                     p+=i; /* jump to the next command */
  234.                 }
  235.             } while (al);
  236.         }
  237.         free(line);
  238.     }
  239.     
  240.     return -1;
  241. }