Thttpd_上傳文件

/*
     thttpd上傳文件
     接收文件在thttpd內部完成
     // 參考文獻
*/
enum
{
    STATE_START,
    STATE_GET_SIGN_CODE,
    STATE_GET_FILE_NAME,
    STATE_GET_FILE_START,
    STATE_GET_FILE_CONTENT,
    STATE_CHECK_END,
    STATE_END
};

#define DEAL_BUF_LEN  2048
#define SIGN_CODE_LEN 100
#define FILE_NAME_LEN 64
#define FILE_SAVE_DIR "/dev/"
#if 0
static void ShowErrorInfo(char * error)  
{  
        printf("Content-Type:text/html;charset=UTF-8\n\n");  
        printf("<center><font color='red'>%s</font></center>" , error );  
}  
#endif

int upload_file_2(int socked, httpd_conn *hc)
{
        FILE *fp; /* 文件指針,保存我們要獲得的文件 */  
        int getState = STATE_START;  
        int contentLength;/*標準輸入內容長度*/  
        int nowReadLen;  
        int signCodeLen;  
        int tmpLen;  
    int content_len = 0;
    int upgrade_file_size = 0;
        char *nowReadP = NULL;  
        char *nowWriteP = NULL;  
        char dealBuf[DEAL_BUF_LEN];  
        char signCode[SIGN_CODE_LEN]; /*存儲本次的特徵碼*/  
        char tmpSignCode[SIGN_CODE_LEN];  
        char fileName[FILE_NAME_LEN];  
    char content_buffer[4096] = {0};
    FILE *web_fd = fdopen(hc->conn_fd, "w+");

        memset(dealBuf,0,DEAL_BUF_LEN);  
        memset(signCode,0,SIGN_CODE_LEN);  
        memset(fileName,0,FILE_NAME_LEN);  
        nowReadLen = 0;  

        if ((char *)getenv("CONTENT_LENGTH")!=NULL) {  
                contentLength = atoi((char *)getenv("CONTENT_LENGTH"));  
                upgrade_file_size = contentLength;
        } else {  
                exit(1);  
        }  

        while (contentLength > 0) {  
                if (contentLength >= DEAL_BUF_LEN) {  
                        nowReadLen = DEAL_BUF_LEN;  
                } else {  
                        nowReadLen = contentLength;  
                }  

                contentLength -= nowReadLen;  
                // CGI程序適用
                //if(fread(dealBuf,sizeof(char),nowReadLen,stdin) != nowReadLen)  
                // thttpd內部接收需要使用socket直接接收
                if (read(socked, dealBuf, nowReadLen) != nowReadLen) {  
                        exit(1);  
                }  
                nowReadP = dealBuf;  
                while (nowReadLen > 0) {  
                        switch (getState) {  
                        case STATE_START:  
                                nowWriteP = signCode;  
                                getState = STATE_GET_SIGN_CODE;  
                        case STATE_GET_SIGN_CODE:  
                                if (strncmp(nowReadP, "\r\n",2) == 0) {  
                                        signCodeLen = nowWriteP - signCode;  
                                        nowReadP++;  
                                        nowReadLen--;  
                                        *nowWriteP = 0;  
                                        getState = STATE_GET_FILE_NAME;  
                                        //ShowErrorInfo(signCode);  
                                } else {  
                                        *nowWriteP = *nowReadP;  
                                        nowWriteP++;  
                                }  
                                break;  

                                case STATE_GET_FILE_NAME:  
                                if (strncmp(nowReadP, "filename=", strlen("filename=")) == 0) {  
                                        nowReadP += strlen("filename=");  
                                        nowReadLen -= strlen("filename=");  
                                        nowWriteP = fileName + strlen(FILE_SAVE_DIR);  
                                        while (*nowReadP != '\r') { 
                                                if (*nowReadP == '\\' || *nowReadP == '/') { 
                                                        nowWriteP = fileName + strlen(FILE_SAVE_DIR); 
                                                } else if (*nowReadP != '\"') { 
                                                        *nowWriteP = *nowReadP; 
                                                        nowWriteP++; 
                                                } 
                                                nowReadP++; 
                                                nowReadLen--; 
                                        } 
                                        *nowWriteP = 0; 
                                        nowReadP++; 
                                        nowReadLen--; 
                                        getState = STATE_GET_FILE_START; 
                                        memcpy(fileName,FILE_SAVE_DIR,strlen(FILE_SAVE_DIR)); 
                                        if ((fp=fopen(fileName, "w"))==NULL) { 
                                                exit(1); 
                                        } 
                                        //ShowErrorInfo(fileName); 
                                } 
                                break; 

                                case STATE_GET_FILE_START: 
                                if (strncmp(nowReadP, "\r\n\r\n", 4) == 0) { 
                                        nowReadP += 3; 
                                        nowReadLen -= 3; 
                                        getState = STATE_GET_FILE_CONTENT; 
                                        //ShowErrorInfo("get"); 
                                } 
                                break; 

                                case STATE_GET_FILE_CONTENT: 
                                if (*nowReadP != '\r') { 
                                        fputc(*nowReadP,fp); 
                                } else { 
                                        if (nowReadLen >= (signCodeLen + 2)) { 
                                                if (strncmp(nowReadP + 2,signCode,signCodeLen) == 0) { 
                                                        getState = STATE_END; 
                                                        nowReadLen = 1; 
                                                } else { 
                                                        fputc(*nowReadP,fp); 
                                                } 
                                        } else { 
                                                getState = STATE_CHECK_END; 
                                                nowWriteP = tmpSignCode; 
                                                *nowWriteP = *nowReadP; 
                                                nowWriteP++; 
                                                tmpLen = 1; 
                                        } 
                                } 
                                break; 

                                case STATE_CHECK_END: 
                                if (*nowReadP != '\r') { 
                                        if (tmpLen < signCodeLen + 2) { 
                                                *nowWriteP = *nowReadP; 
                                                nowWriteP++; 
                                                tmpLen++; 
                                                if (tmpLen == signCodeLen + 2) { 
                                                        *nowWriteP = 0; 
                                                        if ((tmpSignCode[1] == '\n')&&(strncmp(tmpSignCode + 2,signCode,signCodeLen) == 0)) { 
                                                                getState = STATE_END; 
                                                                nowReadLen = 1; 
                                                        } else  {  
                                                                fwrite(tmpSignCode,sizeof(char),tmpLen,fp);  
                                                                getState = STATE_GET_FILE_CONTENT;  
                                                        }  
                                                }  
                                        }  
                                } else {  
                                        *nowWriteP = 0;  
                                        fwrite(tmpSignCode,sizeof(char),tmpLen,fp);  
                                        nowWriteP = tmpSignCode;  
                                        *nowWriteP = *nowReadP;  
                                        nowWriteP++;  
                                        tmpLen = 1;  
                                }  
                                break;

                                case STATE_END:  
                                        nowReadLen = 1;  
                                break;  

                                default:break;  
                        }  
                        nowReadLen--;  
                        nowReadP++;  
                }         
        } 

        if (fp != NULL) {  
                fclose(fp);  
                fp = NULL;
        } 

#if 1    // add by xxx 20160321 新增文件升級功能
    // 1. 反饋傳輸完成
    fprintf(web_fd, "HTTP/1.0 200 OK\r\n");
    fprintf(web_fd, "Cache-Control: no-cache\r\n");
    fprintf(web_fd, "Content-Type: text/html\r\n");
    fprintf(web_fd, "Connection: close\r\n");

    content_len = sprintf(content_buffer,
    "<html><head><title></title>\r\n"
    "<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\r\n"
    "</head><body>\n\n"
    "File upload to complete!\n\n"
    "</body></html>\r\n");

    fprintf(web_fd, "Content-Length: %d\r\n\r\n%s", strlen(content_buffer), content_buffer);

    // 反饋給upgrade升級
    system("touch /dev/onvif_upgrade_flag");
#endif

        return 0;   
}


發佈了112 篇原創文章 · 獲贊 56 · 訪問量 36萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章