[MAN] AnalyzeArgv(): Fix 2 overruns related to element (#703)
[reactos.git] / modules / rosapps / applications / sysutils / man / man.c
1 /*
2 * FILE : man.c
3 * NATIVE NAME: ReactOS manual browser
4 * AUTHOR : Semyon Novikov (tappak)
5 * PROJECT : ReactOS Operating System
6 * DESCRIPTION: manual file browser (Use Linux man file syntax)
7 * DATE : 2004-03-29
8 * LICENSE : GPL
9 */
10
11 /* Known issues.
12 * 1. Scroll screen
13 * 2. Non ENVIRONMENT manpath varrible
14 * 3. At the end of man page must be ./" tag!
15 */
16
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <windows.h>
21 #include <wincon.h>
22
23 #define MAXLINE 256
24 #define BOLD 7|9
25 #define ITALIC 3|9
26 #define NORMAL 7|0
27
28 /*===[functions]===*/
29 void SetCl(WORD cl);
30 int OpenF(char* name);
31 int CloseF(void);
32 void Usage(void);
33 int AnalyzeArgv(char *);
34 int AnalyzeFile();
35 /*=================*/
36
37 /*====[Globals]====*/
38 FILE* manfile;
39 char OpenFlag=0;
40 char manpath[MAXLINE]="c:\\man\\";
41 /*=================*/
42
43 void
44 SetCl(WORD cl)
45 {
46 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),cl);
47 }
48
49 int
50 OpenF(char* name)
51 {
52 int retval=0;
53 char *manpath_local=(char*)malloc(sizeof(char)*MAXLINE);
54
55 strcpy(manpath_local, manpath); //save mandir value
56
57 if((manfile=fopen((strcat(manpath_local,name)),"r"))!=NULL)
58 {
59 OpenFlag=1;
60 AnalyzeFile();
61 }
62 else
63 retval=-1;
64
65 free(manpath_local);
66 return retval;
67 }
68
69 int
70 CloseF()
71 {
72 int retval=0;
73
74 if(fclose(manfile))
75 OpenFlag=0;
76 else retval=-1;
77
78 return retval;
79 }
80
81 void
82 Usage()
83 {
84 puts("usage: man [command]");
85 puts("see \"man man\" for details");
86 }
87
88 int
89 AnalyzeArgv(char *argument)
90 {
91 int element;
92 char HelpFlag=0;
93 char *keys[]={"--help","/h","/?","-h"};
94 char *sections[]={".1",".2",".3",".4",".5",".6",".7",".8",".9"};
95 char *filename=(char*)malloc(sizeof(char)*MAXLINE);
96
97 strcpy(filename,argument); //save argument value
98
99 for(element=0;element<_countof(keys);element++)
100 {
101 if(!strcmp(keys[element],argument))
102 {
103 Usage();
104 HelpFlag=1;
105 }
106 }
107
108 element = 0;
109
110 if(!HelpFlag)
111 {
112
113 if(OpenF(filename))
114 {
115 while(element<_countof(sections)&&OpenF(strcat(filename,sections[element])))
116 {
117 strcpy(filename,argument);
118 element++;
119 }
120
121 if(element>=_countof(sections)) printf("No manual for %s\n",argument);
122 }
123
124 }
125
126 return element;
127 }
128
129 void sh_outp(char *cur_string)
130 {
131 int symbol;
132 putchar('\n');
133 putchar('\n');
134 for(symbol=3;putchar(cur_string[symbol]); symbol++);
135 }
136
137 void th_outp(char *cur_string, char *THtag)
138 {
139 int symbol;
140 putchar('\n');
141 putchar('\n');
142 putchar('\t');
143 putchar('\t');
144 SetCl(ITALIC);
145 for(symbol=3;putchar(THtag[symbol]); symbol++);
146 putchar('\n');
147 SetCl(NORMAL);
148 }
149
150 void text_outp(char *cur_string)
151 {
152 int symbol=0;
153
154 if(cur_string[0]=='.')
155 while(cur_string[symbol]!=' ')
156 symbol++;
157
158
159 for(;cur_string[symbol]!='\n'; symbol++)
160 putchar(cur_string[symbol]);
161 putchar(' ');
162 }
163
164 int
165 AnalyzeFile()
166 {
167 char *cur_string=(char*)malloc(sizeof(char)*MAXLINE);
168 char *THtag=(char*)malloc(sizeof(char)*MAXLINE);
169
170
171
172
173 while(fgets(cur_string,MAXLINE,manfile))
174
175 /* TAGs processing */
176 if((cur_string[0]=='.')&&(cur_string[1]=='S')&&
177 (cur_string[2]=='H')) // .SH tag
178 {
179 SetCl(BOLD);
180 sh_outp(cur_string);
181 SetCl(NORMAL);
182 }
183 else
184 if((cur_string[0]=='.')&&(cur_string[1]=='I')&&
185 (cur_string[2]==' ')) // .I tag
186 {
187 SetCl(ITALIC);
188 text_outp(cur_string);
189 SetCl(NORMAL);
190 }
191 else
192 if((cur_string[0]=='.')&&(cur_string[1]=='/')&&
193 (cur_string[2]=='\"')); // ./" tag (comment)
194
195 else
196 if((cur_string[0]=='.')&&(cur_string[1]=='T')&&
197 (cur_string[2]=='H')) // .TH tag
198 {
199 strcpy(THtag,cur_string);
200 }
201 else
202 if((cur_string[0]=='.')&&(cur_string[1]=='B')&&
203 (cur_string[2]==' ')) // .B tag
204 {
205 SetCl(BOLD);
206 text_outp(cur_string);
207 SetCl(NORMAL);
208 }
209 else
210 if((cur_string[0]=='.')&&(cur_string[1]=='N')&&
211 (cur_string[2]=='L'))
212 {
213 putchar('\n');
214 putchar(' ');
215 }
216
217 else text_outp(cur_string); // print plane text
218 th_outp(cur_string, THtag);
219 /* END of TAGs processing */
220 free(cur_string);
221 free(THtag);
222
223 return 0;
224 }
225
226
227 int
228 main(int argc, char *argv[])
229 {
230
231 switch(argc)
232 {
233 case 1: Usage(); break;
234 case 2: AnalyzeArgv(argv[1]);break;
235 default: Usage();break;
236 }
237
238 if(OpenFlag)CloseF();
239 SetCl(NORMAL);
240 return 0;
241 }
242