| 7272 | } |
| 7273 | |
| 7274 | static int zipfileGetMode( |
| 7275 | sqlite3_value *pVal, |
| 7276 | int bIsDir, /* If true, default to directory */ |
| 7277 | u32 *pMode, /* OUT: Mode value */ |
| 7278 | char **pzErr /* OUT: Error message */ |
| 7279 | ){ |
| 7280 | const char *z = (const char*)sqlite3_value_text(pVal); |
| 7281 | u32 mode = 0; |
| 7282 | if( z==0 ){ |
| 7283 | mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644)); |
| 7284 | }else if( z[0]>='0' && z[0]<='9' ){ |
| 7285 | mode = (unsigned int)sqlite3_value_int(pVal); |
| 7286 | }else{ |
| 7287 | const char zTemplate[11] = "-rwxrwxrwx"; |
| 7288 | int i; |
| 7289 | if( strlen(z)!=10 ) goto parse_error; |
| 7290 | switch( z[0] ){ |
| 7291 | case '-': mode |= S_IFREG; break; |
| 7292 | case 'd': mode |= S_IFDIR; break; |
| 7293 | case 'l': mode |= S_IFLNK; break; |
| 7294 | default: goto parse_error; |
| 7295 | } |
| 7296 | for(i=1; i<10; i++){ |
| 7297 | if( z[i]==zTemplate[i] ) mode |= 1 << (9-i); |
| 7298 | else if( z[i]!='-' ) goto parse_error; |
| 7299 | } |
| 7300 | } |
| 7301 | if( ((mode & S_IFDIR)==0)==bIsDir ){ |
| 7302 | /* The "mode" attribute is a directory, but data has been specified. |
| 7303 | ** Or vice-versa - no data but "mode" is a file or symlink. */ |
| 7304 | *pzErr = sqlite3_mprintf("zipfile: mode does not match data"); |
| 7305 | return SQLITE_CONSTRAINT; |
| 7306 | } |
| 7307 | *pMode = mode; |
| 7308 | return SQLITE_OK; |
| 7309 | |
| 7310 | parse_error: |
| 7311 | *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z); |
| 7312 | return SQLITE_ERROR; |
| 7313 | } |
| 7314 | |
| 7315 | /* |
| 7316 | ** Both (const char*) arguments point to nul-terminated strings. Argument |
no outgoing calls
no test coverage detected