home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / bingrb2b.zip / bingrab.cmd next >
OS/2 REXX Batch file  |  1997-09-14  |  20KB  |  633 lines

  1. /*------------------------------------------------------------------
  2.  * REXX - OS/2 -- BINGRAB ver 0.2b
  3.  * bingrab.cmd : binaries grabber
  4.  *
  5.  * Current version can be found at http://nfinity.com/~tmillea
  6.  *
  7.  * Grabs uudecoded Jpeg and Gif files (multiple and single part)
  8.  * from newsgroups then decodes them into binaries. A small modification
  9.  * can be made to allow it to decode other binaries as well such as Zip
  10.  * and EXE.
  11.  * Requires rxsock.dll and uudeview.exe to function. I have included
  12.  * them, but STRONGLY URGE you to go get the complete file from
  13.  * FTP somewhere. They will have documentation on how to setup.
  14.  * The .rc files contain group info to track what groups to grab
  15.  * and also keep track of messages already downloaded.
  16.  * As to the multiple parts - It has it's limitations. You can adjust the
  17.  * minimum size of messages to download to a smaller value to maybe
  18.  * get the final part of a post, but you are also grabbing a bunch
  19.  * of time consuming garbage in the proccess. I have it set to 500.
  20.  * This is mainly because I don't want a bunch of small pictures in my 
  21.  * directory or to spend time downloading files that are not pictures
  22.  * like .html files or text files. I have found that multiple part posts are 
  23.  * missing pieces anyway. The few complete ones that get missed are
  24.  * probably not worth the extra coding it would take to go look for them.
  25.  * Also another important consideration is the number of group names
  26.  * in the bingroup.rc file. For each group name listed, a seperate call to
  27.  * BINGRAB.CMD is called and a seperate server connection. This could 
  28.  * lead to a slow machine or even errors. I recommend limiting it to less 
  29.  * than 15, I have it set to 10. You can always create multiple .rc files
  30.  * that contain 10 - 15 names and run them at different times.
  31.  * I have included two utility programs. GROUPS.CMD will get a list of
  32.  * available BINARY groups from the server. This list then can be cut
  33.  * and pasted into the .rc files for BINGRAB.CMD. MOVE.CMD will move all
  34.  * jpg and gif files to a directory named the first characture of the file
  35.  * name. It will then delete any jpg or gif files left in the directory. This 
  36.  * should eliminate any duplicate named files. At this time I have no way
  37.  * to determine if there are duplicate pictures with different names.
  38.  * My experience has been that there are not to many.
  39.  * I hope you like the program. It is EMAILware, so drop me a line if you
  40.  * use it and let me know how you like it and what enhancements you 
  41.  * would like to see. I do not guarantee any further versions, but if any
  42.  * major bugs exist I will release an upgrade.
  43.  * 
  44.  * Thanks, CyberLord. CyberLord@Cyber-Wizard.Com
  45.  
  46. if chars() then key = SysGetKey('noecho')
  47.  *------------------------------------------------------------------*/
  48.  
  49. MINSIZE = 500 /*Minimum size of messages to download*/
  50. SOUND = 0 /*set to 0 if you don't like the beeps*/
  51. MAXGROUPS = 10 /*Maximum number of server connections*/
  52.  
  53. parse upper source env how self .
  54. parse arg arguments
  55.  
  56. /**************************************************************
  57. Catch breaks
  58. ***************************************************************/
  59. signal on halt
  60.  
  61. rc = Call_Sys_Funcs()
  62.  
  63. address cmd
  64. '@ECHO OFF'
  65.  
  66. rc = Title()
  67.  
  68. if how = 'FUNCTION' then do
  69.    /* we were started as a function call... */
  70.    /* start us again as a separate session and return. */
  71.    say "Started as a function call"
  72.    say "calling ourselves"
  73.    'START /C' self arguments
  74.    say "Returning to program that called us"
  75.    return 0
  76. end
  77.  
  78. parse arg server group new .
  79.  
  80. if new > 0 then do
  81.  
  82. rc = Call_Sys_Funcs()
  83.  
  84. rc = Title()
  85.  
  86. rc = Chk_Cmd_Line(server, group)
  87.  
  88. sock = Init_Sock_Funcs(server)
  89.  
  90. rc = Interact(sock, group, MINSIZE, SOUND)    /*Jump to interact function*/
  91.  
  92. /*------------------------------------------------------------------
  93.  * quittin' time!
  94.  *------------------------------------------------------------------*/
  95. rc = SendMessage(sock,"quit")
  96. rc = SockSoclose(sock)
  97.  
  98. uudeview.exe "+e .jpg.gif.tif -i" group||".uue" /*decode Jpeg and Gif files. If you are grabbing warez*/
  99.                                                             /*then change the .jpg.gif.tif to .exe.zip.arc or leave the*/
  100.                                                             /*+e .jpg.gif.tif out all together and it will decode all files*/ 
  101. rc = stream(group||".uue", 'c', 'close')
  102. del group||".uue"
  103.  
  104. exit
  105.  
  106. end /*if new > 0 from begining of program way way up at the top*/
  107.  
  108. else if lines(group) then do
  109. /*say lines(group)*/
  110. number = 0
  111. do while lines(group)
  112.     if number < MAXGROUPS then do
  113.     line = linein(group)
  114.     parse var line groupname .
  115.     'START /C' self server groupname 1
  116.     number = number + 1
  117.   end /*if number*/
  118.   else do
  119.     say "Max number of groups reached"
  120.     exit
  121.   end /*else do*/
  122. end /*do while lines*/
  123.  
  124. exit
  125. end /*else if do*/
  126.  
  127. else do
  128. say "ERROR: Command line arguments incorrect or RC file on command line not found in bingrab directory."
  129. exit 1
  130. end
  131.  
  132. /******************************/
  133. /*PROGRAM FUNCTIONS BELOW HERE*/
  134. /******************************/
  135.  
  136.  
  137. /********************************************
  138. Initialize socket functions
  139. ********************************************/
  140.  
  141. Init_Sock_funcs:    procedure expose !.
  142.  
  143. server = arg(1)
  144. /*------------------------------------------------------------------
  145.  * initialize socket function package
  146.  *------------------------------------------------------------------*/
  147.    /*load sockets functions if not loaded*/
  148.    if RxFuncQuery("SockLoadFuncs") then
  149.       do
  150.       rc = RxFuncAdd("SockLoadFuncs","RxSock","SockLoadFuncs")
  151.       rc = SockLoadFuncs()
  152.       end
  153.  
  154. /*------------------------------------------------------------------
  155.  * get address of server
  156.  *------------------------------------------------------------------*/
  157. rc = SockGetHostByName(server,"host.!")
  158. if (rc = 0) then
  159.    do
  160.    say "Unable to resolve server name" server
  161.    exit
  162.    end
  163.  
  164. server = host.!addr
  165.  
  166. /*------------------------------------------------------------------
  167.  * open socket
  168.  *------------------------------------------------------------------*/
  169. sock = SockSocket("AF_INET","SOCK_STREAM",0)
  170. if (sock = -1) then
  171.    do
  172.    say "Error opening socket:" errno
  173.    exit
  174.    end
  175.  
  176. /*------------------------------------------------------------------
  177.  * connect socket
  178.  *------------------------------------------------------------------*/
  179. server.!family = "AF_INET"
  180. server.!port   = 119
  181. server.!addr   = server
  182.  
  183. rc = SockConnect(sock,"server.!")
  184. if (rc = -1) then
  185.    Error(sock,rc,"Error connecting to server :" errno)
  186.  
  187. trc = GetResponse(sock)
  188. do i = 1 to line.0
  189.    say line.i
  190. end
  191.  
  192. return sock
  193.  
  194. /********************************************
  195. Check command line arguments for errors
  196. *********************************************/
  197.  
  198. Chk_Cmd_Line:    procedure expose !.
  199. server = arg(1)
  200. group = arg(2)
  201. if (server = "") then
  202.    do
  203.    say "Expecting a news server name to be passed as a parameter."
  204. if (group = "") then
  205.    do
  206.    say "Expecting a newsgroup to be passed as a parameter."
  207.    exit 1
  208.    end
  209.    end
  210.  
  211. if (group = "") then
  212.    do
  213.    say "Expecting a newsgroup to be passed as a parameter."
  214.    exit 1
  215.    end
  216.  
  217. return 0
  218.  
  219. /**********************************************
  220. Clear screen and write title
  221. ***********************************************/
  222.  
  223. Title:    procedure expose !.
  224.  
  225. call syscls
  226. say "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
  227. say "BINGRAB v0.2b Newsgroup Binaries Grabber"
  228. say "by Timothy Millea - CyberLord@Cyber-Wizard.com"
  229. say "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
  230.  
  231. return 0
  232.  
  233.  
  234. /*------------------------------------------------------------------
  235.  * Get files from group loop
  236.  *------------------------------------------------------------------*/
  237. Interact:        procedure expose !.
  238.    sock = arg(1)
  239.    group = arg(2)
  240.    MINSIZE = arg(3) /*Minimum size of messages to download*/
  241.    SOUND = arg(4) /*set to 1 if sound wanted, set to 0 if not*/
  242. say "Hit Q to exit.  Current message will be downloaded first."
  243. say "Trying slave function support..."
  244. trc = SendMessage(sock,"slave") /*try to use the slave command if server allows*/
  245. trc = GetResponse(sock)
  246. do i =1 to line.0
  247.     say line.i
  248. end /*do i*/
  249.  
  250. trc = SendMessage(sock,"group" group) /*change to desired group*/
  251. trc = GetResponse(sock)
  252.  
  253. do i = 1 to line.0
  254.          say line.i
  255. end /*do i*/
  256.  
  257. parse var line.1 code total begin end1 . /*here we get the total number of messages, the begining number and the end number*/
  258.  
  259. rccommand =  linein(group||'.rc')
  260. parse var rccommand rccode rctotal rcbegin rcend rcgroup /*here we read from the .rc file the last messages we recieved*/
  261.  
  262. if group = rcgroup then do /*if the group and the rcgroup match then continue*/
  263.   begin = rcend
  264.   begin = begin + 1
  265. end /*if*/
  266.  
  267. else if rcgroup != "" then do
  268.   say "Command line "GROUP" does not match with .rc file "RCGROUP
  269.   exit
  270. end /*else if*/
  271.  
  272. say "Last message number read " rcend
  273. say "Newest message number in group " end1
  274.  
  275. if begin > end1 then do 
  276.     say "No new messages in " group
  277.            call lineout group||'.rc', code (rcend-rcend) rcend rcend group, 1
  278.            call lineout group||'.rc'
  279.     return ""
  280. end
  281.  
  282. call lineout group||".uue", group,1
  283. call lineout group||".uue","~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
  284.  
  285.  
  286. call lineout group||'.rc', code (begin-begin) begin begin group, 1
  287. call lineout group||'.rc'
  288.  
  289. number = begin
  290. parse value syscurpos() with row col /*get the current cursor position*/
  291.  
  292. pos = syscurpos(row, col) /*position cursor where we found it*/
  293.  
  294. say "Getting header number " number
  295.  
  296. trc = SendMessage(sock, "head" number)
  297. trc = GetResponse(sock)
  298.  
  299. do i = 1 to line.0
  300. parse var line.i name lines .
  301. if name = "Lines:" then leave
  302. end /*do*/
  303.  
  304. do i = 1 to line.0
  305. parse var line.i subj subject
  306. if subj = "Subject:" then leave
  307. end /*do*/
  308.  
  309. if lines > MINSIZE then do
  310. say 'Waiting for duplicates file to be free...'
  311. do while stream('duplicates','c','open') <> 'READY:'
  312. call syssleep 1 /*just sit here and wait for dup file to be free*/
  313. end
  314.  
  315. say 'Checking for duplicates...'
  316.  
  317. do while lines("duplicates")
  318. dupsubj  =  linein("duplicates")
  319. if subject = dupsubj then do
  320. say "Duplicate Subject - Ignoring Message"
  321. if SOUND then do
  322.    call beep 400, 100
  323.    call beep 500, 100
  324. end /*if sound*/
  325. leave
  326. end /*if*/
  327. end /*do while*/
  328. say 'Closing dup file ... ' stream('duplicates','c','close')
  329.  
  330. end /*if lines*/
  331.  
  332. pos = syscurpos(row, col) /*position cursor where we found it*/
  333. say "                                                  "
  334. say "                                                  "
  335. say "                                                  "
  336. say "                                                  "
  337. say "                                                  "
  338. say "                                                  "
  339. if lines > MINSIZE & subject <> dupsubj then do
  340.  
  341. pos = syscurpos(row, col) /*position cursor where we found it*/
  342. say "Getting " lines "lines from message number " number 
  343.   trc = SendMessage(sock, "body" number)
  344.   trc = GetResponse(sock)
  345.   say "Writing " line.0 "lines..."
  346.   do i = 1 to line.0
  347.   call lineout group||".uue",line.i,1
  348.   end /*do i*/
  349.  
  350. say 'Updating group rc file...'
  351. call lineout group||'.rc', code (number-begin) begin number group, 1 /*don't want to write number out until message*/
  352. call lineout group||'.rc'                                                                /*is written to .uue file*/
  353.  
  354. do while stream('duplicates','c','open') <> 'READY:'
  355. call syssleep 1 /*just sit here and wait for dup file to be free*/
  356. end
  357.  
  358. say 'Updating duplicates file...'
  359. rc = stream('duplicates','c','seek <' 0) /*seek the end of file*/
  360. call lineout 'duplicates', subject /*write the subject and group to the dup file so we can track it*/
  361.  
  362. say 'Closing dup file... ' stream('duplicates','c','close')
  363.  
  364. pos = syscurpos(row, col) /*position cursor where we found it*/
  365. say "                                                  "
  366. say "                                                  "
  367. say "                                                  "
  368. say "                                                  "
  369. say "                                                  "
  370. say "                                                  "
  371.  
  372. end /*if lines > MINSIZE*/
  373.  
  374. else do
  375. call lineout group||'.rc', code (number-begin) begin number group, 1 /*write message number out to file*/
  376. call lineout group||'.rc'                                                                /*after header is read even if less than MINSIZE lines*/
  377. end /*else do*/
  378.  
  379. if chars() then key = SysGetKey('noecho')
  380. if key = 'q' | key = 'Q' then halt()
  381.  
  382.  
  383. do forever
  384.  
  385. /**************************************************************
  386. Catch breaks
  387. ***************************************************************/
  388. signal on halt
  389.  
  390. trc = SendMessage(sock, "next")
  391. trc = GetResponse(sock)
  392. parse var line.1 code number .
  393.  
  394. if code = 421 then do /*code 421 is an error that there are no more messages*/
  395. say line.1
  396. call lineout group||'.rc', code (rcend-rcend) rcend rcend group, 1
  397. call lineout group||'.rc'
  398. return ""
  399. end /*if number*/
  400.  
  401. pos = syscurpos(row, col) /*position cursor where we found it*/
  402. say "Getting header number " number
  403.  
  404. trc = SendMessage(sock, "head" number)
  405. trc = GetResponse(sock)
  406. do i = 1 to line.0
  407. parse var line.i name lines .
  408. if name = "Lines:" then leave
  409. end /*if*/
  410.  
  411. do i = 1 to line.0
  412. parse var line.i subj subject
  413. if subj = "Subject:" then leave
  414. end /*do*/
  415.  
  416. if lines > MINSIZE then do
  417. say 'Waiting for duplicates file to be free...'
  418. do while stream('duplicates','c','open') <> 'READY:'
  419. call syssleep 1
  420. end
  421.  
  422. say 'Checking for duplicates...'
  423.  
  424. do while lines("duplicates")
  425. dupsubj  =  linein("duplicates")
  426. if subject = dupsubj then do
  427. say "Duplicate Subject - Ignoring Message"
  428. if SOUND then do
  429.    call beep 400, 100
  430.    call beep 500, 100
  431. end /*if sound*/
  432. leave
  433. end /*if*/
  434. end /*do while*/
  435. say 'Closing dup file... ' stream('duplicates','c','close')
  436.  
  437. end /*if lines*/
  438.  
  439. pos = syscurpos(row, col) /*position cursor where we found it*/
  440. say "                                                  "
  441. say "                                                  "
  442. say "                                                  "
  443. say "                                                  "
  444. say "                                                  "
  445. say "                                                  "
  446. if lines > MINSIZE & subject <> dupsubj then do
  447.  
  448. pos = syscurpos(row, col) /*position cursor where we found it*/
  449. say "Getting " lines "lines from message number " number 
  450.   trc = SendMessage(sock, "body" number)
  451.   trc = GetResponse(sock)
  452.   say "Writing " line.0 "lines..."
  453.   do i = 1 to line.0
  454.   call lineout group||".uue",line.i
  455.   end /*do i*/
  456.  
  457. say 'Updating group rc file...'
  458. call lineout group||'.rc', code (number-begin) begin number group, 1 /*don't want to write number out until message*/
  459. call lineout group||'.rc'                                                                /*is written to .uue file*/
  460.  
  461. do while stream('duplicates','c','open') <> 'READY:'
  462. call syssleep 1 /*just sit here and wait for dup file to be free*/
  463. end
  464.  
  465. say 'Updating duplicates file...'
  466. rc = stream('duplicates','c','seek <' 0) /*seek end of file*/
  467. call lineout 'duplicates', subject /*write the subject and group to the dup file so we can track it*/
  468.  
  469. say 'Closing dup file... ' stream('duplicates','c','close')
  470.  
  471. pos = syscurpos(row, col) /*position cursor where we found it*/
  472. say "                                                  "
  473. say "                                                  "
  474. say "                                                  "
  475. say "                                                  "
  476. say "                                                  "
  477. say "                                                  "
  478. end /*if lines > MINSIZE*/
  479.  
  480. else do
  481. call lineout group||'.rc', code (number-begin) begin number group, 1 /*write message number out to file*/
  482. call lineout group||'.rc'                                                                /*after header is read even if less than MINSIZE lines*/
  483.  
  484. end /*else do*/
  485.  
  486. call lineout group||".uue","~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
  487. number = number + 1
  488.         
  489. if number > end1 then do
  490.     say "Finished processing newsgroup"
  491.     call lineout group||".uue"
  492.     leave
  493. end /*if*/
  494.  
  495. if chars() then key = SysGetKey('noecho')
  496. if key = 'q' | key = 'Q' then halt()
  497.  
  498. end /*do forever*/
  499. return ""
  500.  
  501.  
  502.  
  503. /*------------------------------------------------------------------
  504.  * close socket (and catch signals)
  505.  * this function is not working properly yet. It is supposed to run when
  506.  * ctrl-break is pressed so it will decode the uue file, delete it and then exit
  507.  * I will educate myself on signal traps and fix it sometime. :)
  508.  *------------------------------------------------------------------*/
  509. halt:
  510.  
  511. rc = SendMessage(sock,"quit")
  512. rc = SockSoClose(sock)
  513. if (rc = -1) then
  514.    do
  515.    say "Error on SockSoClose:" errno
  516.    exit
  517.    end
  518.  
  519. uudeview.exe "+e .jpg.gif -i" group||".uue" /*decode file*/
  520.  
  521. rc = stream(group||".uue", 'c', 'close') /*close and delete .uue file*/
  522. del group||".uue"
  523.  
  524. exit
  525.  
  526. /*------------------------------------------------------------------
  527.  * halting ...
  528.  *------------------------------------------------------------------*/
  529. Halting:
  530.    Error(sock,1,"error on line" sigl)
  531.  
  532. /*------------------------------------------------------------------
  533.  * exit with a message and return code
  534.  *------------------------------------------------------------------*/
  535. Error: procedure
  536.    sock = arg(1)
  537.    retc = arg(2)
  538.    msg  = arg(3)
  539.  
  540.    if (sock <> -1) then
  541.       rc = SockSoClose(sock)
  542.  
  543.    say msg
  544.  
  545.    exit retc
  546.  
  547. /*------------------------------------------------------------------
  548.  * get a line from the server
  549.  *------------------------------------------------------------------*/
  550. GetResponseLine: procedure expose !.
  551.    sock = arg(1)
  552.  
  553.    crlf = d2c(13) || d2c(10)
  554.  
  555.    if (symbol('!.buff') = "LIT") then
  556.       !.buff = ""
  557.  
  558.    do while (pos(crlf,!.buff) = 0)
  559.       rc = SockRecv(sock,"data",8000)
  560.       !.buff = !.buff || data
  561.    end
  562.  
  563.    p = pos(crlf,!.buff)
  564.  
  565.    line = substr(!.buff,1,p-1)
  566.    !.buff = substr(!.buff,p+2)
  567.  
  568.    return line
  569.  
  570. /*------------------------------------------------------------------
  571.  * get a response from the server
  572.  *------------------------------------------------------------------*/
  573. GetResponse:     procedure expose !. line.
  574.    sock = arg(1)
  575.  
  576.    moreids = "100 215 220 221 222 223 230 231"
  577.  
  578.    line.0 = 1
  579.    line.1 = GetResponseLine(sock)
  580.  
  581.    parse var line.1 rid .
  582.  
  583.    if (wordpos(rid,moreids) = 0) then
  584.       return ""
  585.  
  586. if rid = 223 then return "" /*error 223 (no message with that number) does not return to bingrab a blank line */
  587.                 /*with a '.' in it so we have to force it to return*/
  588.  
  589.    do forever
  590.       o = line.0 + 1
  591.  
  592.       line.o = GetResponseLine(sock)
  593.  
  594.       if (line.o = ".") then
  595.          return ""
  596.  
  597.       line.0 = o
  598.    end
  599.  
  600.    return ""
  601.  
  602. /*------------------------------------------------------------------
  603.  * send a string to the server
  604.  *------------------------------------------------------------------*/
  605. SendMessage:     procedure expose !.
  606.    sock = arg(1)
  607.    data = arg(2) || d2c(13) || d2c(10)
  608.  
  609.    len = length(data)
  610.    do while (len > 0)
  611.       i = SockSend(sock,data);
  612.  
  613.       if (errno <> 0) then
  614.          Error(-1,rc,"Error sending data to server.")
  615.  
  616.       if (i <= 0) then
  617.          Error(sock,100,"Server closed the connection.")
  618.  
  619.       data = substr(data,len+1)
  620.       len  = length(data)
  621.    end
  622.  
  623.    return 0
  624.  
  625. /*---------------------------------------------------------------------
  626.  * call sys functions
  627.  *---------------------------------------------------------------------*/
  628. Call_Sys_Funcs:    procedure expose !.
  629.  
  630.   call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  631.   call SysLoadFuncs
  632.  
  633.  return 0