2011-12-28 19 views
1

代碼:CGI C的輸出校正,但不能從網絡請求

<table id="hddtemp"> 
    <tr> 
     <th>Device</th> 
     <th>Mfg</th> 
     <th>Model</th> 
     <th>Temp</th> 
    </tr> 
    <tr> 
     <td>sda</td> 
     <td>WDC</td> 
     <td>WD2500AAKX-001CA0</td> 
     <td>29&deg;C</td> 
    </tr> 
    <tr> 
     <td>sdb</td> 
     <td>WDC</td> 
     <td>WD20EURS-63S48Y0</td> 
     <td>30&deg;C</td> 
    </tr> 
    <tr> 
     <td>sdc</td> 
     <td>WDC</td> 
     <td>WD20EURS-63S48Y0</td> 
     <td>30&deg;C</td> 
    </tr> 
    <tr> 
     <td>sdd</td> 
     <td>WDC</td> 
     <td>WD20EURS-63S48Y0</td> 
     <td>30&deg;C</td> 
    </tr> 
</table> 

:從命令行www-data用戶運行時

#include <unistd.h> 
#include <stdio.h> 

typedef struct hddinfo 
{ 
    char szDevice[4]; 
    char szMfg[64]; 
    char szModel[64]; 
    int nTemp; 
} hddinfo; 

int main(int argc, char *argv[]) 
{ 

    setuid(0); 

    hddinfo hdi[4] = {0}; 

    FILE *fp = popen("/usr/sbin/hddtemp /dev/sd[abcd]","r"); 
    if(NULL != fp) 
    { 

     for(int i = 0; i < 4; i++) 
      fscanf(fp,"/dev/%3[^:]: %64s %64[^:]: %d°C\n",&hdi[i].szDevice, &hdi[i].szMfg, &hdi[i].szModel, &hdi[i].nTemp); 

     pclose(fp); 

     printf("Content-type: text/html\n\n"); 
     printf("<table id=\"hddtemp\">\n\t<tr>\n\t\t<th>Device</th>\n\t\t<th>Mfg</th>\n\t\t<th>Model</th>\n\t\t<th>Temp</th>\n\t</tr>\n"); 
     for(int i = 0; i < 4; i++) 
      printf("\t<tr>\n\t\t<td>%s</td>\n\t\t<td>%s</td>\n\t\t<td>%s</td>\n\t\t<td>%d&deg;C</td>\n\t</tr>\n", hdi[i].szDevice, hdi[i].szMfg, hdi[i].szModel, hdi[i].nTemp); 
     printf("</table>"); 

    } 
    else 
     printf("Status: 400 Bad Request\nContent-type: text/html\n\n"); 

    return 0; 
} 

輸出通過網絡瀏覽器訪問時輸出:

<table id="hddtemp"> 
    <tr> 
     <th>Device</th> 
     <th>Mfg</th> 
     <th>Model</th> 
     <th>Temp</th> 
    </tr> 

    <tr> 
     <td>sda</td> 
     <td>WDC</td> 
     <td>WD2500AAKX-001CA0</td> 
     <td>29&deg;C</td> 
    </tr> 

    <tr> 
     <td></td> 
     <td></td> 
     <td></td> 
     <td>0&deg;C</td> 
    </tr> 
    <tr> 
     <td></td> 

     <td></td> 
     <td></td> 
     <td>0&deg;C</td> 
    </tr> 
    <tr> 
     <td></td> 
     <td></td> 
     <td></td> 

     <td>0&deg;C</td> 
    </tr> 
</table> 

回答

2

看起來您的fscanf調用(度數標誌)有非ASCII格式。

由於在CGI中執行時由於LANG=C而導致解析停止的可能性很大,而在命令行上執行時則設置爲其他值。

+0

啊!!!!現在我明白了爲什麼在從命令行運行時輸入程度符號,而不是當它被管道或從Web服務調用時。看起來'hddtemp'正在檢查'LANG'環境變量並確定是否放置度符號。因此,如果我已將命令調用更改爲'LANG = C/user/sbin/hddtemp/dev/sd [abcd]「',並且刪除了度符號,則它可以用於兩者! – 2011-12-28 05:26:29

1

好吧,所以我發現了這個問題......顯然,無論何時apache運行一個web請求程序,程度字符都不包含在內,而空格字符則包含在內。我也可以通過管道將輸出到另一個應用程序,像這樣複製的命令行這一問題:

./hddtemp.cgi | tee 

卸下度字符修復了網頁請求的輸出,但隨後出現該問題上的命令行調用。看起來我被困在一個或另一個工作。

+0

一個更好的選擇似乎是爲我指定' - hddtemp'上的'--numeric'標誌,但這確實意味着我失去了製造商和SKU /模型 – 2011-12-28 04:59:10

+0

感謝您在解決您自己的問題,並張貼你對別人的想法。 – dicaprio 2011-12-28 05:42:22