File Coverage

blib/lib/WWW/URLToys.pm
Criterion Covered Total %
statement 87 1796 4.8
branch 54 746 7.2
condition 1 8 12.5
subroutine 10 80 12.5
pod 5 73 6.8
total 157 2703 5.8


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             # ********************************************************
4             # URLToys, Perl-style and command-line driven by Joe Drago
5             # Now URLToys.pm, the Perl Module!
6             #
7             # Version 1.28 - Updated 6/19/2004
8             #
9             # The ChangeLog is at the end of the documentation.
10             # ********************************************************
11              
12             # Copyright (c) 2004, Joe Drago
13             # All rights reserved.
14              
15             # See the POD (Documentation) for all of the specifics.
16              
17             =pod
18              
19             =head1 NAME
20              
21             WWW::URLToys - gather and download URLs from URLs
22              
23             =head1 SYNOPSIS
24              
25             use WWW::URLToys qw/:DEFAULT ut_command_loop/;
26             my @utlist;
27             $SIG{'INT'} = 'ut_stop_download';
28             if(@ARGV > 0)
29             {
30             my $initial_command = join ' ',@ARGV;
31             ut_exec_command($initial_command,\@utlist);
32             };
33             ut_command_loop(*STDIN,\@utlist);
34              
35             =head1 DESCRIPTION
36              
37             WWW::URLToys is a separation of the program URLToys into its core code (this
38             module), and the programs that use it (urltoys and urltoysw). This module has
39             been made available via CPAN to allow others to use URLToys commands on their
40             Perl arrays, and to create interfaces for URLToys that far surpass those of
41             the original creator.
42              
43             =head1 METHODS
44              
45             =head2 ut_exec_command
46              
47             @result = ut_exec_command("make",\@somearray);
48              
49             Exported by default, this command runs any single URLToys command on a list,
50             and returns the list that the command would expect it to return.
51              
52             =head2 ut_command_loop
53              
54             ut_command_loop($filepointer,\@list);
55              
56             This will execute a string of commands from any file pointer. If the file
57             pointer is the standard input, it will prompt the user to type in commands
58             with the URLToys command prompt.
59              
60             =head2 ut_stop_download
61              
62             ut_stop_download();
63              
64             This command will stop a download. Useful for stopping a command while inside
65             a callback or Tk callback (if you use a GUI).
66              
67             =head2 loadconfig
68              
69             loadconfig("filename");
70              
71             Loads a URLToys configuration from a file.
72              
73             =head2 saveconfig
74              
75             saveconfig("filename");
76              
77             Saves the current URLToys configuration to a file.
78              
79             =head1 CALLBACKS
80              
81             All callbacks are set via the %ut_callback hash. Setting any of the keywords
82             for the callbacks to a sub of your own, you override the callback and receive
83             it instead. All of them are sent 3 variables: which callback, value1, and
84             value2.
85              
86             An example:
87              
88             sub print_text { my ($type,$text,$ignored) = @_; print $text; };
89             $ut_callback{'print'} = \&print_text;
90              
91             Here is a list of them:
92              
93             Callback Description Calls by Default Value 1 Value 2
94             print Called with the 'print' command cb_tty text to print Ignored
95             extra Things that can safely be ignored cb_tty text to print Ignored
96             help Syntax Help cb_tty text to print Ignored
97             error Error Messages cb_tty text to print Ignored
98             action Explains the current action cb_ignore Current action text Ignored
99             makeupdate Text explaining what 'make' is doing cb_tty text to print Ignored
100             dlbeat Sent when download of unknown size gets data cb_dlbeat Ignored Ignored
101             dlupdate Text explaining what 'get' is doing cb_tty text to print Ignored
102             output Regular output Text by program cb_tty text to print Ignored
103             title Sets the title of the window cb_title text for window title Ignored
104             warnuser BADFLUX: Returns 1 on allow, 0 on no allow cb_warnuser ref to array of bad cmds Ignored
105             variable Updates a variable to the main script cb_ignore variable name value of variable
106             complete When a get or resume finishes cb_ignore directory that finished Ignored
107             begin When a get or resume starts cb_ignore directory its coming to Ignored
108              
109             The return value of the callbacks are ignored except the "warnuser" one, which
110             is to warn a user on a potentially bad flux. It's very important that this
111             returns a 0 if the user does not wish to run the flux! You must override this
112             if you create a GUI flux. Please see urltoysw for an example.
113              
114             =head1 VARIABLES
115              
116             $config_file
117             $config_useragent
118             $config_ext_regex
119             $config_ext_ignore
120             $config_custom_headers
121             $config_href_regex
122             $config_img_regex
123             $config_prompt
124             $config_name_template
125             $config_save_url_list
126             $config_explain_regex_error
127             $config_useundo
128             $config_use_xttitle
129             $config_pausetime
130             $config_downloaddir
131             $config_dirslashes
132             $config_seq_warning_size
133             $config_proxy
134              
135             These are all given by the EXPORT tag "configvars", except $config_file, which is
136             exported by default.
137              
138             =head1 Undocumented
139              
140             As of yet the actions returned by the action callback, and the variables set by the
141             'variable' callback are undocumented.
142              
143             =cut
144              
145              
146             package WWW::URLToys;
147              
148 1     1   883 use strict;
  1         2  
  1         56  
149              
150             # Standard Perl denotation for Version
151             our $VERSION = "1.28";
152              
153             # How URLToys refers to its Version
154             my $URLTOYS_VERSION = "URLToys Version 1.28 (6/19/2004)";
155              
156 1     1   5 use Exporter;
  1         1  
  1         148  
157              
158             our @ISA = qw/Exporter/;
159              
160             our @EXPORT = qw/
161             ut_exec_command
162             %ut_callback
163             ut_stop_download
164             $ut_get_dir
165             $urltoys_dir
166             /;
167              
168             our @EXPORT_OK = qw/
169             $VERSION
170             $URLTOYS_VERSION
171              
172             ut_command_loop
173             ut_getlinks_array
174              
175             $ut_term
176             ut_getnextline
177              
178             loadconfig
179             saveconfig
180              
181             $config_file
182             $config_useragent
183             $config_ext_regex
184             $config_ext_ignore
185             $config_custom_headers
186             $config_href_regex
187             $config_img_regex
188             $config_prompt
189             $config_name_template
190             $config_save_url_list
191             $config_explain_regex_error
192             $config_useundo
193             $config_use_xttitle
194             $config_pausetime
195             $config_downloaddir
196             $config_dirslashes
197             $config_seq_warning_size
198             $config_proxy
199             /;
200              
201             our %EXPORT_TAGS = (configvars => [
202             qw/
203             $config_file
204             $config_useragent
205             $config_ext_regex
206             $config_ext_ignore
207             $config_custom_headers
208             $config_href_regex
209             $config_img_regex
210             $config_prompt
211             $config_name_template
212             $config_save_url_list
213             $config_explain_regex_error
214             $config_useundo
215             $config_use_xttitle
216             $config_pausetime
217             $config_downloaddir
218             $config_dirslashes
219             $config_seq_warning_size
220             $config_proxy
221             /]);
222              
223              
224             # libwww for Perl ... the heart of URLToys
225 1     1   886 use LWP;
  1         74189  
  1         36  
226              
227             # Used by the 'cookies' command
228 1     1   905 use HTTP::Cookies;
  1         8472  
  1         32  
229              
230             # Used to help parse out a few things and make the URL pretty
231 1     1   778 use URI::URL;
  1         4873  
  1         133  
232              
233             # Used in the command line version, unless sufficiently hooked
234              
235             my $using_tk = (exists $INC{'Tk.pm'});
236              
237             unless($using_tk)
238             {
239             require Term::ReadLine;
240             import Term::ReadLine /new/;
241              
242             # Otherwise Windows complains
243             $Term::ReadLine::termcap_nowarn = 1;
244             }
245              
246             # Used by the 'password' command
247 1     1   849 use MIME::Base64;
  1         788  
  1         58  
248              
249             # Used throughout the code, most notably with 'pwd' and 'cwd'
250 1     1   6 use Cwd;
  1         2  
  1         30547  
251              
252             # Built-in Help Text ... YES THIS IS UGLY!
253              
254             my %helplines = (
255             add => "This adds URL to the end of the list. Example:\nadd http://www.example.com/",
256             append => "Loads a list without clearing current list, i.e.\nappend somefile.txt",
257             autorun => "The heart of .flux is 'autorun'. This command executes a flux file.\n\nautorun somefile.flux",
258            
259             batch => "Starts a batch session. It'll ask you for URLs until you type 'end', then\nit will perform whatever command you typed after the batch command, i.e.\n\nbatch fusker\n[batch][0] http://www.example.com/[01-10].jpg\n[batch][2] end\n\n... is like typing \"fusker http://www.example.com/[01-10].jpg\". \nSee docs for more details.",
260            
261             batchcurrent => "Like batch, but instead of asking for a list, it'll use the current list.\n\nSee batch.",
262             cd => "Changes current directory.",
263              
264             config => "Either shows, loads, or saves the configuration to the standard file. Possibilities:\n\nconfig show\nconfig save\nconfig show\n\nSee docs for details.",
265              
266             clear => "Clears the screen.",
267             cls => "Clears the screen.",
268             cookies => "Turns on the usage of cookies when talking to a web server.\nThe cookies will be maintained across\nmultiple conversations for the duration of the program.\n\ncookies\ncookies on\ncookies off\ncookies clear",
269             del => "Deletes list entries that match a regular expression. For example:\n\ndel urltoys\n\n...will delete all URLs with the word 'urltoys' in it.\n\nSee docs for more info.",
270             flux => "The heart of .flux is 'autorun'. This command executes a flux file.\n\nflux somefile.flux",
271            
272             keep => "Just like the del command, only it keeps the matching lines other than\nremoving them. See the docs or the 'del' help.",
273              
274             delh => "Deletes the first N lines of a list.\n\ndelh 10",
275             keeph => "Keeps only the first N lines of a list.\n\nkeeph 10",
276             delt => "Deletes the last N lines of a list.\n\ndelt 10",
277             keept => "Keeps only the last N lines of a list.\n\nkeept 10",
278             exit => "Exits URLToys immediately.",
279            
280             fixparents => "Fixes parent-ridden URLs. Turns URLs from:\n\nhttp://www.example.com/a/../1.jpg\nto\nhttp://www.example.com/1.jpg\n",
281              
282             fusker => "Create list from fusker string.\n\nSee documentation.",
283             fusk => "Create list from fusker string.\n\nSee documentation.",
284             get => "Downloads list (with optional size requirement)\n\nget\nget +100k\nget -1000k\n\nSee docs.",
285             header => "Adds a custom header to all conversations.\n\nheader Referer: http://www.somesite.url/\nheader Authorization: Basic ...\nheader -d Referer",
286             help => "Shows the command list, or detailed help for a command.\n\nhelp\nhelp [commandname]",
287             h => "Shows the command list, or detailed help for a command.\n\nhelp\nhelp [commandname]",
288            
289             history => "Queries the command history. You can view, save, or clear the\ncommand history.\n\nhistory show\nhistory save somefile.txt\nhistory clear",
290              
291             keepuni => "Removes all entries listed more than once, INCLUDING the first one. This\ndiffers from nodupes because nodupes keeps at least one copy.",
292              
293             lip => "Keep only last numbered URL in a series.\n\nSee Docs.",
294             load => "Loads a URL list from a file.\n\nload somefile.txt",
295            
296             make => "Generates a list of URLs, based on an optional custom regex.\nBy default, make uses the built-in href regex.\n\nmake\nmake someregex\n\nSee docs.",
297            
298             href => "Generates a list of URLs, using the regular link finding regex.",
299             hrefimg => "Generates a list of URLs, using the regular link finding regex\nand the IMG tag regex at the same time.",
300             img => "Generates a list of URLs, using the IMG tags from the HTML pages.",
301             makeregex => "Forces URLToys to only process the URLs matching this regex.\n\nSee the documentation!",
302             needparam => "This is for script creation.\nSee the documentation.",
303             nodupes => "Removes all duplicate entries from the list, leaving only the originals.",
304             nsort => "Sorts list, being careful to count the last number properly.\n\nSee sort as another possibility.",
305             password => "Add username/password combo for a site.\n\npassword [domain] [username] [password]",
306             pwd => "Prints the current working directory.",
307             resume => "Resumes a partially downloaded list. You give it the directory its in:\n\nresume 00005\nresume someothername",
308             save => "Save the list to a file.\n\nsave somefile.txt",
309             saveflux => "Save the list to a flux file by attempting to combine as many lines as possible into fusker lines.\n\nsaveflux somefile.flux",
310             spider => "Takes a parent URL and runs through all sub-URLs of that URL,\nfinding all IMG and A tags. \n\nspider",
311             system => "Executes a system command.\n\nsystem dir\nsystem del somefile.txt",
312             systemw => "Executes a system command, but only if in Windows.\n\nsystemw dir\nsystemw del somefile.txt",
313             systemu => "Executes a system command, but only if in Unix/OSX.\n\nsystemu dir\nsystemu del somefile.txt",
314             seq => "Build from numerical sequence.\n\nSee the documentation on this one.",
315             zeq => "Build from numerical sequence.\n\nSee the documentation on this one.",
316             set => "Sets configuration variables.\nYou can see all variables by typing 'set' alone.\n\nset\nset SomeVariable=SomeValue",
317             show => "Shows the current URL list in its entirety,\nor just those matching a regex.",
318             list => "Shows the current URL list in its entirety,\nor just those matching a regex.",
319             ls => "Shows the current URL list in its entirety,\nor just those matching a regex.",
320            
321             size => "Asks the web servers about each URL for their size, then\nonly keeps those in your size range.\n\nsize +100k\nsize -1000k\n\nSee the documentation.",
322            
323             head => "Shows the beginning N URLs of the list.\n\nhead 10",
324             tail => "Shows the last N URLs of the list.\n\ntail 10",
325             print => "Writes text to the screen.\nUsually used in scripts.\n\nprint Hello World!",
326             replace => "Replaces text with new text.\nUse rreplace for regex replacement, or\nstrip to replace with nothing.\n\nreplace thisword withthisone",
327             rreplace => "Replaces text with new text.\nUse replace or strip for nonregex replacement.\n\nrreplace /someregex/somevalue/",
328             sort => "Sorts the list, using Perl's built-in sort.\nSee nsort for another possibility.",
329             strip => "Strips unwanted text from all URLs in the list.\n\nstrip thistextout",
330             title => "Sets the title bar of the program. Used in scripts usually.",
331             u => "Undoes the last list-changing command.",
332             undo => "Undoes the last list-changing command.",
333             version => "Shows the version number, which happens to be:\n\n$URLTOYS_VERSION\n\nHA! RUINED THAT FOR YOU!",
334             );
335              
336              
337             # **** GLOBAL INITS ***********************
338              
339             our $urltoys_dir = $ENV{"HOME"} . "/.urltoys";
340             our $config_file = $ENV{"HOME"} . "/.urltoys/config";
341              
342             # These are the globals that can be saved to the config, and set with "set"
343             our $config_useragent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)";
344             our $config_ext_regex = "htm|html|exe|php|cgi|pl|shtml|asp|pl|cgi|stm|jsp";
345             our $config_ext_ignore = "jpe?g|gif|png|tga|mov|avi|mpe?g|rm|bmp|mp3|ogg|wav|exe";
346             our $config_custom_headers = 'Referer: %URL';
347             our $config_href_regex = qr/[Hh][Rr][Ee][Ff]='?"?([^'"<>]+)/;
348             our $config_img_regex = qr/[Ss][Rr][Cc]='?"?([^'"<>]+)/;
349             our $config_prompt = 'URLToys (%COUNT)> ';
350             our $config_name_template = '%COUNT-%NAME';
351             our $config_save_url_list = 1;
352             our $config_explain_regex_error = 0;
353             our $config_useundo = 1;
354             our $config_use_xttitle = 0;
355             our $config_pausetime = 0;
356             our $config_downloaddir = "";
357             our $config_dirslashes = "/";
358             our $config_seq_warning_size = 5000;
359             our $config_proxy = "";
360              
361             # If this is set, the next 'get' will use this instead of enumerating
362             our $ut_get_dir = "";
363              
364             my $temp_dl_ext = ".utdl";
365              
366             my $fluxvarupdate = 0;
367             my $fluxlines = 0;
368              
369             # NEVER CHANGE THIS! Warnings are good.
370             my $warn_on_autorun = 1;
371              
372             # Used for animating the bar on an unknown length
373             my $animate_pulse = 0;
374             my $animate_add = 10;
375              
376             # Match anything by default
377             my $makeregex = ".*";
378              
379             # From 1.15: The password hash. $passwords{domain} = base64 encoded user/pass;
380             my %passwords;
381              
382             # "The" command history (as of 1.13)
383             my @history = ();
384             my $pulledfromundo = "";
385             my $fromstdin = 0;
386              
387             my $loop_readptr = *STDIN;
388              
389             # Added 1.08
390             my @undolist = ();
391              
392             # Used when downloading a file ... callbacks plus recursion = fun!
393             my $stop_getting_links;
394             my $current_file;
395             my $current_k;
396             my $download_count;
397             my $download_total;
398             my $dir;
399              
400             my $badsize;
401             my $dlsize;
402              
403             my $file_complete;
404             my $resume_spot;
405              
406             # Version 1.24 ... for 'header' command
407             my %headers = ();
408              
409             sub KEEPALIVECOUNT() { 10 };
410              
411             # Used for custom command parameters .. an array of array refs
412             my @params;
413              
414             # Cookie support, very special use
415             my $use_cookies = 0;
416             my $cookies = HTTP::Cookies->new;
417              
418             my @current_action = ('idle'); # Used like a stack
419              
420             # Makes my stuff "pipin' hot", AKA no buffering... otherwise that whole "command prompt" would suck.
421             $| = 1;
422              
423             our ($ut_term,$OUT);
424             $ut_term = 0;
425              
426             sub createterm
427             {
428 0 0   0 0 0 unless($using_tk)
429             {
430             # Moved to global in 1.22 to fix Segfaults in Linux
431 0         0 $ut_term = new Term::ReadLine "URLToys";
432 0   0     0 $OUT = $ut_term->OUT || \*STDOUT;
433 0         0 $ut_term->ornaments(0);
434             }
435             }
436              
437             # Version 1.10 Win32 Detection
438             my $win32 = 0;
439             $win32 = 1 if($^O =~ m/Win/);
440              
441             our %ut_callback = (
442             output => \&cb_tty,
443             print => \&cb_tty,
444             help => \&cb_tty,
445             error => \&cb_tty,
446             extra => \&cb_tty,
447            
448             makeupdate => \&cb_tty,
449             dlupdate => \&cb_tty,
450            
451             title => \&cb_title,
452            
453             dlbeat => \&cb_dlbeat,
454            
455             warnuser => \&cb_warnuser,
456            
457             action => \&cb_ignore,
458             endaction => \&cb_ignore,
459             variable => \&cb_ignore,
460             begin => \&cb_ignore,
461             complete => \&cb_ignore,
462             );
463              
464             # **** CALLBACK FUNCTIONS *********************
465              
466             # This is a cb that is called when the downloader has no idea how large the content is
467             sub cb_dlbeat
468             {
469 0     0 0 0 my ($type,$text,$ignored) = @_;
470 0         0 print "*";
471 0         0 return 0;
472             }
473              
474             # This is the default callback for when the window's Title needs to be set
475             sub cb_title
476             {
477 0     0 0 0 my ($type,$text,$ignored) = @_;
478 0 0       0 set_title_bar($text) if($config_use_xttitle);
479             }
480              
481             # This is for cb's that are ignored by default, but can be overridden
482             sub cb_ignore
483             {
484 0     0 0 0 my ($type,$text,$ignored) = @_;
485 0         0 return 0;
486             }
487              
488             # Generic printing callback
489             sub cb_tty
490             {
491 1     1 0 2 my ($type,$text,$ignored) = @_;
492 1         23 print $text;
493 1         3 return 0;
494             }
495              
496             # Generic warning ... please override for a GUI app with a suitable Tk version
497             sub cb_warnuser
498             {
499 0     0 0 0 my ($type,$warnlist,$ignored) = @_;
500              
501 0 0       0 return 1 unless($warn_on_autorun);
502              
503 0         0 print "*******************************************************************\n";
504 0         0 print "* WARNING !!!\n";
505 0         0 print "* These are potentially dangerous commands in this script:\n* --\n";
506              
507 0         0 foreach my $cmd (@$warnlist)
508             {
509 0         0 chomp($cmd);
510 0         0 print "* $cmd\n";
511             }
512              
513 0         0 print "* --\n";
514 0         0 print "* If you understand what these lines do, and trust the \n";
515 0         0 print "* source of the .flux file, say yes. Otherwise, say no, and\n";
516 0         0 print "* contact the creator of this file for an explanation.\n";
517 0         0 print "* IF YOU SAY YES AND YOUR MACHINE IS COMPROMISED -- BLAME YOURSELF\n";
518 0         0 print "*******************************************************************\n\n";
519              
520 0         0 my $prompt = "Would you like to run this script? ['yes' or 'no'] ";
521              
522 0         0 while(1)
523             {
524 0         0 my $text = ut_getnextline(*STDIN,$prompt);
525 0 0       0 return 0 if($text =~ m/^no$/i);
526 0 0       0 return 1 if($text =~ m/^yes$/i);
527             };
528              
529 0         0 return 0;
530             }
531              
532             # Callback wrapper for the rest of the module
533             sub cb
534             {
535 1     1 0 3 my ($which, $v1,$v2) = @_;
536 1         2 return &{$ut_callback{$which}}($which,$v1,$v2);
  1         5  
537             }
538              
539             # **** ACTION STATEMENTS **********************
540              
541             sub setaction
542             {
543 0     0 0 0 my $action = shift;
544 0         0 unshift @current_action, $action;
545 0         0 cb('action',$action,0);
546             }
547              
548             sub endaction
549             {
550 0     0 0 0 my $oldaction = shift @current_action;
551            
552             # A failsafe
553 0 0       0 @current_action = ('idle') if(@current_action < 1);
554              
555 0         0 my $action = $current_action[0];
556 0         0 cb('endaction',$oldaction,0);
557 0         0 cb('action',$action,0);
558             }
559              
560             # **** CONFIG FUNCTIONS ***********************
561              
562             # Takes a line like "UserAgent=Someone" and sets the proper $config
563             sub handleconfigline
564             {
565 0     0 0 0 my $which = shift;
566 0         0 my $what = shift;
567              
568 0         0 chomp($what);
569 0         0 $what =~ s/\r+$//;
570              
571 0 0       0 $config_useragent = $what if($which =~ /^useragent$/i);
572 0 0       0 $config_ext_regex = $what if($which =~ /^extensionregex$/i);
573 0 0       0 $config_ext_ignore = $what if($which =~ /^extensionignore$/i);
574 0 0       0 $config_custom_headers = $what if($which =~ /^customheaders$/i);
575 0 0       0 $config_href_regex = $what if($which =~ /^hrefregex$/i);
576 0 0       0 $config_img_regex = $what if($which =~ /^imgregex$/i);
577 0 0       0 $config_prompt = $what if($which =~ /^prompt$/i);
578 0 0       0 $config_name_template = $what if($which =~ /^nametemplate$/i);
579 0 0       0 $config_save_url_list = $what if($which =~ /^SaveURLList$/i);
580 0 0       0 $config_explain_regex_error = $what if($which =~ /^ExplainRegexError$/i);
581 0 0       0 $config_useundo = $what if($which =~ /^UseUndo$/i);
582 0 0       0 $config_use_xttitle = $what if($which =~ /^UseXTTitle$/i);
583 0 0       0 $config_pausetime = $what if($which =~ /^PauseTime$/i);
584 0 0       0 $config_downloaddir = $what if($which =~ /^DownloadDir$/i);
585 0 0       0 $config_dirslashes = $what if($which =~ /^DirSlashes$/i);
586 0 0       0 $config_seq_warning_size = $what if($which =~ /^SeqWarningSize$/i);
587 0 0       0 $config_proxy = $what if($which =~ /^Proxy$/i);
588             }
589              
590             sub loadconfig
591             {
592 0     0 1 0 my $configfile = shift;
593              
594 0 0       0 if (-e $configfile)
595             {
596 0         0 open(CONFIG,$configfile);
597 0         0 CONFIGLOOP: while()
598             {
599 0 0       0 next CONFIGLOOP if /^#/;
600            
601 0 0       0 if(m/^([^=]+)=(.*)$/)
602             {
603 0         0 my $which = $1;
604 0         0 my $what = $2;
605              
606 0         0 handleconfigline($which,$what);
607             }
608             }
609 0         0 close(CONFIG);
610             }
611             }
612              
613             sub saveconfig
614             {
615 0     0 1 0 my $filename = shift;
616 0         0 my $print_config_file = shift;
617              
618 0 0       0 open(CONFIGFILE,"> $filename") or return;
619              
620 0         0 print CONFIGFILE "UserAgent=$config_useragent\n";
621 0         0 print CONFIGFILE "ExtensionRegex=$config_ext_regex\n";
622 0         0 print CONFIGFILE "ExtensionIgnore=$config_ext_ignore\n";
623 0         0 print CONFIGFILE "CustomHeaders=$config_custom_headers\n";
624 0         0 print CONFIGFILE "HrefRegex=$config_href_regex\n";
625 0         0 print CONFIGFILE "ImgRegex=$config_img_regex\n";
626 0         0 print CONFIGFILE "Prompt=$config_prompt\n";
627 0         0 print CONFIGFILE "NameTemplate=$config_name_template\n";
628 0         0 print CONFIGFILE "SaveURLList=$config_save_url_list\n";
629 0         0 print CONFIGFILE "ExplainRegexError=$config_explain_regex_error\n";
630 0         0 print CONFIGFILE "UseUndo=$config_useundo\n";
631 0         0 print CONFIGFILE "UseXTTitle=$config_use_xttitle\n";
632 0         0 print CONFIGFILE "PauseTime=$config_pausetime\n";
633 0         0 print CONFIGFILE "DownloadDir=$config_downloaddir\n";
634 0         0 print CONFIGFILE "DirSlashes=$config_dirslashes\n";
635 0         0 print CONFIGFILE "SeqWarningSize=$config_seq_warning_size\n";
636 0         0 print CONFIGFILE "Proxy=$config_proxy\n";
637 0         0 close(CONFIGFILE);
638             }
639              
640             sub showconfig
641             {
642 0     0 0 0 my $filename = shift;
643 0         0 my $print_config_file = shift;
644              
645 0         0 cb('output',"UserAgent=$config_useragent\n",0);
646 0         0 cb('output',"ExtensionRegex=$config_ext_regex\n",0);
647 0         0 cb('output',"ExtensionIgnore=$config_ext_ignore\n",0);
648 0         0 cb('output',"CustomHeaders=$config_custom_headers\n",0);
649 0         0 cb('output',"HrefRegex=$config_href_regex\n",0);
650 0         0 cb('output',"ImgRegex=$config_img_regex\n",0);
651 0         0 cb('output',"Prompt=$config_prompt\n",0);
652 0         0 cb('output',"NameTemplate=$config_name_template\n",0);
653 0         0 cb('output',"SaveURLList=$config_save_url_list\n",0);
654 0         0 cb('output',"ExplainRegexError=$config_explain_regex_error\n",0);
655 0         0 cb('output',"UseUndo=$config_useundo\n",0);
656 0         0 cb('output',"UseXTTitle=$config_use_xttitle\n",0);
657 0         0 cb('output',"PauseTime=$config_pausetime\n",0);
658 0         0 cb('output',"DownloadDir=$config_downloaddir\n",0);
659 0         0 cb('output',"DirSlashes=$config_dirslashes\n",0);
660 0         0 cb('output',"SeqWarningSize=$config_seq_warning_size\n",0);
661 0         0 cb('output',"Proxy=$config_proxy\n",0);
662             }
663              
664             # *** UTILITY FUNCTIONS *********************************
665              
666             sub set_title_bar
667             {
668 0     0 0 0 my $text = shift;
669 0         0 system("xttitle \"$text\"");
670             }
671              
672             # Recursive mkdir, a modified code snippet from a newsgroup
673             sub makedir
674             {
675 0     0 0 0 my $Dir = shift;
676              
677 0         0 $Dir =~ s/\/$//;
678              
679 0 0       0 unless (-d $Dir)
680             {
681 0         0 my $Parent = $Dir;
682 0         0 $Parent =~ s/\/[^\/]+$//;
683            
684 0 0       0 makedir($Parent) unless $Parent eq '';
685 0         0 mkdir($Dir);
686             }
687             }
688              
689             # **** HELP FUNCTIONS ******************************************
690              
691             sub getcustomsyntax
692             {
693              
694 0     0 0 0 my $which = shift;
695              
696 0         0 my $filename = $ENV{"HOME"} . "/.urltoys/$which.u";
697              
698 0         0 my $helpline = '';
699              
700 0         0 my $commentptr;
701 0 0       0 if(open($commentptr,$filename))
702             {
703 0         0 my $temp = <$commentptr>;
704 0 0       0 $helpline = $1 if($temp =~ m/^#\s+(.*)$/);
705 0         0 close($commentptr);
706             }
707              
708 0         0 return $helpline;
709             }
710              
711             sub customcmdslist
712             {
713 0     0 0 0 my $customloc = $ENV{"HOME"} . "/.urltoys/*.u";
714 0         0 my @files = glob $customloc;
715 0         0 my @ret = ();
716              
717 0         0 for my $filename (sort @files)
718             {
719 0 0       0 if($filename =~ m/\/([^\/.]+)\.u$/i)
720             {
721 0         0 my $text = $1;
722 0         0 push @ret, $text;
723             }
724             }
725              
726 0         0 return @ret;
727             }
728              
729             # Printed when someone types in "help" or "h", or "help command"
730             sub helpsyntax
731             {
732 0     0 0 0 my $which = shift;
733              
734 0 0       0 if($which)
735             {
736 0 0       0 if($helplines{$which})
737             {
738 0         0 my $text = $helplines{$which};
739 0         0 $text =~ s/\n/\n\t/gis;
740 0         0 $text = "$which:\n\t" . $text . "\n\n";
741 0         0 cb('help',$text,0);
742             }
743             else
744             {
745 0         0 my $syntax = getcustomsyntax($which);
746 0 0       0 if($syntax)
747             {
748 0         0 my $text = $syntax;
749 0         0 $text =~ s/\n/\n\t/gis;
750 0         0 $text = "$which:\n\t" . $text . "\n\n";
751 0         0 cb('help',$text,0);
752             }
753             else
754             {
755 0         0 cb('error',"No help available for $which.\n",0);
756             }
757             }
758             }
759             else
760             {
761 0         0 my @ar = customcmdslist;
762 0         0 my @helplist = keys %helplines;
763 0         0 push @helplist, @ar;
764              
765 0         0 cb('help',"\nType \"help command\", where command is one of these words: \n\n",0);
766              
767             # The following code is in the Perl Cookbook ... thanks!
768             # Obviously it's been altered for callback-osity
769              
770 0         0 my ($item, $cols, $rows, $maxlen);
771 0         0 my ($mask, @data);
772              
773 0         0 $maxlen = 1;
774 0         0 for(sort @helplist) {
775 0         0 my $mylen;
776 0         0 s/\s+$//;
777 0 0       0 $maxlen = $mylen if (($mylen = length) > $maxlen);
778 0         0 push(@data, $_);
779             }
780              
781 0         0 $maxlen += 1; # to make extra space
782              
783             # determine boundaries of screen
784 0         0 $cols = 5;
785 0         0 $rows = int(($#data+$cols) / $cols);
786              
787             # pre-create mask for faster computation
788 0         0 $mask = sprintf("%%-%ds ", $maxlen-1);
789              
790             # now process each item, picking out proper piece for this position
791 0         0 my $outputline = '';
792              
793 0         0 for ($item = 0; $item < $rows * $cols; $item++) {
794 0         0 my $target = ($item % $cols) * $rows + int($item/$cols);
795 0 0       0 my $piece = sprintf($mask, $target < @data ? $data[$target] : "");
796 0 0       0 $piece =~ s/\s+$// if (($item+1) % $cols == 0); # don't blank-pad to EOL
797 0         0 $outputline .= $piece;
798 0 0       0 if (($item+1) % $cols == 0)
799             {
800 0         0 $outputline .= "\n";
801 0         0 cb('help',$outputline,0);
802 0         0 $outputline = '';
803             }
804             }
805              
806             # finish up if needed
807 0 0       0 if (($item+1) % $cols == 0)
808             {
809 0         0 $outputline .= "\n";
810 0         0 cb('help',$outputline,0);
811             }
812            
813 0         0 cb('help',"\nRead http://www.urltoys.com/pod.html\n\n",0);
814             }
815             }
816              
817             # Sets up the next download folder, and increments value in nextdir.txt
818             sub checkdir
819             {
820              
821 0     0 0 0 my $nextdirfile = open(NEXTDIR,"
822 0         0 my $current_folder = 0;
823            
824 0 0       0 if(defined $nextdirfile)
825             {
826 0         0 $current_folder = ;
827 0         0 close(NEXTDIR);
828             }
829              
830 0         0 my $nextdirfileout = open(NEXTDIR,">nextdir.txt");
831              
832 0 0       0 if(defined $nextdirfileout)
833             {
834 0         0 print NEXTDIR $current_folder+1;
835 0         0 close(NEXTDIR);
836             }
837              
838 0         0 $dir = sprintf("%.5d",$current_folder);
839 0         0 mkdir($dir);
840             }
841              
842              
843             # Turns:
844             # http://somesite.url/a/b/../1.jpg
845             # into
846             # http://somesite.url/a/1.jpg
847              
848             sub fixparents
849             {
850 0     0 0 0 my $url_list = shift;
851              
852 0         0 foreach my $url (@$url_list)
853             {
854 0 0       0 if($url =~ m!(http://[^/ ]+(?:/[^/]+)*/)(\.\./.+)!i)
855             {
856 0         0 my $urlclass = url $2;
857 0         0 $url = $urlclass->abs($1);
858             }
859             }
860             }
861              
862             # Added 1.07 -- This checks for a typo in a regex without crashing URLToys
863             sub test_regex
864             {
865 0     0 0 0 my $regex = shift;
866              
867 0 0       0 if(!$regex)
868             {
869 0         0 return 1;
870             }
871              
872 0         0 my $testtextforregex = "http://www.somesite.url/somefile.something";
873 0         0 my $testregex= '$testtextforregex =~ m/$regex/gis';
874              
875 0         0 eval $testregex;
876 0 0       0 if($@)
877             {
878 0 0       0 if($config_explain_regex_error)
879             {
880 0         0 cb('error',"Error parsing regex. Details:\n\t$@",0);
881             }
882             else
883             {
884 0         0 cb('error',"Error parsing regex. Please review it for errors and try again.\n",0);
885             }
886 0         0 return 0;
887             }
888              
889             # Its OK.
890 0         0 return 1;
891             }
892              
893             # *** LINK GRABBING / HTTP / DOWNLOADING FUNCTIONS ********
894              
895             # addcustomheaders will set up any HTTP::Request for usage
896             sub addcustomheaders
897             {
898 0     0 0 0 my($req,$url,$host) = @_;
899              
900 0         0 my %final_headers = ();
901              
902             # Add custom headers here
903 0         0 my @headerlist = split(/\|/,$config_custom_headers);
904              
905 0         0 foreach my $header (@headerlist)
906             {
907 0 0       0 if($header =~ /^(.+): (.+)$/)
908             {
909 0         0 my $which = $1;
910 0         0 my $what = $2;
911            
912 0         0 $final_headers{$which} = $what;
913             }
914             }
915              
916 0         0 my $domain = $host;
917 0         0 my $pwheader;
918            
919 0         0 for my $key (keys %passwords)
920             {
921 0 0       0 if($domain =~ m/$key/)
922             {
923 0         0 $pwheader = $passwords{$key};
924 0         0 last;
925             }
926             }
927              
928 0 0       0 if($pwheader)
929             {
930 0         0 $final_headers{"Authorization"} = "Basic $pwheader";
931             }
932              
933 0         0 foreach my $headercmdkey (keys %headers)
934             {
935             # The header command overrides any default headers
936 0         0 $final_headers{$headercmdkey} = $headers{$headercmdkey};
937             }
938              
939 0         0 foreach my $key (keys %final_headers)
940             {
941 0         0 my $a = $key;
942 0         0 my $b = $final_headers{$key};
943            
944             # Add other custom header variables here (and one other place)
945 0         0 $b =~ s/%URL/$url/;
946 0         0 $b =~ s/%DOMAIN/$host/;
947            
948 0         0 $req->header($a => $b);
949             }
950             }
951              
952             # Sets up proxy, turns on cookies if need be
953             sub setupagent
954             {
955 0     0 0 0 my $useragent = shift;
956            
957 0 0       0 $useragent->proxy('http',$config_proxy)
958             if(length $config_proxy > 0);
959              
960 0 0       0 $useragent->cookie_jar($cookies) if ($use_cookies);
961             }
962              
963             sub ext_and_parent
964             {
965 0     0 0 0 my $url = shift;
966 0         0 my $parent;
967             my $parent_abs;
968 0         0 my $extension;
969              
970 0 0       0 if($url =~ m/\/$/)
971             {
972 0         0 $parent = $url;
973 0         0 $extension = "";
974              
975 0 0       0 if($url =~ m/(http:\/\/[^\/]+).*$/i)
976             {
977 0         0 $parent_abs = $1;
978             }
979              
980             }
981             else
982             {
983 0 0       0 if($url =~ m/(http:\/\/.+\/)[^\/?]+\.([^\/?&]+)(\?[^\/]+)?/i)
984             {
985 0         0 $parent = $1;
986 0         0 $extension = $2;
987             }
988              
989 0 0       0 if($url =~ m/(http:\/\/[^\/]+).*$/i)
990             {
991 0         0 $parent_abs = $1;
992             }
993             }
994              
995 0         0 return ($parent,$parent_abs,$extension);
996             }
997              
998             sub SKIPEXT_HTML() { 0 };
999             sub SKIPEXT_NOTHTML() { 1 };
1000             sub SKIPEXT_IGNORED() { 2 };
1001              
1002             sub skipext
1003             {
1004 0     0 0 0 my $ext = shift;
1005 0         0 my $ret = SKIPEXT_HTML; # Dont skip by default
1006              
1007 0 0       0 unless($ext =~ m/$config_ext_regex/i)
1008             {
1009 0         0 $ret = SKIPEXT_NOTHTML;
1010             }
1011             else
1012             {
1013 0 0       0 if($ext =~ m/$config_ext_ignore/i)
1014             {
1015 0         0 $ret = SKIPEXT_IGNORED;
1016             }
1017             }
1018              
1019 0         0 return $ret;
1020             }
1021              
1022             # getlinks is the heart of all of of the "make" functions
1023              
1024             sub getlinks
1025             {
1026 0     0 0 0 my $useragent = shift;
1027 0         0 my $argurl = shift;
1028 0         0 my $regexarray = shift;
1029 0         0 my $count = shift;
1030 0         0 my $total = shift;
1031              
1032 0         0 my $parent;
1033             my $parent_abs;
1034              
1035 0         0 my $url_pieces = url $argurl;
1036 0         0 my @lines;
1037              
1038             # This will tack on the trailing slash if need be
1039 0         0 my $url = $url_pieces;
1040              
1041 0         0 my $extension;
1042 0         0 my $extension_allowed = 0;
1043              
1044             # Figure out the parent URL here
1045            
1046 0         0 ($parent,$parent_abs,$extension) = ext_and_parent($url);
1047              
1048 0 0       0 if($extension)
1049             {
1050 0         0 my $se = skipext($extension);
1051              
1052 0 0       0 if($se == SKIPEXT_NOTHTML)
    0          
1053             {
1054 0         0 cb('makeupdate',"Skipping ($count/$total) \"$url\". ($extension not HTML)\n",0);
1055 0         0 push(@lines,$url);
1056 0         0 return @lines;
1057             }
1058             elsif($se == SKIPEXT_IGNORED)
1059             {
1060 0         0 cb('makeupdate',"Skipping ($count/$total) \"$url\". ($extension ignored)\n",0);
1061 0         0 push(@lines,$url);
1062 0         0 return @lines;
1063             }
1064             }
1065              
1066 0         0 cb('makeupdate',"Searching ($count/$total) \"$url\"...",0);
1067            
1068 0         0 my $req = HTTP::Request->new(GET => $url);
1069              
1070 0         0 addcustomheaders($req,$url,$url_pieces->host);
1071              
1072 0         0 my $res = $useragent->request($req);
1073              
1074 0 0       0 if($res->is_success)
1075             {
1076 0         0 my $html = $res->content;
1077              
1078 0         0 for my $regex(@$regexarray)
1079             {
1080              
1081 0         0 while($html =~ m/$regex/gis)
1082             {
1083 0         0 my $link = $1;
1084              
1085 0 0       0 if($link =~ m/^\//)
1086             {
1087 0         0 $link = $parent_abs . $link;
1088             }
1089             else
1090             {
1091             # Tacks on the parent portion of the url for a relative link
1092 0 0       0 unless($link =~ m/^http:\/\//)
1093             {
1094             # These two lines will change things like "/a/b/../1.jpg" to "/a/1.jpg"
1095 0         0 my $tempurl = url $link;
1096 0         0 $link = $tempurl->abs($parent);
1097             }
1098             }
1099              
1100 0         0 push(@lines,$link);
1101             } # while
1102             } # for
1103              
1104             }
1105              
1106 0         0 my $foundlines = @lines . " found.\n";
1107 0         0 cb('makeupdate',$foundlines,0);
1108 0         0 return @lines;
1109             }
1110              
1111             sub ut_getlinks_array
1112             {
1113 0     0 0 0 my $list = shift;
1114 0         0 my $regexarray = shift;
1115              
1116 0         0 my @final_list;
1117             my $link;
1118              
1119 0         0 for my $regex(@$regexarray)
1120             {
1121 0 0       0 return @$list if(!test_regex($regex));
1122             }
1123              
1124 0         0 $stop_getting_links = 0;
1125              
1126 0         0 my $count = 0;
1127 0         0 my $total = @$list;
1128            
1129 0         0 my $useragent = LWP::UserAgent->new( keep_alive => KEEPALIVECOUNT);
1130 0         0 $useragent->agent($config_useragent);
1131 0         0 setupagent($useragent);
1132              
1133 0         0 foreach $link (@$list)
1134             {
1135 0 0       0 return @$list if($stop_getting_links);
1136              
1137 0         0 $count++;
1138 0         0 cb('title',"($count/$total) URLToys Finding Links...",0);
1139              
1140 0 0       0 if($link =~ m/$makeregex/)
1141             {
1142 0         0 cb('variable','dlcount',$count);
1143 0         0 cb('variable','dltotal',$total);
1144 0         0 cb('variable','dlk',0);
1145 0         0 cb('variable','dllen',0);
1146              
1147             # Simpler variables
1148 0 0       0 if($total > 0)
1149             {
1150 0         0 cb('variable','cp',(100*$count)/$total);
1151             }
1152             else
1153             {
1154 0         0 cb('variable','cp',0);
1155             }
1156 0         0 cb('variable','ct',"[Search ($count/$total) ] $link");
1157              
1158 0         0 my @sitelist = getlinks($useragent,$link,$regexarray,$count,$total);
1159              
1160 0 0       0 if(@sitelist > 0)
1161             {
1162 0         0 push @final_list, @sitelist;
1163             }
1164             }
1165             else
1166             {
1167             # Added Version 1.03 4/22/03 (Fixes makeregex bug)
1168 0         0 push @final_list,$link;
1169             }
1170             }
1171              
1172 0         0 return @final_list;
1173             };
1174              
1175             sub ut_stop_download
1176             {
1177 0     0 1 0 $stop_getting_links = 1;
1178             }
1179              
1180             # The interior of the downloading code ... draws the little % bar, writes data
1181             sub downloadfile_callback
1182             {
1183 0     0 0 0 my($data, $response, $protocol) = @_;
1184              
1185             # Believe it or not, this is the way to do it according to the docs
1186 0 0       0 die if ($stop_getting_links);
1187              
1188 0 0       0 if($response->is_success)
1189             {
1190              
1191 0 0       0 if($resume_spot > 0)
1192             {
1193 0 0       0 if($response->code != 206) # Partial Content
1194             {
1195             # The server didn't support the Range header,
1196             # so move to the beginning of the file and start over
1197            
1198 0         0 seek OUTPUT,0,0;
1199 0         0 truncate OUTPUT,0;
1200 0         0 $resume_spot = 0;
1201             }
1202             }
1203              
1204 0         0 my $length = $response->content_length;
1205              
1206 0 0       0 if($length < 1)
1207             {
1208 0         0 cb('dlbeat',0,0);
1209 0         0 cb('variable','dlcount',$download_count);
1210 0         0 cb('variable','dltotal',$download_total);
1211 0         0 cb('variable','dlk',0);
1212 0         0 cb('variable','dllen',0);
1213 0         0 cb('variable','dldir',$dir);
1214            
1215             # Simpler variables
1216              
1217 0         0 $animate_pulse = ($animate_pulse + $animate_add) % 100;
1218            
1219 0         0 cb('variable','cp',$animate_pulse);
1220 0         0 cb('variable','tp',(100*$download_count)/$download_total);
1221             }
1222             else
1223             {
1224 0 0       0 if(!goodsize($length,$dlsize))
1225             {
1226             # Doesn't match the good size
1227 0         0 $badsize = 1;
1228 0         0 cb('dlupdate',"\r[ Incorrect Size for DL ]",0);
1229 0         0 die;
1230             }
1231              
1232 0         0 my $dl_line = '';
1233              
1234 0         0 $dl_line = "\r[";
1235 0         0 $current_k += length($data);
1236              
1237 0         0 my $percentage = (25 * $current_k) / $length;
1238 0         0 my $total_percentage = (10 * $download_count) / $download_total;
1239 0         0 my $count = 0;
1240              
1241 0         0 while($count < $percentage)
1242             {
1243 0         0 $dl_line .= "*";
1244 0         0 $count++;
1245             }
1246              
1247 0         0 while($count < 25)
1248             {
1249 0         0 $dl_line .= "-";
1250 0         0 $count++;
1251             }
1252              
1253 0         0 $dl_line .= "] [ ${current_k}b of ${length}b | $download_count/$download_total (to $dir) ]";
1254            
1255 0         0 cb('dlupdate',$dl_line,0);
1256            
1257 0         0 cb('variable','dlcount',$download_count);
1258 0         0 cb('variable','dltotal',$download_total);
1259 0         0 cb('variable','dlk',$current_k);
1260 0         0 cb('variable','dllen',$length);
1261 0         0 cb('variable','dldir',$dir);
1262            
1263 0         0 cb('variable','cp',(100*$current_k)/$length);
1264 0         0 cb('variable','tp',(100*$download_count)/$download_total);
1265             }
1266              
1267 0         0 print OUTPUT $data;
1268              
1269 0 0       0 $file_complete = 1 if($current_k == $length);
1270            
1271             } #is_success
1272              
1273             } #downloadfile_callback
1274              
1275              
1276             # Called by download_file array ... downloads one file
1277             sub downloadfile
1278             {
1279             # $count is used as a unique number, created inside of downloadfile_array
1280            
1281 0     0 0 0 my $useragent = shift;
1282 0         0 my $url = shift;
1283 0         0 my $count = shift;
1284              
1285 0         0 cb('variable','url',$url);
1286              
1287             # Calculate filename
1288              
1289 0         0 my $base_filename = "unknown-name";
1290 0         0 my $domain = "unknown-domain";
1291 0         0 my $urldir = "";
1292 0         0 my $extension = "";
1293             # if($url =~ m/http:\/\/(?:[^\/]+\/)+(.+)(?:\?.*)?/i)
1294 0 0       0 if($url =~ m/http:\/\/([^\/]+)\/((?:[^\/]+\/)+)?(.+)(?:\?.*)?/i)
1295             {
1296 0         0 $domain = $1;
1297 0         0 $urldir = $2;
1298 0         0 $base_filename = $3;
1299             }
1300              
1301 0 0       0 if(length($base_filename) > 0)
1302             {
1303 0 0       0 if($base_filename =~ m/\.([^.]+)$/)
1304             {
1305 0         0 $extension = $1;
1306             }
1307             }
1308            
1309 0         0 my $countstr = sprintf("%.5d",$count);
1310            
1311 0         0 my $filename = $config_name_template;
1312              
1313 0         0 my $currentdir = cwd();
1314              
1315 0         0 my ($tsec, $tmin, $thour,
1316             $tday, $tmonth, $tyear,
1317             $tweekday, $tdoy, $tdst) = localtime(time);
1318            
1319 0         0 $tyear += 1900; # Fix the year
1320 0         0 my $t24hr = $thour;
1321 0 0       0 $thour -= 12 if($thour > 12);
1322              
1323             # Fix up the urldir, use DirSlashes too
1324 0 0       0 if($urldir)
1325             {
1326 0         0 $urldir =~ s/\/+$//;
1327 0         0 $urldir =~ s/^\/+//;
1328 0         0 $urldir =~ s/\//$config_dirslashes/g;
1329             }
1330              
1331 0         0 $filename =~ s/%DOMAIN/$domain/g;
1332 0         0 $filename =~ s/%DIR/$urldir/g;
1333              
1334 0         0 my $a = uc $extension;
1335 0         0 $filename =~ s/%CEXT/$a/g;
1336 0         0 $a = lc $extension;
1337 0         0 $filename =~ s/%LEXT/$a/g;
1338 0         0 $filename =~ s/%EXT/$extension/g;
1339              
1340 0         0 $filename =~ s/%DAY/$tday/g;
1341 0         0 $filename =~ s/%MONTH/$tmonth/g;
1342 0         0 $filename =~ s/%YEAR/$tyear/g;
1343              
1344 0         0 $filename =~ s/%24HR/$t24hr/g;
1345 0         0 $filename =~ s/%HOUR/$thour/g;
1346 0         0 $filename =~ s/%MIN/$tmin/g;
1347 0         0 $filename =~ s/%SEC/$tsec/g;
1348              
1349             # Add other NameTemplate variables here
1350 0         0 $filename =~ s/%COUNT/$countstr/;
1351 0         0 $filename =~ s/%NAME/$base_filename/;
1352              
1353 0         0 my $full_filename = "$dir/$filename";
1354              
1355             # Fix $full_filename
1356 0         0 $full_filename =~ s!//!/!g;
1357            
1358             # Added condition Version 1.04 for Resuming LISTS not FILES
1359 0 0       0 if(-e $full_filename)
1360             {
1361 0         0 cb('dlupdate',"Skipping $url... found $full_filename\n",0);
1362             }
1363             else
1364             {
1365             # Sets the globally downloading filename
1366 0         0 $current_file = $full_filename;
1367              
1368 0         0 $file_complete = 0;
1369            
1370 0         0 my $req = HTTP::Request->new('GET', $url);
1371              
1372 0         0 addcustomheaders($req,$url,$domain);
1373              
1374 0         0 $resume_spot = 0;
1375 0         0 my $openmode = ">";
1376              
1377             # New Resuming-file code
1378 0         0 my $dl_filename = $full_filename . $temp_dl_ext;
1379 0         0 $current_file = $dl_filename;
1380              
1381 0 0       0 if(-e $dl_filename)
1382             {
1383 0         0 my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) =
1384             stat $dl_filename;
1385              
1386 0         0 cb('dlupdate',"\rSizing $url for resume...",0);
1387 0         0 my $completesize = document_length($url);
1388              
1389 0 0       0 if($completesize < 1)
1390             {
1391 0         0 cb('dlupdate',"Cannot resume.\n",0);
1392 0         0 unlink $dl_filename;
1393             }
1394             else
1395             {
1396 0         0 $openmode = ">>"; # We're gonna be resuming
1397 0         0 $resume_spot = $size;
1398 0         0 $req->header("Range" => "bytes=$size-");
1399 0         0 cb('dlupdate',"\n",0);
1400             }
1401             }
1402              
1403             # Create any needed subdirectories
1404 0         0 my $dir_to_create = $full_filename;
1405 0         0 $dir_to_create =~ s/\/[^\/]+$//; # Strip off name
1406 0         0 makedir($dir_to_create);
1407            
1408 0 0       0 unless(open(OUTPUT,"$openmode $dl_filename"))
1409             {
1410 0         0 cb('error',"can't open output file. ($dl_filename)\n",0);
1411 0         0 return;
1412             }
1413              
1414 0         0 binmode OUTPUT;
1415 0         0 $current_k = 0;
1416              
1417 0 0       0 if($resume_spot > 0)
1418             {
1419 0         0 cb('dlupdate',"Resuming \"$url\"...\n",0);
1420             }
1421             else
1422             {
1423 0         0 cb('dlupdate',"Downloading \"$url\"...\n",0);
1424             }
1425              
1426 0         0 $badsize = 0;
1427 0         0 my $response = $useragent->request($req, \&downloadfile_callback, 4096);
1428 0         0 close(OUTPUT);
1429              
1430 0         0 my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) =
1431             stat $dl_filename;
1432              
1433             # Added 1.10
1434 0 0       0 if($size < 1) # Its nothing
    0          
1435             {
1436 0         0 unlink $dl_filename;
1437             }
1438             elsif($file_complete)
1439             {
1440 0         0 unlink $full_filename;
1441 0         0 rename $dl_filename,$full_filename;
1442             }
1443              
1444 0         0 cb('dlupdate',"\n",0);
1445             }
1446              
1447             # Moved here in 1.10
1448 0         0 $current_file = "";
1449             }
1450              
1451             # The wrapper for downloadfile, gets entire list
1452             sub downloadfile_array
1453             {
1454              
1455 0     0 0 0 my $list = shift;
1456              
1457 0         0 my @final_list;
1458             my $link;
1459 0         0 my $count = 0;
1460              
1461 0 0       0 if($ut_get_dir)
1462             {
1463             # This is an override for the Perl Module
1464 0         0 $dir = $ut_get_dir;
1465 0         0 $ut_get_dir = '';
1466 0         0 mkdir($dir);
1467             }
1468             else
1469             {
1470 0         0 checkdir;
1471             }
1472              
1473 0         0 cb('variable','dldir',$dir);
1474              
1475 0         0 $download_count = 0;
1476 0         0 $download_total = @$list;
1477              
1478 0 0       0 if($config_save_url_list)
1479             {
1480 0         0 my $url_list_filename = "$dir/url_list";
1481 0         0 open(URLLIST, "> $url_list_filename");
1482 0 0       0 unless(defined *URLLIST)
1483             {
1484 0         0 cb('error',"Cannot write to $url_list_filename\n",0);
1485 0         0 return;
1486             }
1487              
1488 0         0 print URLLIST "$_\n" for (@$list);
1489 0         0 close(URLLIST);
1490              
1491 0 0       0 if(keys %passwords > 0)
1492             {
1493 0         0 my $pw_list_filename = "$dir/pw_list";
1494 0         0 open(PWLIST, "> $pw_list_filename");
1495 0 0       0 unless(defined *PWLIST)
1496             {
1497 0         0 cb('error',"Cannot write to $pw_list_filename\n",0);
1498 0         0 return;
1499             }
1500              
1501 0         0 for my $key (sort keys %passwords)
1502             {
1503 0         0 print PWLIST $passwords{$key} . " " . "$key\n";
1504             }
1505 0         0 close(PWLIST);
1506             }
1507            
1508             # As of Version 1.24, the headers and config are saved too
1509              
1510 0 0       0 if(keys %headers > 0)
1511             {
1512 0         0 my $hd_list_filename = "$dir/hd_list";
1513 0         0 open(HDLIST, "> $hd_list_filename");
1514 0 0       0 unless(defined *HDLIST)
1515             {
1516 0         0 cb('error',"Cannot write to $hd_list_filename\n",0);
1517 0         0 return;
1518             }
1519              
1520 0         0 for my $key (sort keys %headers)
1521             {
1522 0         0 print HDLIST $key . ": " . $headers{$key} . "\n";
1523             }
1524 0         0 close(HDLIST);
1525             };
1526            
1527 0         0 saveconfig("$dir/cf_list",1);
1528             }
1529              
1530 0         0 cb('begin',$dir,0);
1531              
1532 0         0 my $useragent = LWP::UserAgent->new( keep_alive => KEEPALIVECOUNT);
1533 0         0 $useragent->agent($config_useragent);
1534 0         0 setupagent($useragent);
1535            
1536 0         0 $stop_getting_links = 0;
1537 0         0 foreach $link (@$list)
1538             {
1539 0 0       0 last if($stop_getting_links);
1540 0         0 $download_count++;
1541 0         0 cb('title',"($download_count/$download_total) URLToys Downloading...",0);
1542            
1543 0         0 cb('variable','cp',0);
1544 0         0 cb('variable','tp',(100*$download_count)/$download_total);
1545 0         0 cb('variable','ct',"$link");
1546 0         0 cb('variable','tt',"Downloading ($download_count/$download_total)...");
1547            
1548 0         0 downloadfile($useragent,$link,$count);
1549 0 0       0 if($config_pausetime)
1550             {
1551 0         0 cb('dlupdate',"Sleeping $config_pausetime seconds...\n",0);
1552 0         0 sleep $config_pausetime;
1553             }
1554 0         0 $count++;
1555             }
1556              
1557 0 0       0 cb('complete',$dir,0) unless($stop_getting_links);
1558             };
1559              
1560             # Added Version 1.04 4/24/2003
1561             sub resume_list
1562             {
1563 0     0 0 0 my $list_to_resume = shift;
1564              
1565 0         0 my @resumelist;
1566             my $link;
1567 0         0 my $count = 0;
1568              
1569 0         0 my $url_list_filename = "$list_to_resume/url_list";
1570              
1571 0 0       0 unless(-f $url_list_filename)
1572             {
1573 0         0 cb('dlupdate',"cannot resume $list_to_resume: $url_list_filename is missing.\n",0);
1574 0         0 return;
1575             }
1576              
1577 0         0 open(RESUMEFILE,"< $url_list_filename");
1578              
1579 0 0       0 unless(defined *resumefile)
1580             {
1581 0         0 cb('error',"cannot open $url_list_filename\n",0);
1582 0         0 return;
1583             }
1584              
1585 0         0 while()
1586             {
1587 0         0 my $url = $_;
1588 0         0 chomp($url);
1589 0         0 push @resumelist,$url;
1590             }
1591              
1592 0         0 my $pw_list_filename = "$list_to_resume/pw_list";
1593              
1594 0 0       0 if(-f $pw_list_filename)
1595             {
1596              
1597 0         0 open(PWFILE,"< $pw_list_filename");
1598              
1599 0 0       0 if(defined *PWFILE)
1600             {
1601 0         0 while()
1602             {
1603 0 0       0 if(/^(\S+)\s+(.*)$/)
1604             {
1605 0         0 my $b64 = $1;
1606 0         0 my $domain = $2;
1607 0         0 chomp($domain);
1608 0         0 $passwords{$domain} = $b64;
1609             }
1610             }
1611            
1612 0         0 close(PWFILE);
1613            
1614             } #if defined
1615              
1616             } # if -f
1617              
1618              
1619 0         0 my $hd_list_filename = "$list_to_resume/hd_list";
1620              
1621 0 0       0 if(-f $hd_list_filename)
1622             {
1623 0         0 open(HDFILE,"< $hd_list_filename");
1624              
1625 0 0       0 if(defined *HDFILE)
1626             {
1627 0         0 while()
1628             {
1629 0 0       0 if(/^([^: ]+): (.+)$/)
1630             {
1631 0         0 my $which = $1;
1632 0         0 my $what = $2;
1633 0         0 chomp($what);
1634 0         0 $headers{$which} = $what;
1635             }
1636             }
1637            
1638 0         0 close(HDFILE);
1639            
1640             } #if defined
1641              
1642             } # if -f
1643              
1644 0         0 my $cf_list_filename = "$list_to_resume/cf_list";
1645              
1646 0 0       0 if(-f $cf_list_filename)
1647             {
1648 0         0 loadconfig($cf_list_filename);
1649             } # if -f
1650              
1651 0         0 $dir = $list_to_resume;
1652            
1653 0         0 cb('variable','dldir',$dir);
1654 0         0 cb('begin',$dir,0);
1655              
1656 0         0 $download_count = 0;
1657 0         0 $download_total = @resumelist;
1658              
1659 0         0 my $useragent = LWP::UserAgent->new( keep_alive => KEEPALIVECOUNT);
1660 0         0 $useragent->agent($config_useragent);
1661 0         0 setupagent($useragent);
1662              
1663 0         0 $stop_getting_links = 0;
1664              
1665 0         0 foreach $link (@resumelist)
1666             {
1667 0 0       0 last if($stop_getting_links);
1668 0         0 $download_count++;
1669 0         0 cb('title',"($download_count/$download_total) URLToys Resuming Download...",0);
1670            
1671 0         0 cb('variable','cp',0);
1672 0         0 cb('variable','tp',(100*$download_count)/$download_total);
1673 0         0 cb('variable','ct',"$link");
1674 0         0 cb('variable','tt',"Downloading ($download_count/$download_total)...");
1675              
1676 0         0 downloadfile($useragent,$link,$count);
1677 0 0       0 if($config_pausetime)
1678             {
1679 0         0 cb('dlupdate',"Sleeping $config_pausetime seconds...\n",0);
1680 0         0 cb('variable','ct',"Sleeping $config_pausetime seconds...\n");
1681 0         0 cb('variable','cp',0);
1682 0         0 sleep $config_pausetime;
1683             }
1684 0         0 $count++;
1685             }
1686            
1687 0 0       0 cb('complete',$dir,0) unless($stop_getting_links);
1688             };
1689              
1690             sub spider
1691             {
1692 0     0 0 0 my $utlist = shift;
1693 0         0 my $prefix;
1694             my %seen;
1695 0         0 my @final;
1696              
1697 0         0 for(@$utlist)
1698             {
1699 0         0 $prefix = $_;
1700              
1701 0         0 $prefix =~ s/\/([^\/]+)$//;
1702              
1703 0         0 my @l = ();
1704 0         0 push @l, $_;
1705 0         0 $seen{$prefix} = 1;
1706              
1707 0         0 while(1)
1708             {
1709 0         0 $stop_getting_links = 0;
1710 0         0 ut_exec_command("hrefimg",\@l);
1711 0 0       0 return @$utlist if($stop_getting_links);
1712              
1713 0         0 my @newl = ();
1714            
1715 0         0 for my $u (@l)
1716             {
1717              
1718 0         0 $u =~ s/(#.*)?$//;
1719              
1720 0 0       0 next if($u =~ /^mailto/i);
1721 0 0       0 next if($u =~ /^nntp:\/\//i);
1722 0 0       0 if($u =~ /^ftp:\/\//i)
1723             {
1724 0         0 push @final,$u;
1725 0         0 $seen{$u} = 1;
1726 0         0 next;
1727             }
1728              
1729 0 0       0 unless($seen{$u})
1730             {
1731 0         0 $seen{$u} = 1;
1732 0         0 push @final,$u;
1733              
1734 0         0 my ($parent,$parent_abs,$extension) = ext_and_parent($u);
1735              
1736 0 0       0 if($extension)
1737             {
1738 0 0       0 unless(skipext($extension))
1739             {
1740 0 0       0 push @newl,$u if($u =~ m/^$prefix/);
1741             }
1742             }
1743             else
1744             {
1745 0 0       0 push @newl,$u if($u =~ m/^$prefix/);
1746             }
1747             }
1748             }
1749              
1750 0         0 @l = @newl;
1751 0 0       0 last if(@l < 1);
1752             }
1753              
1754             } # for
1755              
1756 0         0 return @final;
1757              
1758             }
1759              
1760             # *** LIST MANAGEMENT FUNCTIONS *************************
1761              
1762             # Added 1.09a
1763             sub replace
1764             {
1765 0     0 0 0 my ( $list, $tofind,$replacewith,$useregex) = @_;
1766              
1767 0 0       0 if($useregex)
1768             {
1769 0 0       0 return @$list if(!test_regex($tofind));
1770             }
1771             else
1772             {
1773 0         0 $tofind = quotemeta $tofind;
1774             }
1775              
1776             # Fixed 1.09b
1777 0         0 $_ =~ s/$tofind/$replacewith/g foreach(@$list);
1778              
1779 0         0 return @$list;
1780             }
1781              
1782             # ... AKA Strip
1783             sub replace_with_nothing
1784             {
1785 0     0 0 0 my ($list,$tofind,$useregex) = @_;
1786              
1787 0 0       0 if($useregex)
1788             {
1789 0 0       0 return @$list if(!test_regex($tofind));
1790             }
1791             else
1792             {
1793 0         0 $tofind = quotemeta $tofind;
1794             }
1795              
1796             # Fixed 1.09b
1797 0         0 $_ =~ s/$tofind// foreach(@$list);
1798              
1799 0         0 return @$list;
1800             }
1801              
1802             # Either deletes entries in a list by regex, or -doesn't- delete them
1803             # Version 1.02 redone from Saint Marck 4/21/03
1804             # Version 1.03a Removed and added back in with the /o removed
1805             sub keep_by_regex
1806             {
1807 0     0 0 0 my ( $list, $regex, $delete_instead ) = @_;
1808             # Added /i in 1.08b
1809 0 0       0 grep { $delete_instead ? !/$regex/i : /$regex/i } @$list;
  0         0  
1810             }
1811              
1812             sub document_length
1813             {
1814 0     0 0 0 my $url = shift;
1815 0         0 my $len = -1;
1816            
1817 0         0 my $req = HTTP::Request->new('HEAD', $url);
1818            
1819 0         0 my $url_pieces = url $url;
1820              
1821 0         0 addcustomheaders($req,$url,$url_pieces->host);
1822            
1823 0         0 my $useragent = LWP::UserAgent->new;
1824 0         0 $useragent->agent($config_useragent);
1825 0         0 setupagent($useragent);
1826              
1827 0         0 my $response = $useragent->request($req);
1828 0         0 my $templen = $response->header("Content-Length");
1829              
1830 0 0       0 $len = $templen if($templen > 0);
1831              
1832 0         0 return $len;
1833             }
1834              
1835             sub goodsize
1836             {
1837 0     0 0 0 my($len,$typedsize) = @_;
1838              
1839 0         0 my $comparison = '+';
1840 0         0 my $size = 0;
1841 0         0 my $unit = 'b';
1842            
1843 0         0 my $k = int($len / 1024);
1844              
1845 0         0 my $good = 0;
1846              
1847 0 0       0 if($typedsize =~ /\s*([-+]?)(\d+)([kKbB]?)\s*/)
1848             {
1849 0         0 my($tcomp,$tsize,$tunit) = ($1,$2,$3);
1850 0 0       0 $comparison = '-' if($tcomp eq '-');
1851 0         0 $size = $tsize;
1852 0 0       0 $unit = 'k' if ($tunit =~ m/^k$/i);
1853             }
1854              
1855 0 0       0 if($comparison eq '-')
1856             {
1857             # Less Than
1858 0 0       0 if($unit eq 'k')
1859             {
1860 0 0       0 $good=1 if($k <= $size);
1861             }
1862             else
1863             {
1864 0 0       0 $good=1 if($len <= $size);
1865             }
1866             }
1867             else
1868             {
1869             # Greater Than
1870 0 0       0 if($unit eq 'k')
1871             {
1872 0 0       0 $good=1 if($k >= $size);
1873             }
1874             else
1875             {
1876 0 0       0 $good=1 if($len >= $size);
1877             }
1878             }
1879            
1880 0         0 return $good;
1881             }
1882              
1883             sub keep_by_size
1884             {
1885 0     0 0 0 my ($list, $typedsize ) = @_;
1886 0         0 $stop_getting_links = 0;
1887              
1888             # Default is to allow anything larger than 0 bytes
1889              
1890 0         0 my @retlist = ();
1891              
1892 0         0 for my $entry (@$list)
1893             {
1894 0 0       0 if($stop_getting_links)
1895             {
1896 0         0 return @$list;
1897             }
1898            
1899 0         0 cb('dlupdate',"Sizing ${entry}...",0);
1900            
1901 0         0 my $len = document_length($entry);
1902 0 0       0 if($len == -1)
1903             {
1904 0         0 cb('dlupdate',"[? Keep ?]\n",0);
1905 0         0 push @retlist,$entry;
1906             }
1907             else
1908             {
1909 0         0 my $k = int($len / 1024);
1910 0         0 my $keep = 0;
1911            
1912 0         0 cb('dlupdate',"${k}k",0);
1913              
1914 0 0       0 if(goodsize($len,$typedsize))
1915             {
1916 0         0 push @retlist,$entry;
1917 0         0 cb('dlupdate'," [ Keep ]\n",0);
1918             }
1919             else
1920             {
1921 0         0 cb('dlupdate'," [ Del ]\n",0);
1922             }
1923             }
1924             }
1925              
1926 0         0 return @retlist;
1927             }
1928              
1929             sub removedupes
1930             {
1931 0     0 0 0 my $in = shift;
1932            
1933 0         0 my %saw;
1934 0         0 @saw{@$in} = ();
1935              
1936             # Nodupes sorts now. - 1.26
1937 0         0 my @out = sort keys %saw;
1938              
1939 0         0 return @out;
1940             }
1941              
1942             sub keep_uniques
1943             {
1944 0     0 0 0 my $in = shift;
1945 0         0 my %saw;
1946             my @final;
1947            
1948 0         0 for(@$in)
1949             {
1950 0         0 $saw{$_}++;
1951             }
1952              
1953 0         0 for(keys %saw)
1954             {
1955 0 0       0 push(@final,$_) if($saw{$_} < 2);
1956             }
1957              
1958 0         0 return @final;
1959             }
1960              
1961             sub delhead
1962             {
1963 0     0 0 0 my $list = shift;
1964 0         0 my $count = shift;
1965              
1966 0         0 my $listcount = @$list;
1967              
1968 0 0       0 return @$list if($listcount == 0);
1969 0 0       0 return @$list if($count == 0);
1970              
1971 0 0       0 if($count >= $listcount)
1972             {
1973 0         0 $list = ();
1974 0         0 return $list;
1975             }
1976              
1977 0         0 my @final;
1978              
1979 0         0 my $i = 0;
1980 0         0 for(@$list)
1981             {
1982 0 0       0 push(@final, $_) if($i >= $count);
1983 0         0 $i++;
1984             }
1985              
1986 0         0 return @final;
1987             }
1988              
1989             sub keephead
1990             {
1991 0     0 0 0 my $list = shift;
1992 0         0 my $count = shift;
1993              
1994 0         0 my $listcount = @$list;
1995              
1996 0 0       0 return @$list if($count >= $listcount);
1997 0 0       0 return @$list if($listcount == 0);
1998            
1999 0 0       0 if($count == 0)
2000             {
2001 0         0 return ();
2002             }
2003              
2004 0         0 my @final;
2005              
2006 0         0 for(my $i=0;$i<$count;$i++)
2007             {
2008 0         0 push(@final, $$list[$i]);
2009             }
2010              
2011 0         0 return @final;
2012             }
2013              
2014             sub deltail
2015             {
2016 0     0 0 0 my $list = shift;
2017 0         0 my $count = shift;
2018              
2019 0         0 my $listcount = @$list;
2020              
2021 0 0       0 return @$list if($listcount == 0);
2022 0 0       0 return @$list if($count == 0);
2023              
2024 0 0       0 if($count >= $listcount)
2025             {
2026 0         0 $list = ();
2027 0         0 return $list;
2028             }
2029              
2030 0         0 for(my $i=0;$i<$count;$i++)
2031             {
2032 0         0 pop(@$list);
2033             }
2034              
2035 0         0 return @$list;
2036             }
2037              
2038             sub keeptail
2039             {
2040 0     0 0 0 my $list = shift;
2041 0         0 my $count = shift;
2042              
2043 0         0 my $listcount = @$list;
2044              
2045 0 0       0 return @$list if($count >= $listcount);
2046 0 0       0 return @$list if($listcount == 0);
2047            
2048 0 0       0 if($count == 0)
2049             {
2050 0         0 return ();
2051             }
2052              
2053 0         0 my @final;
2054              
2055 0         0 for(my $i=$count;$i>0;$i--)
2056             {
2057 0         0 push(@final, $$list[$listcount-$i]);
2058             }
2059              
2060 0         0 return @final;
2061             }
2062              
2063             # shows list to standard output
2064             sub showlist
2065             {
2066 0     0 0 0 my $list = shift;
2067 0         0 my $regex = shift;
2068              
2069 0 0       0 unless(defined $regex)
2070             {
2071 0         0 $regex = ".*"; # Show any goddamn thing
2072             }
2073              
2074 0 0       0 if($#$list < 0)
2075             {
2076 0         0 cb('output',"No records to view.\n",0);
2077 0         0 return;
2078             }
2079              
2080 0         0 $stop_getting_links = 0;
2081 0         0 foreach my $entry (@$list)
2082             {
2083 0 0       0 if($entry =~ m/$regex/)
2084             {
2085 0         0 cb('output',"$entry\n",0);
2086             }
2087 0 0       0 last if ($stop_getting_links);
2088             }
2089             }
2090              
2091             sub showhead
2092             {
2093 0     0 0 0 my $list = shift;
2094 0         0 my $amount_to_show = shift;
2095              
2096 0 0       0 $amount_to_show = 10 if(!$amount_to_show);
2097              
2098 0 0       0 if($#$list < 0)
2099             {
2100 0         0 cb('output',"No records to view.\n",0);
2101 0         0 return;
2102             }
2103              
2104 0         0 my $count = 0;
2105 0         0 foreach my $entry (@$list)
2106             {
2107 0         0 cb('output',"$entry\n",0);
2108              
2109 0         0 $count++;
2110 0 0       0 last if($count >= $amount_to_show);
2111             }
2112             }
2113              
2114             sub showtail
2115             {
2116 0     0 0 0 my $list = shift;
2117 0         0 my $amount_to_show = shift;
2118              
2119 0 0       0 $amount_to_show = 10 if(!$amount_to_show);
2120              
2121 0         0 my $listcount = @$list;
2122              
2123 0 0       0 $amount_to_show = $listcount if($amount_to_show > $listcount);
2124              
2125 0 0       0 if($#$list < 0)
2126             {
2127 0         0 cb('output',"No records to view.\n",0);
2128 0         0 return;
2129             }
2130              
2131 0         0 my $count = -1 * $amount_to_show;
2132 0         0 while($count < 0)
2133             {
2134 0         0 my $entry = @$list[$count];
2135 0         0 cb('output',"$entry\n",0);
2136              
2137 0         0 $count++;
2138             }
2139             }
2140              
2141             # Used internally by nsort
2142             sub sort_by_num
2143             {
2144 0     0 0 0 my $i = reverse shift;
2145 0         0 my $j = reverse shift;
2146              
2147 0 0       0 unless($i =~ m/^(\D+?)(\d+)(.+)$/)
2148             {
2149 0         0 return $i cmp $j;
2150             }
2151              
2152 0         0 my $iprefix = reverse $3;
2153 0         0 my $id = reverse $2;
2154 0         0 my $isuffix = reverse $1;
2155            
2156 0 0       0 unless($j =~ m/^(\D+?)(\d+)(.+)$/)
2157             {
2158 0         0 return $i cmp $j;
2159             }
2160            
2161 0         0 my $jprefix = reverse $3;
2162 0         0 my $jd = reverse $2;
2163 0         0 my $jsuffix = reverse $1;
2164              
2165 0 0       0 return $i cmp $j unless($iprefix eq $jprefix);
2166             # return $i cmp $j unless($isuffix eq $jsuffix);
2167              
2168 0         0 return $id <=> $jd;
2169             }
2170              
2171             # Added 1.05
2172             # This takes in a list like:
2173             # http://site/10.jpg
2174             # http://site/100.jpg
2175             # http://site/1.jpg
2176             # and sorts it:
2177             # http://site/1.jpg
2178             # http://site/10.jpg
2179             # http://site/100.jpg
2180             # (based on number)
2181              
2182             sub nsort
2183             {
2184 0     0 0 0 my $list = shift;
2185 0         0 my %cool; # The neato hash of arrays used for this
2186             my @outputlist;
2187              
2188 0         0 for(@$list)
2189             {
2190 0         0 my $current = reverse $_;
2191            
2192 0 0       0 if($current =~ m/^(\D+?)(\d+)(.+)$/)
2193             {
2194 0         0 my $prefix = reverse $3;
2195 0         0 my $d = reverse $2;
2196 0         0 my $suffix = reverse $1;
2197              
2198 0         0 $current = reverse $current;
2199 0         0 push (@{ $cool{$prefix} }, $current);
  0         0  
2200             }
2201             else
2202             {
2203 0         0 push @{$cool{'unmatched'}}, $_;
  0         0  
2204             }
2205             }
2206              
2207 0         0 foreach my $family ( sort keys %cool )
2208             {
2209 0         0 my @sorted = sort { sort_by_num($a,$b) } @{ $cool{$family} };
  0         0  
  0         0  
2210 0         0 push @outputlist,@sorted;
2211             }
2212              
2213 0         0 return @outputlist;
2214             }
2215              
2216             # *** SAVING / LOADING LIST FUNCTIONS **************************
2217              
2218             sub savetofile
2219             {
2220 0     0 0 0 my $utlist = shift;
2221 0         0 my $filename = shift;
2222              
2223 0 0       0 unless(open(LISTFILE,"> $filename"))
2224             {
2225 0         0 cb('error',"Couldn't Open file: $filename\n",0);
2226 0         0 return;
2227             }
2228              
2229 0         0 foreach my $link (@$utlist)
2230             {
2231 0         0 print LISTFILE "$link\n";
2232             }
2233            
2234 0         0 cb('output',"Saved list to \"$filename\".\n",0);
2235            
2236 0         0 close(LISTFILE);
2237             }
2238              
2239             sub loadfromfile
2240             {
2241 0     0 0 0 my $filename = shift;
2242 0         0 my @list;
2243            
2244 0 0       0 unless(-r $filename)
2245             {
2246 0         0 cb('error',"You cannot read this file: $filename\n",0);
2247 0         0 return;
2248             }
2249              
2250 0 0       0 unless(open(LISTFILE,"< $filename"))
2251             {
2252 0         0 cb('error',"Couldn't Open file: $filename\n",0);
2253 0         0 return;
2254             }
2255            
2256 0         0 while()
2257             {
2258 0         0 my $link = $_;
2259 0         0 chomp($link);
2260 0         0 push @list,$link;
2261             }
2262            
2263 0         0 close(LISTFILE);
2264            
2265 0         0 cb('output',"Loaded list from \"$filename\".\n",0);
2266            
2267 0         0 return @list;
2268             }
2269              
2270             # *** THE "SEQUENTIALS" *********************************
2271              
2272             sub lastinprefix
2273             {
2274 0     0 0 0 my $list = shift;
2275 0         0 my @lastlist;
2276              
2277             my $lastprefix;
2278 0         0 my $lasturl;
2279              
2280              
2281 0         0 @$list = nsort($list);
2282              
2283 0         0 foreach my $url (@$list)
2284             {
2285              
2286 0         0 $url = reverse $url;
2287              
2288 0 0       0 if($url =~ m/^(\D+?)(\d+)(.+)$/)
2289             {
2290 0         0 my $prefix = reverse $3;
2291 0         0 my $d = reverse $2;
2292 0         0 my $suffix = reverse $1;
2293              
2294 0 0 0     0 if($lastprefix && !($lastprefix eq $prefix))
2295             {
2296 0 0       0 if($lasturl)
2297             {
2298 0         0 push @lastlist, $lasturl;
2299             }
2300             }
2301              
2302 0         0 $lastprefix = $prefix;
2303              
2304             }
2305             else
2306             {
2307 0         0 push @lastlist, $url;
2308             }
2309              
2310 0         0 $lasturl = reverse $url;
2311              
2312             } # foreach
2313              
2314 0         0 return @lastlist;
2315              
2316             }
2317              
2318             sub seqlinesize
2319             {
2320 0     0 0 0 my $line = shift;
2321              
2322 0 0       0 if($line =~ /^[sz]eq\s+(.+)$/)
2323             {
2324 0         0 my $url = reverse $1;
2325 0 0       0 if($url =~ m/^(\D+?)(\d+)(.+)$/)
2326             {
2327 0         0 my $d = reverse $2;
2328 0         0 return $d;
2329             }
2330             }
2331            
2332 0         0 return 0;
2333             }
2334              
2335             # 99.9% of this code comes courtesy of Saint_Marck of SE fame
2336             sub seq
2337             {
2338 0     0 0 0 my $url = reverse shift;
2339 0         0 my $leading_zeros = shift;
2340              
2341 0         0 my @seqlist;
2342            
2343 0 0       0 if($url =~ m/^(\D+?)(\d+)(.+)$/)
2344             {
2345 0         0 my $prefix = reverse $3;
2346 0         0 my $d = reverse $2;
2347 0         0 my $suffix = reverse $1;
2348            
2349 0         0 my $len = length $d;
2350              
2351 0 0       0 if($d > $config_seq_warning_size)
2352             {
2353 0         0 cb('error',"** That command will create $d URLs! Raise SeqWarningSize if you wish to do this.\n");
2354 0         0 return ();
2355             }
2356              
2357 0 0       0 if($leading_zeros)
2358             {
2359 0         0 @seqlist = map { sprintf( "%s%0${len}d%s", $prefix, $_, $suffix ) } 1..$d;
  0         0  
2360             }
2361             else
2362             {
2363 0         0 @seqlist = map { "$prefix$_$suffix" } 1..$d;
  0         0  
2364             }
2365             }
2366             else
2367             {
2368 0         0 @seqlist = (reverse $url);
2369             }
2370              
2371 0         0 return @seqlist;
2372             }
2373              
2374             sub lengthsort
2375             {
2376 0     0 0 0 my $list = shift;
2377 0         0 my %n;
2378              
2379 0         0 for my $v (@$list)
2380             {
2381 0         0 push(@{$n{length $v}},$v);
  0         0  
2382             }
2383              
2384 0         0 my @final;
2385              
2386 0         0 for my $k (sort keys %n)
2387             {
2388 0         0 push @final, sort @{$n{$k}};
  0         0  
2389             }
2390              
2391 0         0 return @final;
2392             }
2393              
2394             sub autofusk
2395             {
2396 0     0 0 0 my $list = shift;
2397 0         0 my @unoptimized;
2398             my @final;
2399 0         0 my %f;
2400              
2401 0 0       0 if(@$list < 1)
2402             {
2403             # An empty list is sorted.
2404 0         0 return @$list;
2405             }
2406              
2407             # %f is a hash table of arrays. The key is the URL template,
2408             # and the values of the array are numbers that go in the
2409             # template.
2410              
2411             # Using http://www.example.com/pic35.jpg as an example ...
2412              
2413 0         0 for my $u (@$list)
2414             {
2415 0 0       0 if($u =~ m/^([^\[]+[^\[0-9])(\d+)(.*)$/)
2416             {
2417 0         0 my $prefix = $1; # http://www.example.com/
2418 0         0 my $digit = $2; # 35
2419 0         0 my $suffix = $3; # .jpg
2420              
2421             # http://www.example.com/pic<>.jpg
2422 0         0 my $hashvalue = "$prefix<>$suffix";
2423              
2424             # push 35 onto the array @${http://www.example.com/pic<>.jpg}
2425 0         0 push @{$f{$hashvalue}}, $digit;
  0         0  
2426             }
2427             else
2428             {
2429             # This will be where all of the prefusked or unfuskables go
2430 0         0 push @unoptimized, $u;
2431             }
2432             }
2433              
2434             # For all templated URLs (the hash values) ...
2435 0         0 for my $hv (sort keys %f)
2436             {
2437 0         0 my $front = undef;
2438 0         0 my $back = undef;
2439            
2440             # Sort a special way, by digit count. 9 goes before 03
2441 0         0 my @valuelist = lengthsort(\@{$f{$hv}});
  0         0  
2442            
2443 0         0 for my $v (@valuelist)
2444             {
2445 0 0       0 if(!defined($front))
2446             {
2447             # First time in the loop ... set some basic values
2448 0         0 $front = $v;
2449 0         0 $back = $v;
2450             }
2451             else
2452             {
2453             # Figure out what the next value would be
2454 0         0 my $next = $back+1;
2455              
2456             # Create a copy of the current value, without leading zeros
2457 0         0 my $tempv = $v;
2458 0         0 $tempv =~ s/^0+//;
2459              
2460             # If keepgoing is false, break off a fresh fuskline
2461 0         0 my $keepgoing = 0;
2462            
2463 0         0 $keepgoing = (int($next) == int($tempv));
2464              
2465 0 0       0 if($keepgoing)
2466             {
2467 0 0       0 if(length($back) < length($v))
2468             {
2469             # if the bracketed values are different length
2470             # due to a zero, break that
2471              
2472 0 0       0 $keepgoing = 0 if($v =~ m/^0/);
2473             }
2474             }
2475              
2476 0 0       0 if($keepgoing)
2477             {
2478             # Keep going, stretch out that list
2479 0         0 $back = $v;
2480             }
2481             else
2482             {
2483             # Break off a new fusker line and reset f&b
2484 0         0 my $fuskline = $hv;
2485 0         0 $fuskline =~ s/<>/\[$front-$back\]/;
2486 0         0 push @final,$fuskline;
2487 0         0 $front = $v;
2488 0         0 $back = $v;
2489             }
2490             }
2491             } # for my $v
2492              
2493 0         0 my $fuskline = $hv;
2494 0         0 $fuskline =~ s/<>/\[$front-$back\]/;
2495 0         0 push @final,$fuskline;
2496             }
2497              
2498 0         0 my @blao = ();
2499              
2500 0 0       0 if(@final > 0)
2501             {
2502             # Recursion. This works because the intial regex
2503             # ignores bracketed numbers, so something that
2504             # is all brackets will be ignored.
2505 0         0 @blao = autofusk(\@final);
2506             }
2507              
2508 0         0 push @unoptimized,@blao;
2509              
2510             # remove all brackets that don't do anything meaningful
2511 0         0 return strip_dumb_brackets(\@unoptimized);
2512             }
2513              
2514             # strip all brackets where the two values are the same
2515             sub strip_dumb_brackets
2516             {
2517 0     0 0 0 my $list = shift;
2518              
2519 0         0 for(@$list)
2520             {
2521 0         0 while(m/\[(\d+)-(\d+)\]/g)
2522             {
2523 0 0       0 if(int($1) == int($2))
2524             {
2525 0         0 my $torep = "\\[$1-$2\\]";
2526 0         0 my $with = $1;
2527 0         0 s/$torep/$with/g;
2528             }
2529             }
2530             }
2531              
2532 0         0 return @$list;
2533             }
2534              
2535              
2536             sub saveflux
2537             {
2538 0     0 0 0 my $list = shift;
2539 0         0 my $filename = shift;
2540              
2541 0 0       0 if(!open(FLUXFILE,"> $filename"))
2542             {
2543 0         0 cb('error',"Could not open $filename, sorry.\n",0);
2544 0         0 return;
2545             }
2546            
2547 0         0 my @answer = autofusk($list);
2548              
2549 0         0 for(@answer)
2550             {
2551 0 0       0 if(m/\[\d+-\d+\]/)
2552             {
2553 0         0 print FLUXFILE "fusk $_\n";
2554             }
2555             else
2556             {
2557 0         0 print FLUXFILE "$_\n";
2558             }
2559             }
2560              
2561 0         0 close(FLUXFILE);
2562              
2563 0 0       0 return if(@answer < 1);
2564 0         0 my $stats = "Saved \"$filename\" - " . @$list . " URLs in " . @answer . " command(s). Efficiency Index: " .
2565             sprintf("%2.2f",scalar(@$list)/scalar(@answer)). "\n";
2566 0         0 cb('output',$stats,0);
2567             }
2568              
2569             # Saint Marck gets all of the credit on this one
2570              
2571             sub fusk {
2572 0     0 0 0 my $url = shift;
2573 0 0       0 unless ($url) {
2574             # warn 'function fusk requires a URL argument';
2575 0         0 return ();
2576             }
2577 0         0 my @list = ();
2578 0         0 $url =~ s/^([^\[{]+)//;
2579 0         0 my $pre .= $1;
2580 0 0       0 if ($url =~ s/^[\[]//) {
    0          
2581            
2582             # Version 1.04 Change
2583 0 0       0 $url =~ s/^([0-9a-z]+-[0-9a-z]+)]// || return ();
2584             # $url =~ s/^(\d+-\d+)]// || return ();
2585              
2586 0         0 my ( $r1, $r2 ) = split '-', $1;
2587 0         0 my $len = length $r1;
2588              
2589             # Version 1.04 Change
2590 0         0 push @list, map { fusk( sprintf( "$pre%0${len}s$url", $_ ) ) } $r1..$r2;
  0         0  
2591             # push @list, map { fusk( sprintf( "$pre%0${len}d$url", $_ ) ) } $r1..$r2;
2592              
2593             } elsif ($url =~ s/^{//) {
2594 0 0       0 $url =~ s/^([^}]+)}// || return ();
2595 0         0 my @strings = split ',', $1;
2596 0         0 push @list, map { fusk( "$pre$_$url" ) } @strings;
  0         0  
2597             } else {
2598 0         0 push @list, $pre;
2599             }
2600 0         0 return @list;
2601             }
2602              
2603             # *** HISTORY COMMANDS ****************************
2604              
2605             # Made this a command just in case I wanted to add stuff to it
2606             sub addhistory
2607             {
2608 0     0 0 0 my $cmd = shift;
2609 0 0       0 return if(!$fromstdin);
2610              
2611 0         0 $pulledfromundo = "";
2612              
2613 0         0 push(@history,$cmd);
2614             }
2615              
2616             sub addhistory_undo
2617             {
2618 0     0 0 0 my $cmd = shift;
2619 0 0       0 return if(!$fromstdin);
2620              
2621 0 0       0 if($pulledfromundo)
2622             {
2623 0         0 push(@history,$pulledfromundo);
2624 0         0 $pulledfromundo = "";
2625             }
2626             else
2627             {
2628 0         0 $pulledfromundo = pop(@history);
2629             }
2630             }
2631              
2632             sub clearhistory
2633             {
2634 0     0 0 0 @history = ();
2635 0         0 cb('output',"History Cleared.\n",0);
2636             }
2637              
2638             sub showhistory
2639             {
2640 0     0 0 0 my $count = shift;
2641              
2642 0 0       0 if(@history < 1)
2643             {
2644 0         0 cb('output',"The history is empty.\n",0);
2645 0         0 return;
2646             }
2647              
2648 0         0 my $n = 0;
2649              
2650 0         0 for my $h (@history)
2651             {
2652 0         0 cb('output',"$h\n",0);
2653 0         0 $n++;
2654 0 0       0 if($count)
2655             {
2656 0 0       0 return if($n >= $count);
2657             }
2658             }
2659             }
2660              
2661             sub savehistory
2662             {
2663 0     0 0 0 my $filename = shift;
2664 0         0 my $count = shift;
2665              
2666 0         0 my $n = 0;
2667              
2668 0 0       0 if(!open(HISTORYFILE,"> $filename"))
2669             {
2670 0         0 cb('error',"Cannot open \"$filename\".\n",0);
2671 0         0 return;
2672             }
2673              
2674 0         0 for my $h (@history)
2675             {
2676 0         0 print HISTORYFILE "$h\n";
2677            
2678 0         0 $n++;
2679              
2680 0 0       0 if($count)
2681             {
2682 0 0       0 last if($n >= $count);
2683             }
2684             }
2685              
2686 0         0 close(HISTORYFILE);
2687              
2688 0         0 cb('output',"Saved $n commands to \"$filename\".\n",0);
2689             }
2690              
2691              
2692             # *** COMMAND LINE FUNCTIONS ***********************************
2693              
2694             sub createprompt
2695             {
2696 0     0 0 0 my $list = shift;
2697              
2698 0         0 my $temp = $config_prompt;
2699 0         0 my $count = @$list;
2700              
2701             # Add other variables for the prompt here
2702 0         0 my $currentdir = cwd();
2703              
2704 0         0 my ($tsec, $tmin, $thour,
2705             $tday, $tmonth, $tyear,
2706             $tweekday, $tdoy, $tdst) = localtime(time);
2707              
2708 0         0 $tyear += 1900; # Fix the year
2709              
2710 0         0 $temp =~ s/%DAY/$tday/;
2711 0         0 $temp =~ s/%MONTH/$tmonth/;
2712 0         0 $temp =~ s/%YEAR/$tyear/;
2713              
2714 0         0 my $t24hr = $thour;
2715 0 0       0 $thour -= 12 if($thour > 12);
2716              
2717 0         0 $temp =~ s/%24HR/$t24hr/;
2718 0         0 $temp =~ s/%HOUR/$thour/;
2719 0         0 $temp =~ s/%MIN/$tmin/;
2720 0         0 $temp =~ s/%SEC/$tsec/;
2721              
2722 0         0 $temp =~ s/%COUNT/$count/;
2723 0         0 $temp =~ s/%CWD/$currentdir/;
2724              
2725 0         0 return $temp;
2726             }
2727              
2728             sub makeundo
2729             {
2730 0     0 0 0 my $list = shift;
2731            
2732 0 0       0 if($config_useundo)
2733             {
2734 0         0 @undolist = (@$list);
2735             }
2736             }
2737              
2738             sub doundo
2739             {
2740 0     0 0 0 my $list = shift;
2741 0         0 my @templist = (@undolist);
2742 0         0 @undolist = (@$list);
2743              
2744 0         0 return @templist;
2745             }
2746              
2747             sub ut_exec_command
2748             {
2749 1     1 1 106 $_ = shift;
2750 1         3 my $utlist = shift;
2751              
2752 1         3 chomp;
2753              
2754             # New Parameter code for 1.09
2755 1 50       5 if(@params > 0)
2756             {
2757 0         0 my $cmd = $_;
2758 0         0 my $p = $params[0];
2759 0         0 for(my $i = 0;$i<@$p;$i++)
2760             {
2761 0         0 my $replacestr = "~$i";
2762 0         0 $cmd =~ s/$replacestr/$$p[$i]/;
2763             }
2764              
2765 0         0 $_ = $cmd;
2766             }
2767              
2768             CMDPARSE:
2769             {
2770 1 50       2 if (/^$/) { last CMDPARSE; }
  1         6  
  0         0  
2771 1 50       5 if (/^#/) { last CMDPARSE; }
  0         0  
2772 1 50       5 if (/^\s+$/) { last CMDPARSE; }
  0         0  
2773              
2774 1 50       5 if (/^exit$/i) { exit; };
  0         0  
2775            
2776 1 0       6 if (/^clear$/i) { if($win32) { system("cls"); } else { system("clear"); } last CMDPARSE; };
  0 50       0  
  0         0  
  0         0  
  0         0  
2777 1 0       5 if (/^cls$/i) { if($win32) { system("cls"); } else { system("clear"); } last CMDPARSE; };
  0 50       0  
  0         0  
  0         0  
  0         0  
2778              
2779 1 0       6 if (/^show(?: (.+))?$/i) { my $r = $1; showlist($utlist,$r) if(test_regex($r)); last CMDPARSE;};
  0 50       0  
  0         0  
  0         0  
2780 1 0       4 if (/^list(?: (.+))?$/i) { my $r = $1; showlist($utlist,$r) if(test_regex($r)); last CMDPARSE;};
  0 50       0  
  0         0  
  0         0  
2781 1 0       4 if (/^ls(?: (.+))?$/i) { my $r = $1; showlist($utlist,$r) if(test_regex($r)); last CMDPARSE;};
  0 50       0  
  0         0  
  0         0  
2782            
2783 1 50       5 if (/^head(?: (.+))?$/i) { my $r = $1; showhead($utlist,$r); last CMDPARSE;};
  0         0  
  0         0  
  0         0  
2784 1 50       4 if (/^tail(?: (.+))?$/i) { my $r = $1; showtail($utlist,$r); last CMDPARSE;};
  0         0  
  0         0  
  0         0  
2785              
2786 1 50       4 if (/^history\s+show(?:\s+)?$/i)
2787             {
2788 0         0 showhistory(0);
2789 0         0 last CMDPARSE;
2790             };
2791              
2792 1 50       21 if (/^history\s+show\s+(\d+)$/i)
2793             {
2794 0         0 my $count = $1;
2795 0         0 showhistory($count);
2796 0         0 last CMDPARSE;
2797             };
2798              
2799 1 50       3 if (/^history\s+save(?:\s+)?$/i)
2800             {
2801 0         0 helpsyntax('history');
2802 0         0 last CMDPARSE;
2803             };
2804              
2805 1 50       4 if (/^history\s+save\s+(\S.*)\s+(\d+)$/i)
2806             {
2807 0         0 my $filename = $1;
2808 0         0 my $count = $2;
2809 0         0 savehistory($filename,$count);
2810 0         0 last CMDPARSE;
2811             };
2812              
2813 1 50       4 if (/^history\s+save\s+(\S.*)$/i)
2814             {
2815 0         0 my $filename = $1;
2816 0         0 savehistory($filename,0);
2817 0         0 last CMDPARSE;
2818             };
2819              
2820 1 50       4 if (/^history\s+clear/i)
2821             {
2822 0         0 clearhistory;
2823 0         0 last CMDPARSE;
2824             };
2825              
2826 1 50       5 if (/^history(?:\s+)?$/i)
2827             {
2828 0         0 helpsyntax('history');
2829 0         0 last CMDPARSE;
2830             };
2831              
2832 1 50       4 if (/^keep(?:\s+)?$/i) { helpsyntax('keep'); last CMDPARSE;};
  0         0  
  0         0  
2833 1 50       5 if (/^keep (.+)$/i)
2834             {
2835 0         0 my $regex = $1;
2836 0         0 makeundo($utlist);
2837 0 0       0 if(test_regex($regex))
2838             {
2839 0         0 setaction('filter');
2840 0         0 @$utlist = keep_by_regex($utlist,$regex,0);
2841 0         0 endaction;
2842 0         0 addhistory($_);
2843             }
2844 0         0 last CMDPARSE;
2845             };
2846              
2847 1 50       7 if (/^size(?:\s+)?$/i) { helpsyntax('size'); last CMDPARSE;};
  0         0  
  0         0  
2848 1 50       4 if (/^size (.+)$/i)
2849             {
2850 0         0 my $size = $1;
2851 0         0 makeundo($utlist);
2852 0         0 setaction('size');
2853 0         0 @$utlist = keep_by_size($utlist,$size);
2854 0         0 endaction;
2855 0         0 addhistory($_);
2856            
2857 0         0 last CMDPARSE;
2858             };
2859              
2860 1 50       4 if(/^needparam$/i) { helpsyntax('needparam'); last CMDPARSE;};
  0         0  
  0         0  
2861 1 50       3 if(/^needparam\s+(\d+)(?:\s+(.*))?$/i)
2862             {
2863 0         0 my $which = $1;
2864 0         0 my $why = $2;
2865              
2866 0 0       0 if(@params < 1)
2867             {
2868 0         0 cb('error', "You can't type this in manually. This is for .u scripts.\n",0);
2869             }
2870             else
2871             {
2872 0         0 my $p = $params[0];
2873 0 0       0 if(!$$p[$which])
2874             {
2875 0         0 cb('help', "$why\n",0);
2876 0         0 return 0; # End this script
2877             }
2878             }
2879              
2880 0         0 last CMDPARSE;
2881             }
2882              
2883 1 50       13 if (/^batch(?:\s+)?$/i) { helpsyntax('batch'); last CMDPARSE;};
  0         0  
  0         0  
2884 1 50       5 if (/^batch (.+)$/i)
2885             {
2886 0         0 my $batchline = $1;
2887            
2888 0         0 makeundo($utlist);
2889 0         0 addhistory($_);
2890            
2891             # This disables messing with the undo during this
2892 0         0 my $cuu = $config_useundo;
2893 0         0 $config_useundo = 0;
2894 0         0 batchloop($loop_readptr,$utlist,$batchline);
2895 0         0 $config_useundo = $cuu;
2896 0         0 last CMDPARSE;
2897             };
2898              
2899 1 50       3 if (/^batchcurrent(?:\s+)?$/i) { helpsyntax('batchcurrent'); last CMDPARSE;};
  0         0  
  0         0  
2900 1 50       4 if (/^batchcurrent (.+)$/i)
2901             {
2902 0         0 my $batchline = $1;
2903            
2904 0         0 makeundo($utlist);
2905 0         0 addhistory($_);
2906            
2907             # This disables messing with the undo during this
2908 0         0 my $cuu = $config_useundo;
2909 0         0 $config_useundo = 0;
2910 0         0 @$utlist = batchcurrent($utlist,$batchline);
2911 0         0 $config_useundo = $cuu;
2912 0         0 last CMDPARSE;
2913             };
2914              
2915 1 50       3 if(/^keeph/)
2916             {
2917 0 0       0 if(/^keeph\s+(\d+)\s*$/)
2918             {
2919 0         0 addhistory($_);
2920 0         0 makeundo($utlist);
2921 0         0 setaction('filter');
2922 0         0 @$utlist = keephead($utlist,$1);
2923 0         0 endaction;
2924             }
2925             else
2926             {
2927 0         0 helpsyntax('keeph');
2928             }
2929              
2930 0         0 last CMDPARSE;
2931             }
2932              
2933 1 50       4 if(/^delh/)
2934             {
2935 0 0       0 if(/^delh\s+(\d+)\s*$/)
2936             {
2937 0         0 addhistory($_);
2938 0         0 makeundo($utlist);
2939 0         0 setaction('filter');
2940 0         0 @$utlist = delhead($utlist,$1);
2941 0         0 endaction;
2942             }
2943             else
2944             {
2945 0         0 helpsyntax('delh');
2946             }
2947              
2948 0         0 last CMDPARSE;
2949             }
2950              
2951 1 50       9 if(/^keept/)
2952             {
2953 0 0       0 if(/^keept\s+(\d+)\s*$/)
2954             {
2955 0         0 addhistory($_);
2956 0         0 makeundo($utlist);
2957 0         0 setaction('filter');
2958 0         0 @$utlist = keeptail($utlist,$1);
2959 0         0 endaction;
2960             }
2961             else
2962             {
2963 0         0 helpsyntax('keept');
2964             }
2965              
2966 0         0 last CMDPARSE;
2967             }
2968              
2969 1 50       5 if(/^delt/)
2970             {
2971 0 0       0 if(/^delt\s+(\d+)\s*$/)
2972             {
2973 0         0 addhistory($_);
2974 0         0 makeundo($utlist);
2975 0         0 setaction('filter');
2976 0         0 @$utlist = deltail($utlist,$1);
2977 0         0 endaction;
2978             }
2979             else
2980             {
2981 0         0 helpsyntax('delt');
2982             }
2983              
2984 0         0 last CMDPARSE;
2985             }
2986              
2987 1 50       4 if (/^del(?:\s+)?$/i) { helpsyntax('del'); last CMDPARSE;};
  0         0  
  0         0  
2988 1 50       4 if (/^del (.+)$/i)
2989             {
2990 0         0 my $regex = $1;
2991 0         0 makeundo($utlist);
2992 0 0       0 if(test_regex($regex))
2993             {
2994 0         0 addhistory($_);
2995 0         0 setaction('filter');
2996 0         0 @$utlist = keep_by_regex($utlist,$regex,1);
2997 0         0 endaction;
2998             }
2999 0         0 last CMDPARSE;
3000             };
3001              
3002 1 50       4 if (/^replace(?:\s+)?$/i) { helpsyntax('replace'); last CMDPARSE;};
  0         0  
  0         0  
3003 1 50       4 if (/^replace\s+(\S+)\s+(\S+)$/i)
3004             {
3005 0         0 addhistory($_);
3006 0         0 setaction('replace');
3007 0         0 @$utlist = replace($utlist,$1,$2,0);
3008 0         0 endaction;
3009 0         0 last CMDPARSE;
3010             };
3011              
3012 1 50       4 if (/^rreplace(?:\s+)?$/i) { helpsyntax('rreplace'); last CMDPARSE;};
  0         0  
  0         0  
3013 1 50       4 if (/^rreplace\s+(.*)$/i)
3014             {
3015 0         0 addhistory($_);
3016 0         0 setaction('replace');
3017 0         0 $_ = $1;
3018 0 0       0 if (/^s?\/(.*)(?
3019             {
3020 0         0 @$utlist = replace($utlist,$1,$2,1);
3021             }
3022             else
3023             {
3024 0         0 cb('error',"rreplace: Cannot understand that. Please check for errors.\n",0);
3025             }
3026 0         0 endaction;
3027 0         0 last CMDPARSE;
3028             };
3029              
3030 1 50       4 if (/^password(?:\s+)?$/i) { helpsyntax('password'); last CMDPARSE;};
  0         0  
  0         0  
3031 1 50       3 if (/^password\s+clear\s*$/i)
3032             {
3033 0         0 %passwords = ();
3034 0         0 last CMDPARSE;
3035             }
3036 1 50       5 if (/^password\s+show\s*$/i)
    50          
3037             {
3038 0         0 my @keys = sort keys %passwords;
3039              
3040 0 0       0 if(!@keys)
3041             {
3042 0         0 cb('output',"URLToys isn't aware of any passwords.\n",0);
3043             }
3044             else
3045             {
3046 0         0 for my $key(@keys)
3047             {
3048 0         0 cb('output',"$key - " . decode_base64($passwords{$key}) . "\n",0);
3049             }
3050             }
3051              
3052 0         0 last CMDPARSE;
3053             }
3054             elsif (/^password\s+(\S+)\s+(\S+)\s+(\S+)\s*$/i)
3055             {
3056 0         0 addhistory($_);
3057 0         0 my $domain = $1;
3058 0         0 my $username = $2;
3059 0         0 my $password = $3;
3060            
3061 0         0 chomp($username);
3062 0         0 chomp($password);
3063            
3064 0         0 $passwords{$domain} = encode_base64("$username:$password");
3065 0         0 chomp($passwords{$domain});
3066              
3067 0         0 cb('output',"URLToys will use $username for $domain now.\n",0);
3068            
3069 0         0 last CMDPARSE;
3070             };
3071              
3072 1 50       4 if (/^strip(?:\s+)?$/i) { helpsyntax('strip'); last CMDPARSE;};
  0         0  
  0         0  
3073 1 50       11 if (/^strip\s+(.*)$/i)
3074             {
3075 0         0 addhistory($_);
3076 0         0 setaction('replace');
3077 0         0 @$utlist = replace_with_nothing($utlist,$1,0);
3078 0         0 endaction;
3079 0         0 last CMDPARSE;
3080             };
3081              
3082 1 50 33     11 if ((/^u$/i) or (/^undo\s*$/))
3083             {
3084 0         0 addhistory_undo($_);
3085 0         0 @$utlist = doundo($utlist);
3086 0         0 last CMDPARSE;
3087             };
3088              
3089 1 50       4 if (/^nodupes$/i)
3090             {
3091 0         0 addhistory($_);
3092 0         0 makeundo($utlist);
3093 0         0 setaction('filter');
3094 0         0 @$utlist = removedupes($utlist);
3095 0         0 endaction;
3096 0         0 last CMDPARSE;
3097             };
3098              
3099 1 50       9 if (/^spider$/i)
3100             {
3101 0         0 addhistory($_);
3102 0         0 makeundo($utlist);
3103 0         0 setaction('make');
3104 0         0 $fromstdin = 0;
3105 0         0 @$utlist = spider($utlist);
3106 0         0 endaction;
3107 0         0 last CMDPARSE;
3108             };
3109              
3110              
3111 1 50       10 if (/^keepuni$/i)
3112             {
3113 0         0 addhistory($_);
3114 0         0 makeundo($utlist);
3115 0         0 setaction('filter');
3116 0         0 @$utlist = keep_uniques($utlist);
3117 0         0 endaction;
3118 0         0 last CMDPARSE;
3119             };
3120              
3121             # Added 1.01 4/19/03
3122 1 50       4 if (/^fusk(?:\s+)?$/i) { helpsyntax('fusk'); last CMDPARSE;};
  0         0  
  0         0  
3123 1 50       4 if (/^fusker(?:\s+)?$/i) { helpsyntax('fusker'); last CMDPARSE;};
  0         0  
  0         0  
3124 1 50       3 if (/^fusk(?:er)? (.+)$/i)
3125             {
3126 0         0 my $fuskurl = $1;
3127 0         0 chomp($fuskurl);
3128            
3129 0         0 addhistory($_);
3130              
3131 0         0 setaction('add');
3132 0         0 my @fusklist = fusk($fuskurl);
3133            
3134 0         0 makeundo($utlist);
3135 0 0       0 push(@$utlist, @fusklist) if @fusklist;
3136            
3137 0         0 endaction;
3138              
3139 0         0 last CMDPARSE;
3140             };
3141              
3142             # Last In Prefix ... Added 1.06 05/19/03
3143 1 50       3 if (/^lip$/i)
3144             {
3145 0         0 addhistory($_);
3146 0         0 makeundo($utlist);
3147 0         0 setaction('filter');
3148 0         0 @$utlist = lastinprefix($utlist);
3149 0         0 endaction;
3150            
3151 0         0 last CMDPARSE;
3152             };
3153              
3154             # Version ... Added 1.06 05/19/03
3155 1 50       6 if (/^ver/i)
3156             {
3157 1         8 cb('output',"$URLTOYS_VERSION\n",0);
3158            
3159 1         3 last CMDPARSE;
3160             };
3161              
3162 0 0       0 if (/^seq(?:\s+)?$/i) { helpsyntax('seq'); last CMDPARSE;};
  0         0  
  0         0  
3163 0 0       0 if (/^seq (.+)$/i)
3164             {
3165 0         0 my $sequrl = $1;
3166 0         0 chomp($sequrl);
3167 0         0 addhistory($_);
3168              
3169 0         0 setaction('add');
3170             # The 0 means "no leading zeros"
3171 0         0 my @seqlist = seq($sequrl,0);
3172            
3173 0         0 makeundo($utlist);
3174 0         0 push @$utlist, @seqlist;
3175 0         0 endaction;
3176              
3177 0         0 last CMDPARSE;
3178             };
3179              
3180 0 0       0 if (/^cd(?:\s+)?$/i) { helpsyntax('cd'); last CMDPARSE;};
  0         0  
  0         0  
3181 0 0       0 if (/^cd\s+(.+)$/i)
3182             {
3183 0         0 my $newdir = $1;
3184 0         0 chomp($newdir);
3185 0         0 addhistory($_);
3186              
3187 0         0 chdir $newdir;
3188              
3189 0         0 last CMDPARSE;
3190             };
3191              
3192 0 0       0 if (/^header(?:\s+)?$/i)
3193             {
3194 0         0 cb('output',"\nCurrently assigned headers:\n",0);
3195 0 0       0 if(%headers > 0)
3196             {
3197 0         0 foreach my $key (keys %headers)
3198             {
3199 0         0 cb('output',$key . ": " . $headers{$key} . "\n",0);
3200             }
3201             }
3202             else
3203             {
3204 0         0 cb('output',"-- None --\n",0);
3205             }
3206              
3207 0         0 cb('output',"\n",0);
3208            
3209 0         0 last CMDPARSE;
3210             };
3211 0 0       0 if (/^header\s+(.+)$/i)
3212             {
3213 0         0 my $newheader = $1;
3214 0         0 chomp($newheader);
3215 0         0 addhistory($_);
3216              
3217 0 0       0 if($newheader =~ m/^\s*([^ \t:]+):?\s+(.*)$/)
3218             {
3219 0         0 my ($which,$what) = ($1,$2);
3220 0 0       0 if($which =~ /^-d$/)
3221             {
3222 0         0 delete($headers{$what});
3223             }
3224             else
3225             {
3226 0         0 $headers{$which} = $what;
3227             }
3228             }
3229              
3230 0         0 last CMDPARSE;
3231             };
3232              
3233 0 0       0 if (/^pwd(?:\s+)?$/i)
3234             {
3235 0         0 my $tehdir = cwd();
3236 0         0 cb('output',"$tehdir\n",0);
3237              
3238 0         0 last CMDPARSE;
3239             };
3240              
3241 0 0       0 if (/^zeq(?:\s+)?$/i) { helpsyntax('zeq'); last CMDPARSE;};
  0         0  
  0         0  
3242 0 0       0 if (/^zeq (.+)$/i)
3243             {
3244 0         0 my $sequrl = $1;
3245 0         0 chomp($sequrl);
3246 0         0 addhistory($_);
3247              
3248 0         0 setaction('add');
3249             # The 1 means "use the leading zeros"
3250 0         0 my @seqlist = seq($sequrl,1);
3251            
3252 0         0 makeundo($utlist);
3253 0         0 push @$utlist, @seqlist;
3254              
3255 0         0 endaction;
3256              
3257 0         0 last CMDPARSE;
3258             };
3259              
3260              
3261 0 0       0 if (/^(http:\/\/[^ <>]+)$/i)
3262             {
3263 0         0 my $toadd = $1;
3264 0         0 chomp($toadd);
3265 0         0 addhistory($_);
3266 0         0 makeundo($utlist);
3267 0         0 setaction('add');
3268 0         0 push @$utlist, $toadd;
3269 0         0 endaction;
3270 0         0 last CMDPARSE;
3271             };
3272              
3273             # Added 1.03
3274 0 0       0 if (/^sort$/i)
3275             {
3276 0         0 makeundo($utlist);
3277 0         0 addhistory($_);
3278 0         0 setaction('sort');
3279 0         0 @$utlist = sort @$utlist;
3280 0         0 endaction;
3281 0         0 last CMDPARSE;
3282             };
3283             # Added 1.05
3284 0 0       0 if (/^nsort$/i)
3285             {
3286 0         0 makeundo($utlist);
3287 0         0 addhistory($_);
3288 0         0 setaction('sort');
3289 0         0 @$utlist = nsort($utlist);
3290 0         0 endaction;
3291 0         0 last CMDPARSE;
3292             };
3293            
3294             # Added 1.04a
3295 0 0       0 if (/^system(?:\s+)?$/i) { helpsyntax('system'); last CMDPARSE;};
  0         0  
  0         0  
3296 0 0       0 if (/^system (.+)$/i)
3297             {
3298 0         0 my $cmd = $1;
3299 0         0 chomp($cmd);
3300 0         0 addhistory($_);
3301 0         0 setaction('system');
3302 0         0 system($cmd);
3303 0         0 endaction;
3304 0         0 last CMDPARSE;
3305             };
3306              
3307 0 0       0 if (/^systemw(?:\s+)?$/i) { helpsyntax('systemw'); last CMDPARSE;};
  0         0  
  0         0  
3308 0 0       0 if (/^systemw (.+)$/i)
3309             {
3310 0         0 my $cmd = $1;
3311 0         0 chomp($cmd);
3312 0         0 addhistory($_);
3313 0         0 setaction('system');
3314 0 0       0 system($cmd) if($win32);
3315 0         0 endaction;
3316 0         0 last CMDPARSE;
3317             };
3318              
3319 0 0       0 if (/^systemu(?:\s+)?$/i) { helpsyntax('systemu'); last CMDPARSE;};
  0         0  
  0         0  
3320 0 0       0 if (/^systemu (.+)$/i)
3321             {
3322 0         0 my $cmd = $1;
3323 0         0 chomp($cmd);
3324 0         0 addhistory($_);
3325 0         0 setaction('system');
3326 0 0       0 system($cmd) if(!$win32);
3327 0         0 endaction;
3328 0         0 last CMDPARSE;
3329             };
3330              
3331 0 0       0 if (/^add(?:\s+)?$/i) { helpsyntax('add'); last CMDPARSE;};
  0         0  
  0         0  
3332 0 0       0 if (/^add (.+)$/i)
3333             {
3334 0         0 my $toadd = $1;
3335 0         0 chomp($toadd);
3336 0         0 addhistory($_);
3337 0         0 makeundo($utlist);
3338 0         0 setaction('add');
3339 0         0 push @$utlist, $toadd;
3340 0         0 endaction;
3341 0         0 last CMDPARSE;
3342             };
3343              
3344 0 0       0 if (/^save(?:\s+)?$/i) { helpsyntax('save'); last CMDPARSE;};
  0         0  
  0         0  
3345 0 0       0 if (/^save (.+)$/i)
3346             {
3347 0         0 my $filename = $1;
3348 0         0 chomp($filename);
3349 0         0 addhistory($_);
3350 0         0 setaction('save');
3351 0         0 savetofile($utlist,$filename);
3352 0         0 endaction;
3353 0         0 last CMDPARSE;
3354             };
3355              
3356 0 0       0 if (/^saveflux(?:\s+)?$/i) { helpsyntax('saveflux'); last CMDPARSE;};
  0         0  
  0         0  
3357 0 0       0 if (/^saveflux (.+)$/i)
3358             {
3359 0         0 my $filename = $1;
3360 0         0 chomp($filename);
3361 0         0 addhistory($_);
3362 0         0 setaction('save');
3363 0         0 saveflux($utlist,$filename);
3364 0         0 endaction;
3365 0         0 last CMDPARSE;
3366             };
3367              
3368 0 0       0 if (/^load(?:\s+)?$/i) { helpsyntax('load'); last CMDPARSE;};
  0         0  
  0         0  
3369 0 0       0 if (/^load (.+)$/i)
3370             {
3371 0         0 my $filename = $1;
3372 0         0 chomp($filename);
3373 0         0 addhistory($_);
3374 0         0 makeundo($utlist);
3375 0         0 setaction('load');
3376 0         0 @$utlist = loadfromfile($filename);
3377 0         0 endaction;
3378 0         0 last CMDPARSE;
3379             };
3380              
3381 0 0       0 if (/^append(?:\s+)?$/i) { helpsyntax('append'); last CMDPARSE;};
  0         0  
  0         0  
3382 0 0       0 if (/^append (.+)$/i)
3383             {
3384 0         0 my $filename = $1;
3385 0         0 chomp($filename);
3386 0         0 addhistory($_);
3387 0         0 makeundo($utlist);
3388 0         0 setaction('load');
3389 0         0 my @templist = loadfromfile($filename);
3390 0         0 push @$utlist, @templist;
3391 0         0 endaction;
3392 0         0 last CMDPARSE;
3393             };
3394              
3395 0 0       0 if (/^title\s*$/) { helpsyntax('title'); last CMDPARSE;};
  0         0  
  0         0  
3396 0 0       0 if (/^title (.+)$/i)
3397             {
3398 0         0 my $text = $1;
3399 0         0 addhistory($_);
3400 0         0 cb('title',$text,0);
3401 0         0 last CMDPARSE;
3402             };
3403              
3404 0 0       0 if (/^print$/i) { cb('print',"\n",0); last CMDPARSE; };
  0         0  
  0         0  
3405 0 0       0 if (/^print (.*)$/i)
3406             {
3407 0         0 my $text = $1;
3408 0         0 addhistory($_);
3409 0         0 cb('print',"$text\n",0);
3410 0         0 last CMDPARSE;
3411             };
3412              
3413 0 0       0 if(/^href$/i)
3414             {
3415 0         0 addhistory($_);
3416 0         0 makeundo($utlist);
3417 0         0 setaction('make');
3418 0         0 @$utlist = ut_getlinks_array($utlist,[$config_href_regex]);
3419 0         0 endaction;
3420 0         0 last CMDPARSE;
3421             }
3422              
3423 0 0       0 if(/^img$/i)
3424             {
3425 0         0 addhistory($_);
3426 0         0 makeundo($utlist);
3427 0         0 setaction('make');
3428 0         0 @$utlist = ut_getlinks_array($utlist,[$config_img_regex]);
3429 0         0 endaction;
3430 0         0 last CMDPARSE;
3431             }
3432              
3433 0 0       0 if(/^hrefimg$/i)
3434             {
3435 0         0 addhistory($_);
3436 0         0 makeundo($utlist);
3437 0         0 setaction('make');
3438 0         0 @$utlist = ut_getlinks_array($utlist,[$config_href_regex,$config_img_regex]);
3439 0         0 endaction;
3440 0         0 last CMDPARSE;
3441             }
3442              
3443 0 0       0 if(/^fixparents$/i)
3444             {
3445 0         0 addhistory($_);
3446 0         0 makeundo($utlist);
3447 0         0 setaction('replace');
3448 0         0 fixparents($utlist);
3449 0         0 endaction;
3450 0         0 last CMDPARSE;
3451             }
3452              
3453 0 0       0 if(/^config(?: +)?$/i)
3454             {
3455 0         0 showconfig("-",0);
3456 0         0 last CMDPARSE;
3457             }
3458              
3459 0 0       0 if(/^config\s+save\s*$/i)
3460             {
3461 0         0 addhistory($_);
3462 0         0 cb('output',"Saving Configuration...\n",0);
3463 0         0 mkdir($urltoys_dir);
3464 0         0 setaction('save');
3465 0         0 saveconfig($config_file);
3466 0         0 endaction;
3467 0         0 last CMDPARSE;
3468             }
3469              
3470 0 0       0 if(/^set$/i)
3471             {
3472 0         0 showconfig("-",0);
3473 0         0 last CMDPARSE;
3474             }
3475              
3476 0 0       0 if(/^config\s+load\s*$/i)
3477             {
3478 0         0 addhistory($_);
3479 0         0 cb('output',"Loading Configuration...\n",0);
3480 0         0 setaction('load');
3481 0         0 loadconfig($config_file);
3482 0         0 endaction;
3483 0         0 last CMDPARSE;
3484             }
3485              
3486 0 0       0 if (/^makeregex(?: (.+))?$/i)
3487             {
3488 0 0       0 if(defined $1)
3489             {
3490 0 0       0 if(test_regex($1))
3491             {
3492 0         0 $makeregex = $1;
3493 0         0 addhistory($_);
3494             }
3495             }
3496             else
3497             {
3498 0         0 cb('output',"Current Make Regex is: \"$makeregex\"\n",0);
3499             }
3500 0         0 last CMDPARSE;
3501             };
3502              
3503 0 0       0 if (/^make(?: (.+))?$/i)
3504             {
3505 0         0 makeundo($utlist);
3506              
3507 0 0       0 if(defined $1)
3508             {
3509 0         0 my $new_regex = $1;
3510 0 0       0 if(test_regex($new_regex))
3511             {
3512 0         0 addhistory($_);
3513 0         0 setaction('make');
3514 0         0 @$utlist = ut_getlinks_array($utlist,[$new_regex]);
3515 0         0 endaction;
3516             };
3517             }
3518             else
3519             {
3520 0 0       0 if(test_regex($config_href_regex))
3521             {
3522 0         0 addhistory($_);
3523 0         0 setaction('make');
3524 0         0 @$utlist = ut_getlinks_array($utlist,[$config_href_regex]);
3525 0         0 endaction;
3526             };
3527             }
3528 0         0 last CMDPARSE;
3529             };
3530              
3531             # Added Version 1.04 4/24/2003 -- resume list
3532 0 0       0 if (/^resume(?:\s+)?$/i) { helpsyntax('resume'); last CMDPARSE;};
  0         0  
  0         0  
3533 0 0       0 if (/^resume (.+)$/i)
3534             {
3535 0         0 my $resumedir = $1;
3536 0         0 chomp($resumedir);
3537 0         0 addhistory($_);
3538 0         0 $dlsize = "+0b";
3539 0         0 setaction('download');
3540 0         0 resume_list($resumedir);
3541 0         0 endaction;
3542 0         0 last CMDPARSE;
3543             }
3544              
3545 0 0       0 if(/^get$/i)
3546             {
3547 0         0 addhistory($_);
3548 0         0 $dlsize = "+0b";
3549 0         0 setaction('download');
3550 0         0 downloadfile_array($utlist);
3551 0         0 endaction;
3552 0         0 last CMDPARSE;
3553             }
3554              
3555 0 0       0 if(/^get\s+(.+)$/i)
3556             {
3557 0         0 my $dl = $1;
3558 0         0 addhistory($_);
3559 0         0 $dlsize = $dl;
3560 0         0 setaction('download');
3561 0         0 downloadfile_array($utlist);
3562 0         0 endaction;
3563 0         0 last CMDPARSE;
3564             }
3565              
3566 0 0       0 if(/^help\s+(\S+)(?:\s+(?:.*))?$/i){ helpsyntax($1); last CMDPARSE; }
  0         0  
  0         0  
3567 0 0       0 if(/^h\s+(\S+)(?:\s+(?:.*))?$/i){ helpsyntax($1); last CMDPARSE; }
  0         0  
  0         0  
3568              
3569 0 0       0 if(/^help(?:\s+)?$/i){ helpsyntax; last CMDPARSE; }
  0         0  
  0         0  
3570 0 0       0 if(/^h(?:\s+)?$/i) { helpsyntax; last CMDPARSE; }
  0         0  
  0         0  
3571            
3572             # Attempt to set a command
3573 0 0       0 if(/^set ([^=]+)=(.*)$/)
3574             {
3575 0         0 my $which = $1;
3576 0         0 my $what = $2;
3577            
3578 0         0 addhistory($_);
3579 0         0 handleconfigline($which,$what);
3580 0         0 last CMDPARSE;
3581             }
3582              
3583 0 0       0 if (/^cookies(?:\s+)?$/i)
3584             {
3585 0 0       0 if($use_cookies)
3586             {
3587 0         0 cb('output',"Cookies enabled.",0);
3588             }
3589             else
3590             {
3591 0         0 cb('output',"Cookies disabled.",0);
3592             }
3593              
3594 0         0 cb('output',"\nCurrent Cookie Jar: \n",0);
3595 0         0 my $cookiestring = $cookies->as_string;
3596              
3597 0 0       0 if(length $cookiestring > 0)
3598             {
3599 0         0 cb('output',$cookiestring,0);
3600             }
3601             else
3602             {
3603 0         0 cb('output'," None.\n",0);
3604             }
3605            
3606 0         0 last CMDPARSE;
3607             };
3608 0 0       0 if (/^cookies (.+)$/i)
3609             {
3610 0         0 my $cmd = $1;
3611 0         0 chomp($cmd);
3612 0         0 addhistory($_);
3613              
3614 0 0       0 $use_cookies = 1 if($cmd =~/^on/);
3615 0 0       0 $use_cookies = 0 if($cmd =~/^off/);
3616 0 0       0 $cookies->clear if($cmd =~/^clear/);
3617              
3618 0         0 last CMDPARSE;
3619             }
3620              
3621 0 0       0 if (/^autorun(?:\s+)?$/i) { helpsyntax('autorun'); last CMDPARSE;};
  0         0  
  0         0  
3622 0 0       0 if (/^autorun (.+)$/i)
3623             {
3624 0         0 my $fluxfile = $1;
3625 0         0 chomp($fluxfile);
3626 0         0 $fluxfile =~ s/^"+//;
3627 0         0 $fluxfile =~ s/"+$//;
3628 0         0 addhistory($_);
3629              
3630 0         0 setaction('flux');
3631              
3632 0         0 my $cmdfileptr;
3633 0 0       0 if(open($cmdfileptr,$fluxfile))
3634             {
3635 0         0 my $warn = 0;
3636 0         0 my @warnlist = ();
3637              
3638 0         0 my $seqcount = 0;
3639              
3640 0         0 $fluxlines = 0;
3641              
3642 0         0 while(<$cmdfileptr>)
3643             {
3644 0         0 $fluxlines++;
3645              
3646 0         0 my $w=0;
3647 0 0       0 $w=1 if(m/^\s*system/i);
3648 0 0       0 $w=1 if(m/^\s*cd/i);
3649 0 0       0 $w=1 if(m/^\s*config/i);
3650 0 0       0 $w=1 if(m/^\s*set/i);
3651 0 0       0 $w=1 if(m/^\s*spider/i);
3652              
3653 0 0       0 if($w)
3654             {
3655 0         0 $warn = 1;
3656 0         0 push @warnlist,$_;
3657             }
3658              
3659 0         0 $seqcount += seqlinesize($_);
3660             }
3661 0         0 close($cmdfileptr);
3662              
3663 0         0 my $docmd = 1;
3664              
3665 0 0       0 if($seqcount > 30000)
3666             {
3667 0         0 push @warnlist, "NOTE: The seq/zeq commands in this flux will generate $seqcount URLs.";
3668 0         0 $warn = 1;
3669             }
3670            
3671 0 0       0 if($warn)
3672             {
3673 0 0       0 $docmd = 0 unless(cb('warnuser',\@warnlist,0));
3674             }
3675            
3676             # This protects against malicious .flux files, somewhat.
3677 0 0       0 if($docmd)
3678             {
3679 0         0 open($cmdfileptr,$fluxfile);
3680 0         0 $stop_getting_links = 0;
3681 0         0 $fluxvarupdate = 1;
3682 0         0 ut_command_loop($cmdfileptr,$utlist);
3683 0         0 $fluxvarupdate = 0;
3684 0         0 close($cmdfileptr);
3685             }
3686             }
3687              
3688 0         0 endaction;
3689              
3690 0         0 last CMDPARSE;
3691             }
3692            
3693             # Look for custom command in the .urltoys folder
3694 0         0 my $cmd = $_;
3695 0         0 chomp($cmd);
3696 0         0 my $theactualcommand = '';
3697 0 0       0 if(/^(\S+)/)
3698             {
3699 0         0 $theactualcommand = $1;
3700             }
3701              
3702 0         0 my $cmdfile = $ENV{"HOME"} . "/.urltoys/" . $theactualcommand . ".u";
3703              
3704 0 0       0 if (-e $cmdfile)
3705             {
3706 0         0 addhistory($_);
3707 0         0 my $cmdfileptr;
3708 0         0 open($cmdfileptr,$cmdfile);
3709 0         0 my @tempparams = split(' ',$cmd);
3710 0         0 shift @tempparams; # remove first one to replace it
3711 0         0 my $allparams = join(' ',@tempparams);
3712 0         0 unshift @tempparams,$allparams;
3713              
3714 0         0 unshift @params, \@tempparams;
3715 0         0 $stop_getting_links = 0;
3716 0         0 setaction('custom');
3717 0         0 ut_command_loop($cmdfileptr,$utlist);
3718 0         0 endaction;
3719 0         0 shift @params;
3720 0         0 close($cmdfileptr);
3721              
3722 0         0 last CMDPARSE;
3723             }
3724              
3725             # Otherwise ... we don't know this command!
3726 0         0 cb('error',"Unknown Command: $_\n",0);
3727             }
3728              
3729 1         2 return 1;
3730             }
3731              
3732             sub ut_getnextline
3733             {
3734 0     0 0   my $htr = shift;
3735 0           my $prompt = shift;
3736            
3737             # if($htr == *STDIN)
3738 0 0         if(-t $htr)
3739             {
3740 0           $fromstdin = 1;
3741 0 0         createterm() unless($ut_term);
3742 0           my $text = $ut_term->readline($prompt);
3743 0 0         return "" unless(defined($text));
3744 0 0         $text = " " if(!$text);
3745 0           return $text;
3746             }
3747             else
3748             {
3749 0           $fromstdin = 0;
3750             }
3751              
3752 0           return <$htr>;
3753             }
3754              
3755             sub batchcurrent
3756             {
3757 0     0 0   my $utlist = shift;
3758 0           my $commandtobatch = shift;
3759              
3760 0           my @newlist;
3761              
3762 0           for my $entry (@$utlist)
3763             {
3764 0           my $cmd = $commandtobatch;
3765 0 0         if($cmd =~ m/~/)
3766             {
3767             # It's got a specific location to place the line
3768 0           $cmd =~ s/~/$entry/g;
3769             }
3770             else
3771             {
3772             # just tack it on the end otherwise
3773 0           $cmd .= " $entry";
3774             }
3775              
3776 0           ut_exec_command($cmd,\@newlist);
3777             }
3778            
3779 0           return @newlist;
3780             }
3781              
3782             sub batchloop
3783             {
3784 0     0 0   my $handletoread = shift;
3785 0           my $utlist = shift;
3786 0           my $commandtobatch = shift;
3787              
3788 0           my $batchcount = 0;
3789 0           my @batchlist;
3790 0           my $batchprompt = "[batch][$batchcount] ";
3791             # my $endbatch = 0;
3792              
3793 0           READCMD: while ($_ = ut_getnextline($handletoread,$batchprompt))
3794             {
3795             # last if ($endbatch);
3796              
3797 0 0         if(m/^end$/i)
    0          
    0          
3798             {
3799 0           last;
3800             }
3801             elsif(m/^exit$/i)
3802             {
3803 0           last;
3804             }
3805             elsif(m/^quit$/i)
3806             {
3807 0           last;
3808             }
3809             else
3810             {
3811 0 0         unless(m/^\s*$/) # It's just whitespace
3812             {
3813 0           push @batchlist, $_;
3814             }
3815             };
3816              
3817 0 0         if($handletoread == *STDIN)
3818             {
3819 0 0         if (-t *STDIN)
3820             {
3821 0           $batchcount = @batchlist;
3822 0           $batchprompt = "[batch][$batchcount] ";
3823             }
3824             }
3825             } # while loop
3826              
3827 0           for my $entry (@batchlist)
3828             {
3829 0           my $cmd = $commandtobatch;
3830 0 0         if($cmd =~ m/~/)
3831             {
3832             # It's got a specific location to place the line
3833 0           $cmd =~ s/~/$entry/g;
3834             }
3835             else
3836             {
3837             # just tack it on the end otherwise
3838 0           $cmd .= " $entry";
3839             }
3840              
3841 0           ut_exec_command($cmd,$utlist);
3842             }
3843              
3844             # return @$utlist;
3845              
3846             } #batchloop
3847              
3848             sub ut_command_loop
3849             {
3850 0     0 1   my $handletoread = shift;
3851 0           my $utlist = shift;
3852              
3853 0           my $count = @$utlist;
3854              
3855 0           $loop_readptr = $handletoread;
3856              
3857 0           cb('title',"URLToys ($count)",0);
3858              
3859 0           $stop_getting_links = 0;
3860              
3861 0           my $currentline = 0;
3862              
3863 0           READCMD: while ($_ = ut_getnextline($handletoread,createprompt($utlist)))
3864             {
3865              
3866 0           s/\r+$//; # Fix issue with /r/n people making unix files
3867              
3868             # last if ($stop_getting_links);
3869              
3870 0 0         if($fluxvarupdate)
3871             {
3872 0           $currentline++;
3873 0           cb('variable','tt',"Fluxing ($currentline/$fluxlines Lines)...");
3874 0 0         if($fluxlines > 0)
3875             {
3876 0           cb('variable','tp',(100*$currentline)/$fluxlines);
3877             }
3878             else
3879             {
3880 0           cb('variable','tp',0);
3881             }
3882             }
3883              
3884 0 0         if(!ut_exec_command($_,$utlist))
3885             {
3886 0           return;
3887             }
3888              
3889 0           $count = @$utlist;
3890 0           cb('title',"URLToys ($count)",0);
3891              
3892 0           $stop_getting_links = 0;
3893             }
3894              
3895 0           cb('output',"\n",0);
3896              
3897             }
3898              
3899             1;
3900              
3901             # ** END OF MODULE **
3902