1.   #!/usr/bin/perl
2.   ######################################
3.   ## Coded by Douglas[at]WeakNetLabs[dot]com
4.   ## Coded by Chartreuse[at]WeakNetLabs[dot]com
5.   #####################################
6.   #  TODO List:  (Add to when new features are wanted with priorities 0-9 where 0 is urgent)
7.   #   + -7- Create configuration file code and store the environment there to be loaded
8.   #   + -6- Create a Help File/Help Page to display for command help
9.   #   + -3- Create more commands and populate them out
10.  #   + -9- Trap Arrow keys and implement functions to do scrollback
11.  #   + -5- Remove system call's in favor of modules -- system calls reduce portability
12.  #
13.  #
14.  #
15.  #
16.  #
17.  #####################################
18.  #  Change Log:
19.  # [18/05/10 Chartreuse] Recoded Trevelyn's original code and added my own
20.  # [19/05/10 Chartreuse] Added in Trevelyn's new code for mysql and such
21.  #                       Made Help function print list of valid commands
22.  #                       Moved parsing user input to it's own function
23.  #                       Added support for command alias's
24.  #
25.  ##
26.  use strict;
27.  use warnings;
28. 
29.  #####################################
30.  # Load up Modules
31.  ##
32.  use Cwd;
33.  use Term::ANSIColor;
34.  use File::Spec;
35.  use POSIX;
36.  use Term::Cap;
37. 
38. 
39.  #####################################
40.  # Pre-set Environment variables
41.  ##  TODO: Move to configuration file (.celeritasrc) and load on startup
42.  my $hostname = "celeritas";
43.  my $PS1 = colored (getlogin() . "\@$hostname", "bold green") . colored (" " . getWorkingDirectory() . "%", "bold blue") . " ";
44.  my $version = "0.1.1-ALPHA";
45. 
46.  ####################################
47.  # Global Variables  --  Avoid Creating these
48.  ##  TODO: Find other solutions rather than these
49.  my $term;                          # Needed for term::cap
50.  my $termios = new POSIX::Termios;  # Needed for term::cap
51.  my $iAmAlive = 1; # Clean exit flag
52. 
53.  my $db = "";
54.  my $usr = "";
55.  my $col = 0;
56.  my $pass = "";
57. 
58.  my @validCommands = qw /exit echo sys help clear mysql set use show/; # List of valid commands that can be symbolically called
59.  my %commandAlias = (   # Hash of alias's, key = alias name, value = command name
60.  "usedb" => "use"
61.         );
62. 
63.  ####################################
64.  ##### ENTRY POINT - Begin Here #####
65.  ####################################
66.  initialSetup();
67.  mainLoop();
68.  cleanUpAndQuit();
69.  ###################################
70.  ######### END ENTRY POINT #########
71.  ###################################
72. 
73. 
74.  ###################################
75.  # Subroutines Here
76.  ##
77.  ### initialSetup() - Preconfigure everything before entering mainLoop()
78.  # TODO: Unknown
79.  sub initialSetup
80.  {
81.  ## Stuff needed for Term::Cap
82. 
83.  # General terminal line I/O
84.  $termios->getattr;
85.  # Extract the entry of the terminal type
86.  $term = Term::Cap->Tgetent( { TERM => undef, OSPEED => $termios->getospeed } );
87. 
88.  return;
89.  }
90.  ### mainLoop() - Program Flow and Logic Here ###
91.  # TODO: Unknown
92.  sub mainLoop
93.  {
94.  my $returnValue=0;
95.  while($iAmAlive) ## Logic Loop while we have not been told to exit nicely
96.  {
97.  printPrompt(); # Show us a prompt
98.  parseUserInput();
99. 
100. }
101.
102. return;
103. }
104. sub parseUserInput
105. {
106. chomp( my $userCommand = <STDIN> ); # Set $userCommand with user input and clean off any trailing newlines
107. $userCommand =~ /^(\S+)\s?(.*)/; # Return all characters up till first space and everything after first space
108.
109. my $commandName = $1;
110. my $commandArguments = $2;
111.
112. if(!( grep {$_ eq lc($1)} @validCommands))
113. {
114. if( exists $commandAlias{$1} ) # Check if we are dealing with a command alias
115. {
116. no strict 'refs';  # Should we even be doing the symbolic-references in the first place?
117.
118. return &{lc($commandAlias{$1} . "_cmd")}($2);  # Does the postfix protection make this safe enough?
119. }
120. else
121. {
122. print colored("Celeritas:", "bold red") . colored(" $1","bold") . " command not understood\n";
123. return 0;
124. }
125. }
126. else
127. {
128. no strict 'refs';  # Should we even be doing the symbolic-references in the first place?
129. $commandName .= "_cmd";  # Append postfix to entered command and call it
130. return &{lc($commandName)}($2);           # Does the postfix protection make this safe enough?
131. }
132. return 0;
133. }
134. ### printPrompt() - Prints the prompt ($PS1) to STDIN
135. # TODO: Unknown
136. sub printPrompt
137. {
138. print $PS1; # Just print out the prompt string for now
139. return;
140. }
141.
142. ### getWorkingDirectory() - Returns the current working directory without the full path
143. # TODO: Unknown
144. sub getWorkingDirectory
145. {
146. my @dirs = File::Spec->splitdir( Cwd::cwd() ); # Split the Current working path
147. return $dirs[$#dirs];  # Return the last element, (The current directory)
148. }
149.
150. ### cleanUpAndQuit() - Clean up all we've done, prepare to quit, and quit
151. # TODO: Unknown
152. sub cleanUpAndQuit
153. {
154. print "\n";  # Give shell some breathing room before leaving
155. exit(0);
156. }
157.
158. ####################################
159. # Celeritas Commands Below
160. ##  TODO: Populate Commands
161.
162. ### exit_cmd - Command to nicely exit back to the shell
163. # TODO: Unknown
164. sub exit_cmd
165. {
166. print "Now Exiting... See you later :)\n";
167. $iAmAlive = 0;
168.
169. return;
170. }
171. ### echo_cmd - Command to echo arguments out to STDOUT
172. # TODO: Possible Input Protection? Required?
173. sub echo_cmd
174. {
175. my ($input) = @_;
176. print "$input\n";
177.
178. return;
179. }
180. ### sys_cmd - Run command through the host shell
181. # TODO: Reimplement Trevelyn's Backref the REGEX code into a subroutine
182. sub sys_cmd
183. {
184. # Trevelyn's Backreference the REGEX Code  
185. my ($input) = @_;
186. my @split;
187. if ($input =~ /\\-[0-9]/) {
188. @split = split(/\)/, $input);
189. foreach (@split) {
190. $_ =~ s/.*\(//g;
191. }
192. }
193. my $n = 0;
194. foreach (@split) {
195. $n++;
196. $input =~ s/\\-$n/\($_\)/g;
197. }
198.
199. system($input); # Run the command
200. print "Command was $input\n";
201. return;
202. }
203. ### help_cmd - Display help pages to user
204. # TODO: Create Help Menu
205. sub help_cmd
206. {
207. print "Help\n";
208. print "-----------------\n";
209. print "Valid Commands: \n";
210. print join(" ", @validCommands) . "\n";
211. print "Help not yet fully implemented... Sorry :(\n";
212.
213. return;
214. }
215. ### clear_cmd - Clears the screen
216. # TODO: Unknown
217. sub clear_cmd
218. {
219. print $term->Tputs('cl');
220. return;
221. }
222. ### mysql_cmd - Run mysql
223. # TODO: Use Modules instead of system command?
224. sub mysql_cmd {
225. my @split_cmd = split(" ", shift);
226. if (@split_cmd)
227. {
228. my ($what,$table,$regexp);
229. my $n = 0;
230. foreach (@split_cmd)
231. { 
232. if ($_ =~ /select/i) { $what = $split_cmd[($n)]; }
233. if ($_ =~ /from/i) { $table = $split_cmd[($n)]; }
234. if ($_ =~ /REGEXP/) { $regexp = $split_cmd[($n)]; }
235. $n++;
236. }
237. # slurp all results line x line into array @lines:
238. ## SYSTEM COMMAND, perhaps use the MySQL module? ##
239. my @lines = `mysql -t -e \'select $what from $table\' $db --password=$pass --user=$usr`;
240. # get column of target for "where $something regexp..."
241.
242. my $g = 0;
243. print $lines[0] . $lines[1] . $lines[2];
244.
245. foreach( $lines[1] ) 
246. {
247. if ($_ =~ /where/i) 
248. { 
249. $col = ($g + 1); ## Changed from my $col to $col, it's already a global var, did you mean to locally scope it to inside this if statement only?
250. last();
251. } $g++;
252. }
253.
254. my $t = $#lines;
255. foreach(@lines[3..$t])
256. {
257. my @split_lines = split(/" "/, $_);
258. # Here it is, if it's here, it gets printed:
259. if ($split_lines[$col] =~ /$regexp/) 
260. {
261. chomp $_;
262. print "$_\n";
263. print $lines[0];
264. }
265. }
266. #print "The command was: select " . $what . " from " . " $table " . " where column " . $something . " had a regexp match of " . $regexp . "\n";
267. }
268. return;
269. }
270. ### set_cmd - Set variables for built in commands
271. # TODO: Add more?   Maybe make these like environment variables
272. #                   and use a symbolic reference to store them as
273. #                   varname_env and make them accessable in commands
274. #                   and regex
275. sub set_cmd {
276. my @split_cmd = split(" ", shift);
277. if (@split_cmd)
278. {
279. if ($split_cmd[0] eq 'db' or $split_cmd[0] eq 'database') { 
280. print "Database: ";
281. $db = <STDIN>;
282. chomp $db;
283. return;
284. }
285. if ($split_cmd[0] eq 'pass' or $split_cmd[0] eq 'passwd') { 
286. print "Password: ";
287. system "stty -echo";  ## Use Term::Cap module to remove the need for system call?
288. $pass = <STDIN>;
289. chomp $pass;
290. system "stty echo"; ## Use Term::Cap module to remove the need for system call?
291. print "\n";
292. return;
293. }
294. if ($split_cmd[0] eq 'usr' or $split_cmd[0] eq 'user') { 
295. print "Username: ";
296. $usr = <STDIN>;
297. chomp $usr;
298. return;
299. }
300. }
301. return;
302. }
303. ### use_cmd - Set which database we are using
304. # Alias's: usedb
305. # TODO: Unknown
306. sub use_cmd {
307. my @split_cmd = split(" ", shift);
308. if (@split_cmd)
309. {
310. if ($split_cmd[0] eq '') { 
311. print "Invalid name for database.\n";
312. return 0;
313. }
314. else {
315. $db = $split_cmd[0];
316. print "Database successfully changed to " . $db . "\n";
317. return;
318. }
319. }
320. }
321. ### show_cmd - Show all variables for built in commands
322. # TODO: Same as set_cmd, possibly use an env variables type setup
323. sub show_cmd {
324. my @split_cmd = split(" ", shift);
325. if (@split_cmd)
326. {
327. if ($split_cmd[0] eq 'db' or $split_cmd[0] eq 'database' or $split_cmd[0] eq 'dbase') {
328. print $db . "\n";
329. return;
330. }
331. if ($split_cmd[0] eq 'user' or $split_cmd[0] eq 'usr' or $split_cmd[0] eq 'who') {
332. print $usr . "\n";
333. return;
334. }
335. if ($split_cmd[0] eq 'version' or $split_cmd[0] eq 'v' or $split_cmd[0] eq 'V') { 
336. print $version . "\n";
337. return;
338. }
339. if ($split_cmd[0] eq 'help') { 
340. help();
341. }
342. else { 
343. print "Error: " . $split_cmd[0] . " not yet implemented for command: \"show\"\n";
344. return;
345. }
346. }
347. }

Download the File By Clicking HERE

Coded in PHP