"I'm currently in the process of customizing the firmware for a RAID controller used in some of my company's products," jspenguin wrote, "The LCD Controller Module (LCM) is written in PHP and, as it turns out, an LCM is not quite what PHP was designed for. In addition to abusing exec() all over the place, they poorly re-implement functions that are built-in to PHP."

function strcenter($string, $len = LCM_ROW_LEN)
{
    //printf("%s\n", __FUNCTION__);
    $size = strlen($string);
    if ($size > $len) return $string;

    $divisor = ($len - $size) / 2;
    
    unset($new_str);
    for ($i = 0; $i < $divisor; $i++) {
        $new_str .= " ";
    }

    $new_str .= sprintf("%s", $string);
    
    for ($i = strlen($new_str); $i < $len; $i++) {
        $new_str .= " ";
    }
    //$test = strlen($new_str);
    //echo "len = $test\n";
    return $new_str;
}

function strleft($string, $len = LCM_ROW_LEN)
{
    //printf("%s\n", __FUNCTION__);
    $size = strlen($string);
    if ($size > $len) return $string;

    $remainder = $len - $size;
    
    unset($new_str);
    $new_str .= sprintf("%s", $string);
    
    for ($i = 0; $i < $remainder; $i++) {
        $new_str .= " ";
    }
    //$test = strlen($new_str);
    //echo "len = $test\n";
    return $new_str;
}


 function LCM_get_base_position($length, $tag=TAG_NONE)
{
    for ($i = 0; $i < $length; $i++) {
        $string .= "X";
    }
    
    switch ($tag) {
    case TAG_ENT:
    case TAG_SCROLL:
        $max = LCM_ROW_LEN - 1;
        break;
    case TAG_SCROLL_ENT:
    case TAG_UP_ENT:
    case TAG_DN_ENT:
        $max = LCM_ROW_LEN - 2;
        break;
    case TAG_NONE:
    default:
        break;
    }

    $string = strcenter($string, $max);
    //printf("%s: str = %s, max = %d, length = %d\n", __FUNCTION__, $string, $max, $length);
    $pos = strpos($string, 'X');
    
    if ($pos == false) {
        printf("%s: Failed to get postion\n", __FUNCTION__);
    } else {
        return $pos;
    }
}

jspenguin continued, "I especially like the sprintf("%s", $string). As for their exec() abuse..."

function alarm_mute()
{
    //exec("echo 0 > /proc/ems/alarm/tone; echo 0 > /proc/ems/system/error_led");
    exec("echo 0 > /proc/ems/alarm/tone");
}


 function GetIfaceInfo(&$config, &$address, &$submask, &$gateway, &$dns)
{
    $dhcp_cmd = "grep \"iface eth0 inet dhcp\" /etc/network/interfaces";
    exec($dhcp_cmd, $a1);
    if ( count($a1) == 1 ) {
        $config = "dhcp";
    } else {
        $config = "static";
    }

    $get_addr_cmd = "ifconfig eth0 | awk '$1 ~ /inet/{print $2}' | awk -F: '{print $2}'";
    exec($get_addr_cmd, $temp);
    $address_string = $temp[0];
    GetIfaceforIP($gateway_string, $submask_string,$dns_string);
    TransIfaceInfo($address_string, $address);
    TransIfaceInfo($submask_string, $submask);
    TransIfaceInfo($gateway_string, $gateway);
    TransIfaceInfo($dsn_string, $dns);
}

"And as a bonus, due in no small part to the kernel module, exec() is slow. Really slow. It takes nearly a whole second to fork and execute a process. This means it takes two or three seconds to write a single event to the log. So, if there was a problem that affected all eight hard drives -- say, a power issue -- this is what will happen:

  1. LCM reports the first drive failure and starts alarming.
  2. User presses the Mute button and, three second later, the beeping stops. 
  3. Seconds later, LCM repors the second drive failure and start alarming.
  4. User presses the Mute button and, three second later, the beeping stops. 
  -- snip --
  16. User presses the Mute button and, three second later, the beeping stops. For good.

"I doubt anyone actually makes it until the last step, though. It's much easier to just yank the power plug in frustration."