Automatically reboot a TP-LINK TD-W8960N Modem through PHP script

I recently got a bit fed up of the ADSL2+ speeds I was getting and constant line resyncing. I thought I would set up a script to automatically reboot the modem when sleeping.

It turns out that previously it was very simply to reboot TP-LINK modems, but it has got a lot more difficult recently. This page, which I initially found through googling, lead me on a wild goose chase more then anything else. It turns out it was better to start from scratch, with the comments helping me to work out the username/password hashing.

One of the advantages with my script below, is I also capture the sync speeds, and you could use that to determine if the modem should be rebooted.

Naturally in my goto PHP language. Code below, simply modify username, password and modem IP.

	$username = 'admin';
	$password = 'XXXXXX';
	$ip = '';

	// code below
	$ip = "http://{$ip}/";
	$auth_enc =  base64_encode($username.':'.$password);
	$cookies = dirname(__FILE__).'/cookies-tplink.txt';
	//delete the existing cookie file, important
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
	curl_setopt($ch, CURLOPT_COOKIEFILE, $cookies);
	curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
	curl_setopt($ch, CURLOPT_COOKIE, 'Authorization=Basic '.$auth_enc.';path=/');
	curl_setopt($ch, CURLOPT_REFERER, $ip);
	curl_setopt($ch, CURLOPT_URL, $ip);
	$output = curl_exec($ch);
	//grab the connection information
	curl_setopt($ch, CURLOPT_URL, $ip.'info.html');
	$output = curl_exec($ch);

	preg_match_all('%<td class=\\\\"dataStyle\\\\">(\d*?)</td>%im', $output, $result, PREG_PATTERN_ORDER);
	$Upstream = $result[1][0];
	$Downstream = $result[1][1];
	//grab session key from reboot router page
	curl_setopt($ch, CURLOPT_URL, $ip.'resetrouter.html');
	$output = curl_exec($ch);
	if (preg_match('/var sessionKey=\'(.*?)\';/im', $output, $regs)) {
		$sessionKey = $regs[1];
	//reboot the modem
	if ($sessionKey && false) {
		curl_setopt($ch, CURLOPT_URL, $ip.'rebootinfo.cgi?sessionKey='.$sessionKey);
		$output = curl_exec($ch);
		echo "Modem has been rebooted\r\n";

Automatically start and run LabVIEW VI

Here is an AutoIT script and executable that takes a LabVIEW VI path, opens the VI and then runs the VI.

Script and download below.

#include <File.au3>

If $CmdLine[0] > 0 Then

; assume first parmaeter is the file and path of the VI
Local $sFilePath = $CmdLine[1]

Local $sDrive = "", $sDir = "", $sFilename = "", $sExtension = ""
Local $aPathSplit = _PathSplit($sFilePath, $sDrive, $sDir, $sFilename, $sExtension)

; generate the window title
Local $sTitle = $sFilename & $sExtension & " Front Panel"

; run the VI
ShellExecute($sFilePath )

; wait till the VI opens

; send CTRL-R to start to RUN


Open and Run LabVIEW VI AutoIt
Open and Run LabVIEW VI EXE

Use as follows;

open-run-labiew-vi.exe "C:\Users\UserName\Desktop\"

Photoshop VBScript to automatically resize images

Decided to learn Photoshop VBScripting, don’t know why I didn’t do this sooner, I now have scripts to automatically generate my blog thumbnails (as below), and add little Google Maps markers on them (see here).

A few constants to change in the script (edit with Notepad);

  • RESIZEWIDTH – thumbnail width
  • RESIZEHEIGHT – thumbnail height
  • IGNOREVERTICAL – should vertical (portrait) images be ignored (I like to do these manually as I crop them to landscape)
  • SUFFIX – thumbnail suffix

To run it, simply place the script in your image folder (make sure to take a backup) and execute the file.

Public Const RESIZEWIDTH = 150
Public Const RESIZEHEIGHT = 113

Public Const IGNOREVERTICAL = True
Public Const SUFFIX = "-th"

Dim spath
spath = Mid(WScript.ScriptFullName, 1, InStrRev(WScript.ScriptFullName, "\", -1, vbBinaryCompare))

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

Dim foldero
Set foldero = fso.GetFolder(spath)

Dim fileo
Dim sfile

For Each fileo In foldero.Files
    'only modify jpg files
    sfile = fileo.Name
    If InStrRev(sfile, ".jpg", -1, vbTextCompare) = Len(sfile) - 3 Then
        resize spath & sfile
    End If

MsgBox "Complete."

Sub resize(sfilename)

    Set WshShell = WScript.CreateObject("WScript.Shell")
    Set colProcessList = GetObject("Winmgmts:").ExecQuery("Select * from Win32_Process")

    Dim found
    found = False

    For Each objProcess In colProcessList
        If StrComp(objProcess.Name, "photoshop.exe", vbTextCompare) = 0 Then
            found = True
            Exit For
        End If

    Dim appRef
    If found Then
        Set appRef = GetObject(, "Photoshop.Application")
        Set appRef = CreateObject("Photoshop.Application")
    End If

    Do While appRef.documents.Count
       appRef.activeDocument.Close 2 'dont' save

    Dim originalRulerUnits
    originalRulerUnits = appRef.Preferences.RulerUnits
    appRef.Preferences.RulerUnits = 1 'pixels

    Dim docRef
    Set docRef = appRef.Open(sfilename)

    Dim modified
    modified = False

    If docRef.Width >= docRef.Height Then 'horizontal photo
            If docRef.Width <> RESIZEWIDTH Then 'proceed if not already resized
                docRef.ResizeImage RESIZEWIDTH 'preserves aspect ratio
                modified = True
            End If
    Else 'verticle photo
        If Not IGNOREVERTICAL Then 'proceed
            If docRef.Height <> RESIZEHEIGHT Then 'proceed if not already resized
                docRef.ResizeImage , RESIZEHEIGHT 'preserves aspect ratio
                modified = True
            End If
        End If
    End If

    If modified Then 'only save if the image was modified
        Dim jpgSaveOptions
        Set jpgSaveOptions = CreateObject("Photoshop.JPEGSaveOptions")
        jpgSaveOptions.Quality = 8

        'calculate the new file name
        Dim newfilename
        newfilename = Mid(sfilename, 1, Len(sfilename) - 4) & SUFFIX & ".jpg"

        docRef.SaveAs newfilename, jpgSaveOptions, True, 2 'for psLowercase
    End If

    docRef.Close 2 'dont' save

    appRef.Preferences.RulerUnits = originalRulerUnits

End Sub

In search of the elusive Google default marker

For a number of years now I have been developing a Google Maps plugin for WordPress <end of plug>, I have even created a script to dynamically generate coloured markers with custom text. This is a great solution for hosting your own markers, but is has a lot of overhead, having to host a custom Arial font and requiring the PHP GD library installed. And even then, I still relied on Google to provide the starting coloured marker .

Google does provide an alternative, custom text and colour, but there is one problem, what if I want the classic default Google Map’s marker default marker, the one with the large black dot. Well it isn’t there. And that is where my script, dare I say, exceeded Google.

The trick was adding the large black dot to the font. You know that ugly square box you sometimes see when you don’t have the correct fonts installed square box marker, I simply replaced this with the large black dot. Any character codes that aren’t available will simply return the default style marker default marker with my script.

So that’s my implementation, but how do I migrate from my script to Google’s while keeping the default style marker. I had to find an equivalent. All the obvious choices (bullet U+2022, bullet operator U+2219 and black circle U+25CF) didn’t work.

I started sifting through thousands of markers, looking for the closest representation to the default marker. What I found was kangxi radical one U+2F00, now don’t ask me why, but for some reason this produced a black dot style marker close enough default marker, though smaller than the default. This would have to do.

collection of markers

5000+ markers in a 1mb+ png file
5000+ markers in a html page (file name is the unicode)

Note: all above inline marker examples are hosted on Google or generated with my script (view the image name to find out more).

WordPress hacked – broken or blank refreshing admin/dashboard

Recently, my Linux Go Daddy hosting servicing all three of my WordPress blogs were somehow accessed and malicious code inserted into every one of my php files.

The symptoms include;

  • A similar error in your RSS feed Warning: gzuncompress() [function.gzuncompress]: data error in /home/content/t/h/y/thydzik/html/blog/wp-includes/http.php on line 1818.
  • A broken Admin/Dashboard. This is due to the addition of the malicious script on the dynamic CSS files.
  • The Admin/Dashboard refreshes to a blank screen. This is due to the malicious script redirecting to other page.

What to look for;

  • The following code (truncated) inserted into all your php files;
<?php /**/ eval(base64_decode("aWYoZnVuY3Rpb25fZXhpc3RzKCdvYl...=="));?>
  • The following code when you view the source code in a browser;
<iframe src="" width=1 height=1 frameborder=0></iframe>

What to do;

  • Change all your passwords.
  • Backup the ENTIRE site to local computer.
  • Cleanup all affected php files (it doesn’t seem to do anything to other file types). See below.
  • Re-upload your site.

Now to make things easier, I have created a VBS script that will automate the cleanup task. Place it in your local root director and run. A log file will be generated at C:\cleanUpWordPressPHP.txt listing the files it has cleaned.

Download the VBS script cleanUpWordPressPHP.vbs (right-click save-as)

Further information can be found on this Google support thread.