Changeset 959 for trunk/client
- Timestamp:
- Aug 16, 2016, 5:35:07 PM (9 years ago)
- Location:
- trunk/client/src
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/client/src/debug.c
r957 r959 43 43 int debuglvl(int level) 44 44 { 45 return (level <= debuglevel) ? 1 : 0;45 return (level <= debuglevel) ? 1 : 0; 46 46 } 47 47 … … 79 79 } 80 80 else 81 {82 81 strncat(logfile, logfilename, sizeof(logfile) -1); 83 }82 84 83 // set the samba logging stuff 85 84 do_logging = TRUE; … … 88 87 rc = DosCreateMutexSem(nameMutex, &logMutex, 0, FALSE); 89 88 if (rc == ERROR_DUPLICATE_NAME) 90 { 91 rc = DosOpenMutexSem(nameMutex, &logMutex); 92 } 89 rc = DosOpenMutexSem(nameMutex, &logMutex); 93 90 94 91 return; … … 107 104 // do we have to log at all 108 105 if (!do_logging) 109 { 110 return; 111 } 106 return; 112 107 113 108 // if the sem is created we request it 114 109 if (logMutex) 115 {116 110 DosRequestMutexSem(logMutex, (ULONG) SEM_INDEFINITE_WAIT); 117 }118 111 119 do 120 { 121 struct timeval tv; 122 char buf[80] = {0}; 123 va_list args; 124 if (logfile[0]) 125 { 126 f = fopen(logfile, "a"); 127 if (!f) 128 { 129 break; 130 } 131 } 132 else 133 { 134 f = stdout; 135 } 112 do { 113 struct timeval tv; 114 char buf[80] = {0}; 115 va_list args; 116 if (logfile[0]) 117 { 118 f = fopen(logfile, "a"); 119 if (!f) 120 break; 121 } 122 else 123 f = stdout; 136 124 137 // in the first log line we write our version of the client138 if (firstLogLine)139 {140 fprintf(f, "Samba client %s build %s based on %s\n", VERSION, BUILD, smbwrp_getVersion());141 fprintf(f, "This build is maintained by %s\n", VENDOR);142 firstLogLine = FALSE;143 }125 // in the first log line we write our version of the client 126 if (firstLogLine) 127 { 128 fprintf(f, "Samba client %s build %s based on %s\n", VERSION, BUILD, smbwrp_getVersion()); 129 fprintf(f, "This build is maintained by %s\n", VENDOR); 130 firstLogLine = FALSE; 131 } 144 132 145 gettimeofday(&tv, NULL); 146 strftime(buf,sizeof(buf)-1,"%Y/%m/%d %H:%M:%S", localtime((time_t *)&tv.tv_sec)); 147 fprintf(f, "%s.%d: %d %d: ", buf, tv.tv_usec / 10000, level, (long)_gettid()); 148 va_start(args, fmt); 149 vfprintf(f, fmt, args); 150 va_end(args); 151 if (logfile) 152 { 153 // fflush(f); 154 fclose(f); 155 } 156 } 157 while (0); 133 gettimeofday(&tv, NULL); 134 strftime(buf,sizeof(buf)-1,"%Y/%m/%d %H:%M:%S", localtime((time_t *)&tv.tv_sec)); 135 fprintf(f, "%s.%d: %d %d: ", buf, tv.tv_usec / 10000, level, (long)_gettid()); 136 va_start(args, fmt); 137 vfprintf(f, fmt, args); 138 va_end(args); 139 if (logfile) 140 fclose(f); 141 142 } while (0); 158 143 159 144 // if the sem is created we release it 160 145 if (logMutex) 161 {162 146 DosReleaseMutexSem(logMutex); 163 }164 147 165 148 return; -
trunk/client/src/ndpsmb.c
r957 r959 32 32 #include "util.h" 33 33 34 #define debug_printf(...) debuglocal(9, __VA_ARGS__)35 36 34 // ------------------------------------------------------------- 37 35 … … 43 41 void fsphUnixTimeToDosDate( time_t time, FDATE* fdate, FTIME *ftime) 44 42 { 45 struct tm* gmt = localtime( &time);43 struct tm* gmt = localtime( &time); 46 44 #if 0 // as localtime() already does dst we don't need to add something 47 if (gmt->tm_isdst>0) { 48 debug_printf( "daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone); 49 time -= 3600; 50 gmt = localtime( &time); 51 } 45 if (gmt->tm_isdst>0) 46 { 47 debuglocal(9, "daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone); 48 time -= 3600; 49 gmt = localtime( &time); 50 } 52 51 #endif 53 fdate->day = gmt->tm_mday;54 fdate->month = gmt->tm_mon+1;55 fdate->year = gmt->tm_year + 1900 - 1980;56 ftime->twosecs = gmt->tm_sec/2;57 ftime->minutes = gmt->tm_min;58 ftime->hours = gmt->tm_hour;52 fdate->day = gmt->tm_mday; 53 fdate->month = gmt->tm_mon+1; 54 fdate->year = gmt->tm_year + 1900 - 1980; 55 ftime->twosecs = gmt->tm_sec/2; 56 ftime->minutes = gmt->tm_min; 57 ftime->hours = gmt->tm_hour; 59 58 } 60 59 61 60 void fsphDosDateToUnixTime( FDATE fdate, FTIME ftime, ULONG* time) 62 61 { 63 struct tm gmtime = { 0 };64 65 debug_printf("fsphDosDateToUnixTime time %02d:%02d:%02d\n", ftime.hours, ftime.minutes, ftime.twosecs*2);66 gmtime.tm_mday = fdate.day;67 gmtime.tm_mon = fdate.month-1;68 gmtime.tm_year = fdate.year + 1980 - 1900;69 gmtime.tm_sec = ftime.twosecs*2;70 gmtime.tm_min = ftime.minutes;71 gmtime.tm_hour = ftime.hours;72 gmtime.tm_isdst = -1; // force libc to check dst saving73 74 *time = mktime( &gmtime);75 debug_printf("fsphDosDateToUnixTime time1 %d %s", *time, ctime( (time_t*)time));62 struct tm gmtime = { 0 }; 63 64 debuglocal(9, "fsphDosDateToUnixTime time %02d:%02d:%02d\n", ftime.hours, ftime.minutes, ftime.twosecs*2); 65 gmtime.tm_mday = fdate.day; 66 gmtime.tm_mon = fdate.month-1; 67 gmtime.tm_year = fdate.year + 1980 - 1900; 68 gmtime.tm_sec = ftime.twosecs*2; 69 gmtime.tm_min = ftime.minutes; 70 gmtime.tm_hour = ftime.hours; 71 gmtime.tm_isdst = -1; // force libc to check dst saving 72 73 *time = mktime( &gmtime); 74 debuglocal(9, "fsphDosDateToUnixTime time1 %d %s", *time, ctime( (time_t*)time)); 76 75 #if 0 // as mktime() already does dst we don't need to add something 77 struct tm* gmt; 78 gmt = localtime( (time_t*) time); 79 if (gmt->tm_isdst>0) { 80 debug_printf( "fsphDosDateToUnixTime daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone); 81 *time += 3600; 82 } 83 debug_printf( "fsphDosDateToUnixTime time2 %d %s", *time, ctime( (time_t*)time)); 76 struct tm* gmt; 77 gmt = localtime( (time_t*) time); 78 if (gmt->tm_isdst>0) 79 { 80 debuglocal(9, "fsphDosDateToUnixTime daylight saving in effect %d, timezone %d\n",gmt->tm_isdst, timezone); 81 *time += 3600; 82 } 83 debuglocal(9, "fsphDosDateToUnixTime time2 %d %s", *time, ctime( (time_t*)time)); 84 84 #endif 85 85 } … … 90 90 const char *NdpTypes[] = 91 91 { 92 "SMBFS",93 NULL92 "SMBFS", 93 NULL 94 94 } 95 95 ; … … 100 100 static const NDPROPERTYINFO smbProperties[] = 101 101 { 102 {ND_PROP_STRING, 0, "WORKGROUP", ""},103 {ND_PROP_STRING, 0, "SERVER", ""},104 {ND_PROP_STRING, 0, "SHARE", ""},105 {ND_PROP_STRING, 0, "USER", "guest"},106 {ND_PROP_STRING, 0, "PASSWORD", ""},107 {ND_PROP_STRING, 0, "SPASSWORD", ""},108 {ND_PROP_STRING, 0, "MASTER", "WORKGROUP"},109 {ND_PROP_ULONG, 0, "MASTERTYPE", "1"},110 {ND_PROP_ULONG, 0, "CTO", "10"},111 {ND_PROP_ULONG, 0, "CLD", "32"},112 {ND_PROP_ULONG, 0, "EASUPPORT", "1"},113 {ND_PROP_STRING, 0, NULL, NULL}102 {ND_PROP_STRING, 0, "WORKGROUP", ""}, 103 {ND_PROP_STRING, 0, "SERVER", ""}, 104 {ND_PROP_STRING, 0, "SHARE", ""}, 105 {ND_PROP_STRING, 0, "USER", "guest"}, 106 {ND_PROP_STRING, 0, "PASSWORD", ""}, 107 {ND_PROP_STRING, 0, "SPASSWORD", ""}, 108 {ND_PROP_STRING, 0, "MASTER", "WORKGROUP"}, 109 {ND_PROP_ULONG, 0, "MASTERTYPE", "1"}, 110 {ND_PROP_ULONG, 0, "CTO", "10"}, 111 {ND_PROP_ULONG, 0, "CLD", "32"}, 112 {ND_PROP_ULONG, 0, "EASUPPORT", "1"}, 113 {ND_PROP_STRING, 0, NULL, NULL} 114 114 }; 115 115 … … 118 118 const NDPROPERTYINFO *NdpPropertiesInfo[] = 119 119 { 120 smbProperties120 smbProperties 121 121 }; 122 122 … … 130 130 static int lockInit (void) 131 131 { 132 return ph->fsphCreateMutex (&mutex);132 return ph->fsphCreateMutex (&mutex); 133 133 } 134 134 135 135 static void lockClose (void) 136 136 { 137 ph->fsphCloseMutex (mutex);137 ph->fsphCloseMutex (mutex); 138 138 } 139 139 140 140 static int lockRequest (void) 141 141 { 142 return ph->fsphRequestMutex (mutex, SEM_INDEFINITE_WAIT);142 return ph->fsphRequestMutex (mutex, SEM_INDEFINITE_WAIT); 143 143 } 144 144 145 145 static void lockRelease (void) 146 146 { 147 ph->fsphReleaseMutex (mutex);147 ph->fsphReleaseMutex (mutex); 148 148 } 149 149 150 150 #if LIBSMB_THREAD_SAFE==0 151 151 152 #define ENTER() do { \153 int rcLock = lockRequest();\154 if (rcLock != NO_ERROR)\155 return rcLock;\152 #define ENTER() do { \ 153 int rcLock = lockRequest(); \ 154 if (rcLock != NO_ERROR) \ 155 return rcLock; \ 156 156 } while (0) 157 157 158 #define LEAVE() do { \159 lockRelease();\158 #define LEAVE() do { \ 159 lockRelease(); \ 160 160 } while (0) 161 161 … … 167 167 int helperEASet (cli_state *cli, FEALIST *pFEAList, char *path) 168 168 { 169 int rc = 0; 170 171 if (!path || !pFEAList || pFEAList->cbList <= sizeof(long)) 172 { 173 return ERROR_EAS_NOT_SUPPORTED; 174 } 175 176 ENTER(); 177 178 do { 179 // got FEA there 180 FEA * pfea; 181 unsigned long done = sizeof(long); 182 pfea = pFEAList->list; 183 while (done < pFEAList->cbList) 184 { 185 rc = smbwrp_setea(cli, path, (char*)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue); 186 if (rc) 187 { 188 break; 189 } 190 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue); 191 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 192 } 193 } while (0); 194 LEAVE(); 195 return rc; 169 int rc = 0; 170 171 if (!path || !pFEAList || pFEAList->cbList <= sizeof(long)) 172 return ERROR_EAS_NOT_SUPPORTED; 173 174 ENTER(); 175 176 do { 177 // got FEA there 178 FEA * pfea; 179 unsigned long done = sizeof(long); 180 pfea = pFEAList->list; 181 while (done < pFEAList->cbList) 182 { 183 rc = smbwrp_setea(cli, path, (char*)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue); 184 if (rc) 185 break; 186 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue); 187 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 188 } 189 } while (0); 190 191 LEAVE(); 192 return rc; 196 193 } 197 194 198 195 int APIENTRY NdpPluginLoad (PLUGINHELPERTABLE2L *pPHT) 199 196 { 200 int rc; 201 HPIPE pipe; 202 unsigned long action; 203 ph = pPHT; 204 ifL = 0; 205 /* 206 if (ph->cb < sizeof (PLUGINHELPERTABLE2)) 207 { 208 return ERROR_INVALID_FUNCTION; 209 } 210 */ 211 if (ph->cb >= sizeof (PLUGINHELPERTABLE2L)) 212 { 213 ifL = 1; 214 } 215 lockInit(); 216 debugInit(); 217 debuglocal(9,"Working with %s bit fileio NDFS\n", ifL ? "64" : "32"); 218 return NO_ERROR; 197 ph = pPHT; 198 ifL = 0; 199 if (ph->cb >= sizeof (PLUGINHELPERTABLE2L)) 200 ifL = 1; 201 202 lockInit(); 203 debugInit(); 204 debuglocal(9,"Working with %s bit fileio NDFS\n", ifL ? "64" : "32"); 205 return NO_ERROR; 219 206 } 220 207 … … 222 209 int APIENTRY NdpPluginFree (void) 223 210 { 224 debugDelete();225 lockClose();226 return NO_ERROR;211 debugDelete(); 212 lockClose(); 213 return NO_ERROR; 227 214 } 228 215 … … 230 217 void getfindinfo(Connection * pConn, FILEFINDBUF3 * stat, smbwrp_fileinfo * finfo) 231 218 { 232 char * name = ph->fsphStrRChr(finfo->fname, '\\'); 233 if (name) 234 { 235 name++; 236 } 237 else 238 { 239 name = finfo->fname; 240 } 241 if (!*name) 242 { 243 name = pConn->pRes->srv.share_name; 244 } 245 strncpy(stat->achName, name, CCHMAXPATHCOMP - 1); 246 stat->cbFile = finfo->size; 247 stat->cbFileAlloc = stat->cbFile; 248 stat->oNextEntryOffset = 0ul; 249 stat->cchName = strlen(stat->achName); 250 stat->attrFile = (finfo->attr & 0x37); 251 252 fsphUnixTimeToDosDate(finfo->mtime, &stat->fdateLastWrite, &stat->ftimeLastWrite); 253 fsphUnixTimeToDosDate(finfo->ctime, &stat->fdateCreation, &stat->ftimeCreation); 254 fsphUnixTimeToDosDate(finfo->atime, &stat->fdateLastAccess, &stat->ftimeLastAccess); 219 char * name = ph->fsphStrRChr(finfo->fname, '\\'); 220 221 if (name) 222 name++; 223 else 224 name = finfo->fname; 225 226 if (!*name) 227 name = pConn->pRes->srv.share_name; 228 229 strncpy(stat->achName, name, CCHMAXPATHCOMP - 1); 230 stat->cbFile = finfo->size; 231 stat->cbFileAlloc = stat->cbFile; 232 stat->oNextEntryOffset = 0ul; 233 stat->cchName = strlen(stat->achName); 234 stat->attrFile = (finfo->attr & 0x37); 235 236 fsphUnixTimeToDosDate(finfo->mtime, &stat->fdateLastWrite, &stat->ftimeLastWrite); 237 fsphUnixTimeToDosDate(finfo->ctime, &stat->fdateCreation, &stat->ftimeCreation); 238 fsphUnixTimeToDosDate(finfo->atime, &stat->fdateLastAccess, &stat->ftimeLastAccess); 239 return; 255 240 } 256 241 257 242 int getfindinfoL(Connection * pConn, void * plist, smbwrp_fileinfo * finfo, ULONG ulAttribute, char * mask) 258 243 { 259 FILESTATUS3L stat = {0}; 260 char * name = ph->fsphStrRChr(finfo->fname, '\\'); 261 if (name) 262 { 263 name++; 264 } 265 else 266 { 267 name = finfo->fname; 268 } 269 if (!*name) 270 { 271 name = pConn->pRes->srv.share_name; 272 } 273 if (mask && (!ph->fsphAttrMatch(ulAttribute, finfo->attr & 0x37) || !ph->fsphWildMatch(mask, name, ND_IGNORE_CASE))) 274 { 275 return 0; 276 } 277 278 stat.cbFile = finfo->size; 279 stat.cbFileAlloc = stat.cbFile; 280 stat.attrFile = (finfo->attr & 0x37); 281 282 fsphUnixTimeToDosDate(finfo->mtime, &stat.fdateLastWrite, &stat.ftimeLastWrite); 283 fsphUnixTimeToDosDate(finfo->ctime, &stat.fdateCreation, &stat.ftimeCreation); 284 fsphUnixTimeToDosDate(finfo->atime, &stat.fdateLastAccess, &stat.ftimeLastAccess); 285 debug_printf( "fname %s\n", finfo->fname); 286 debug_printf( "mtime %d %s", finfo->mtime, ctime( (time_t*)&finfo->mtime)); 287 debug_printf( "ftimeLastAccess %02d:%02d:%02d\n", stat.ftimeLastWrite.hours, stat.ftimeLastWrite.minutes, stat.ftimeLastWrite.twosecs*2); 288 289 ph->fsphAddFile32L(plist, &stat, name, strlen(name), finfo, sizeof(*finfo), 0); 290 return 1; 244 FILESTATUS3L stat = {0}; 245 char * name = ph->fsphStrRChr(finfo->fname, '\\'); 246 if (name) 247 name++; 248 else 249 name = finfo->fname; 250 251 if (!*name) 252 name = pConn->pRes->srv.share_name; 253 254 if (mask && (!ph->fsphAttrMatch(ulAttribute, finfo->attr & 0x37) || !ph->fsphWildMatch(mask, name, ND_IGNORE_CASE))) 255 return 0; 256 257 stat.cbFile = finfo->size; 258 stat.cbFileAlloc = stat.cbFile; 259 stat.attrFile = (finfo->attr & 0x37); 260 261 fsphUnixTimeToDosDate(finfo->mtime, &stat.fdateLastWrite, &stat.ftimeLastWrite); 262 fsphUnixTimeToDosDate(finfo->ctime, &stat.fdateCreation, &stat.ftimeCreation); 263 fsphUnixTimeToDosDate(finfo->atime, &stat.fdateLastAccess, &stat.ftimeLastAccess); 264 debuglocal(9, "fname %s\n", finfo->fname); 265 debuglocal(9, "mtime %d %s", finfo->mtime, ctime( (time_t*)&finfo->mtime)); 266 debuglocal(9, "ftimeLastAccess %02d:%02d:%02d\n", stat.ftimeLastWrite.hours, stat.ftimeLastWrite.minutes, stat.ftimeLastWrite.twosecs*2); 267 268 ph->fsphAddFile32L(plist, &stat, name, strlen(name), finfo, sizeof(*finfo), 0); 269 return 1; 291 270 } 292 271 293 272 static unsigned char fromhex (char c) 294 273 { 295 if ('0' <= c && c <= '9') 296 { 297 return c - '0'; 298 } 299 300 if ('A' <= c && c <= 'F') 301 { 302 return c - 'A' + 0xA; 303 } 304 305 if ('a' <= c && c <= 'f') 306 { 307 return c - 'a' + 0xA; 308 } 309 310 return 0; 274 if ('0' <= c && c <= '9') 275 return c - '0'; 276 277 if ('A' <= c && c <= 'F') 278 return c - 'A' + 0xA; 279 280 if ('a' <= c && c <= 'f') 281 return c - 'a' + 0xA; 282 283 return 0; 311 284 } 312 285 313 286 static char tohex (unsigned char b) 314 287 { 315 b &= 0xF; 316 317 if (b <= 9) 318 { 319 return b + '0'; 320 } 321 322 return 'A' + (b - 0xA); 288 b &= 0xF; 289 290 if (b <= 9) 291 return b + '0'; 292 293 return 'A' + (b - 0xA); 323 294 } 324 295 325 296 static void decryptPassword (const char *pszCrypt, char *pszPlain) 326 297 { 327 /* A simple "decryption", character from the hex value. */ 328 const char *s = pszCrypt; 329 char *d = pszPlain; 330 331 while (*s) 332 { 333 *d++ = (char)((fromhex (*s++) << 4) + fromhex (*s++)); 334 } 335 336 *d++ = 0; 298 // A simple "decryption", character from the hex value. 299 const char *s = pszCrypt; 300 char *d = pszPlain; 301 302 while (*s) 303 { 304 *d++ = (char)((fromhex (*s++) << 4) + fromhex (*s++)); 305 } 306 307 *d++ = 0; 308 return; 337 309 } 338 310 339 311 static void encryptPassword (const char *pszPlain, char *pszCrypt) 340 312 { 341 /* A simple "encryption" encode each character as hex value. */ 342 const char *s = pszPlain; 343 char *d = pszCrypt; 344 345 while (*s) 346 { 347 *d++ = tohex ((*s) >> 4); 348 *d++ = tohex (*s); 349 s++; 350 } 351 352 *d++ = 0; 313 // A simple "encryption" encode each character as hex value. */ 314 const char *s = pszPlain; 315 char *d = pszCrypt; 316 317 while (*s) 318 { 319 *d++ = tohex ((*s) >> 4); 320 *d++ = tohex (*s); 321 s++; 322 } 323 324 *d++ = 0; 325 return; 353 326 } 354 327 … … 358 331 int initResource (Resource *pRes, NDPROPERTYHANDLE properties) 359 332 { 360 int rc = NO_ERROR;361 unsigned long t;362 const CHAR* q = NULL;363 int defaultPassword = 1;364 365 pRes->rootlevel = 0;366 pRes->easupport = 1;333 int rc = NO_ERROR; 334 unsigned long t; 335 const char * q = NULL; 336 int defaultPassword = 1; 337 338 pRes->rootlevel = 0; 339 pRes->easupport = 1; 367 340 #ifdef HAVE_KRB5_H 368 pRes->krb5support = 1;341 pRes->krb5support = 1; 369 342 #else 370 pRes->krb5support = 0;343 pRes->krb5support = 0; 371 344 #endif 372 pRes->pdc = NULL; 373 374 t = 0, q = NULL; 375 rc = ph->fsphQueryStringProperty (properties, "WORKGROUP", &q, &t); 376 if (!rc && t && *q) 377 { 378 strncpy(pRes->srv.workgroup, q, sizeof(pRes->srv.workgroup) - 1); 379 pRes->rootlevel = 1; 380 } 381 382 t = 0, q = NULL; 383 rc = ph->fsphQueryStringProperty (properties, "SERVER", &q, &t); 384 if (!rc && t && *q) 385 { 386 strncpy(pRes->srv.server_name, q, sizeof(pRes->srv.server_name) - 1); 387 pRes->rootlevel = 2; 388 } 389 390 t = 0, q = NULL; 391 rc = ph->fsphQueryStringProperty (properties, "SHARE", &q, &t); 392 if (!rc && t && *q) 393 { 394 strncpy(pRes->srv.share_name, q, sizeof(pRes->srv.share_name) - 1); 395 pRes->rootlevel = 3; 396 } 397 398 t = 0, q = NULL; 399 rc = ph->fsphQueryStringProperty (properties, "USER", &q, &t); 400 if (!rc && t && *q) 401 { 402 strncpy(pRes->srv.username, q, sizeof(pRes->srv.username) - 1); 403 } 404 405 t = 0, q = NULL; 406 rc = ph->fsphQueryStringProperty (properties, "PASSWORD", &q, &t); 407 if (!rc && t && *q) 408 { 409 strncpy(pRes->srv.password, q, sizeof(pRes->srv.password) - 1); 410 defaultPassword = 0; 411 } 412 413 t = 0, q = NULL; 414 rc = ph->fsphQueryStringProperty (properties, "SPASSWORD", &q, &t); 415 if ( rc == NO_ERROR && *q != '\0' && defaultPassword) 416 { 417 char p[1024]; 418 p[0] = 0; 419 420 decryptPassword (q, p); 421 422 if (*p) 423 { 424 strncpy(pRes->srv.password, p, sizeof(pRes->srv.password) - 1); 425 426 /* clear the plain password */ 427 ph->fsphSetProperty (properties, "PASSWORD", ""); 428 } 429 } 430 else 431 { 432 char c[1024]; 433 encryptPassword (pRes->srv.password, c); 434 435 ph->fsphSetProperty (properties, "SPASSWORD", c); 436 437 // clear the plain password 438 ph->fsphSetProperty (properties, "PASSWORD", ""); 439 } 440 441 t = 0, q = NULL; 442 rc = ph->fsphQueryStringProperty (properties, "MASTER", &q, &t); 443 if (!rc && t && *q) 444 { 445 strncpy(pRes->srv.master, q, sizeof(pRes->srv.master) - 1); 446 } 447 448 t = 0; 449 rc = ph->fsphQueryUlongProperty (properties, "MASTERTYPE", &t); 450 if (!rc) 451 { 452 if (t > 1) 453 { 454 rc = ERROR_INVALID_PARAMETER; 455 } 456 else 457 { 458 pRes->srv.ifmastergroup = t; 459 } 460 } 461 462 t = 0; 463 rc = ph->fsphQueryUlongProperty (properties, "EASUPPORT", &t); 464 if (!rc) 465 { 466 if (t > 1) 467 { 468 rc = ERROR_INVALID_PARAMETER; 469 } 470 else 471 { 472 pRes->easupport = t; 473 } 474 } 475 476 t = 0; 477 rc = ph->fsphQueryUlongProperty (properties, "CTO", &t); 478 if (!rc) 479 { 480 if (t > 600) 481 { 482 rc = ERROR_INVALID_PARAMETER; 483 } 484 else 485 { 486 pRes->cachetimeout = t; 487 } 488 } 489 490 t = 0; 491 rc = ph->fsphQueryUlongProperty (properties, "CLD", &t); 492 if (!rc) 493 { 494 if (t > 96) 495 { 496 rc = ERROR_INVALID_PARAMETER; 497 } 498 else 499 { 500 pRes->cachedepth = t; 501 } 502 } 503 504 /* 505 * Create a directory cache with expiration time and cache listings 506 * the above values come from the gui. default: timeout 10; listings: 32 507 */ 508 dircache_create(&pRes->pdc, pRes->cachetimeout, pRes->cachedepth); 509 510 return rc; 345 pRes->pdc = NULL; 346 347 t = 0, q = NULL; 348 rc = ph->fsphQueryStringProperty (properties, "WORKGROUP", &q, &t); 349 if (!rc && t && *q) 350 { 351 strncpy(pRes->srv.workgroup, q, sizeof(pRes->srv.workgroup) - 1); 352 pRes->rootlevel = 1; 353 } 354 355 t = 0, q = NULL; 356 rc = ph->fsphQueryStringProperty (properties, "SERVER", &q, &t); 357 if (!rc && t && *q) 358 { 359 strncpy(pRes->srv.server_name, q, sizeof(pRes->srv.server_name) - 1); 360 pRes->rootlevel = 2; 361 } 362 363 t = 0, q = NULL; 364 rc = ph->fsphQueryStringProperty (properties, "SHARE", &q, &t); 365 if (!rc && t && *q) 366 { 367 strncpy(pRes->srv.share_name, q, sizeof(pRes->srv.share_name) - 1); 368 pRes->rootlevel = 3; 369 } 370 371 t = 0, q = NULL; 372 rc = ph->fsphQueryStringProperty (properties, "USER", &q, &t); 373 if (!rc && t && *q) 374 strncpy(pRes->srv.username, q, sizeof(pRes->srv.username) - 1); 375 376 t = 0, q = NULL; 377 rc = ph->fsphQueryStringProperty (properties, "PASSWORD", &q, &t); 378 if (!rc && t && *q) 379 { 380 strncpy(pRes->srv.password, q, sizeof(pRes->srv.password) - 1); 381 defaultPassword = 0; 382 } 383 384 t = 0, q = NULL; 385 rc = ph->fsphQueryStringProperty (properties, "SPASSWORD", &q, &t); 386 if (rc == NO_ERROR && *q != '\0' && defaultPassword) 387 { 388 char p[1024]; 389 p[0] = 0; 390 391 decryptPassword (q, p); 392 if (*p) 393 { 394 strncpy(pRes->srv.password, p, sizeof(pRes->srv.password) - 1); 395 // clear the plain password 396 ph->fsphSetProperty (properties, "PASSWORD", ""); 397 } 398 } 399 else 400 { 401 char c[1024]; 402 encryptPassword (pRes->srv.password, c); 403 ph->fsphSetProperty (properties, "SPASSWORD", c); 404 // clear the plain password 405 ph->fsphSetProperty (properties, "PASSWORD", ""); 406 } 407 408 t = 0, q = NULL; 409 rc = ph->fsphQueryStringProperty (properties, "MASTER", &q, &t); 410 if (!rc && t && *q) 411 strncpy(pRes->srv.master, q, sizeof(pRes->srv.master) - 1); 412 413 t = 0; 414 rc = ph->fsphQueryUlongProperty (properties, "MASTERTYPE", &t); 415 if (!rc) 416 { 417 if (t > 1) 418 rc = ERROR_INVALID_PARAMETER; 419 else 420 pRes->srv.ifmastergroup = t; 421 } 422 423 t = 0; 424 rc = ph->fsphQueryUlongProperty (properties, "EASUPPORT", &t); 425 if (!rc) 426 { 427 if (t > 1) 428 rc = ERROR_INVALID_PARAMETER; 429 else 430 pRes->easupport = t; 431 } 432 433 t = 0; 434 rc = ph->fsphQueryUlongProperty (properties, "CTO", &t); 435 if (!rc) 436 { 437 if (t > 600) 438 rc = ERROR_INVALID_PARAMETER; 439 else 440 pRes->cachetimeout = t; 441 } 442 443 t = 0; 444 rc = ph->fsphQueryUlongProperty (properties, "CLD", &t); 445 if (!rc) 446 { 447 if (t > 96) 448 rc = ERROR_INVALID_PARAMETER; 449 else 450 pRes->cachedepth = t; 451 } 452 453 /* 454 * Create a directory cache with expiration time and cache listings 455 * the above values come from the gui. default: timeout 10; listings: 32 456 */ 457 dircache_create(&pRes->pdc, pRes->cachetimeout, pRes->cachedepth); 458 459 return rc; 511 460 } 512 461 513 462 int iftestpath(char * path) 514 463 { 515 char * p = path; 516 if (!path) 517 { 518 return 0; 519 } 520 while ((p = ph->fsphStrChr(p, 'A')) != NULL) 521 { 522 if (ph->fsphStrNCmp(p, "A.+,;=[].B", 10) == 0) 523 { 524 return 1; 525 } 526 p++; 527 } 528 return 0; 464 char * p = path; 465 if (!path) 466 return 0; 467 468 while ((p = ph->fsphStrChr(p, 'A')) != NULL) 469 { 470 if (ph->fsphStrNCmp(p, "A.+,;=[].B", 10) == 0) 471 return 1; 472 p++; 473 } 474 return 0; 529 475 } 530 476 531 477 int pathparser(Resource *pRes, Connection * pConn, char * path, char * result) 532 478 { 533 int rootlevel;534 int rc = NO_ERROR;535 if (!pRes || !path || !result)536 { 537 return ERROR_INVALID_PARAMETER; 538 } 539 // handle special case when someone wants to test support ofLFN or smth similar540 if (iftestpath(path)) 541 { 542 strcpy(result, "\\A.+,;=[].B"); 543 return NO_ERROR;544 } 545 546 rootlevel = pRes->rootlevel; 547 if (*path == '\\') path++;548 549 if (rootlevel < 3) 550 { 551 char * p; 552 // flag: 1 parameters changed, reconnection required, 0 do nothing 553 int newlevel = 0; 554 // use a temporary resource to test disconnection/reconnection 555 Resource tmpRes; 556 // copy exising data 557 memcpy( &tmpRes, pRes, sizeof( tmpRes)); 558 // pointer to new connection fields 559 smbwrp_server * tmp = &tmpRes.srv; 560 if (rootlevel == 0) 561 { 562 p = ph->fsphStrChr(path, '\\'); 563 if (!p) 564 { 565 p = path + strlen(path);566 } 567 if (strlen(tmp->workgroup) != p - path 568 || (p == path || ph->fsphStrNICmp(path, tmp->workgroup, p - path))) 569 { 570 strncpy(tmp->workgroup, path, p - path); 571 tmp->workgroup[p - path] = 0;572 newlevel = 1;573 } 574 path = *p == '\\' ? p + 1 : p; 575 rootlevel = 1;576 } 577 if (rootlevel == 1) // root path starts from server name 578 { 579 p = ph->fsphStrChr(path, '\\'); 580 if (!p) 581 { 582 p = path + strlen(path); 583 } 584 if (strlen(tmp->server_name) != p - path 585 || (p == path || ph->fsphStrNICmp(path, tmp->server_name, p - path))) 586 { 587 strncpy(tmp->server_name, path, p - path); 588 tmp->server_name[p - path] = 0; 589 newlevel = 1;590 } 591 path = *p == '\\' ? p + 1 : p;592 rootlevel = 2; 593 } 594 if (rootlevel == 2) // root path starts from share name 595 { 596 p = ph->fsphStrChr(path, '\\'); 597 if (!p) 598 {599 p = path + strlen(path);600 } 601 if (strlen(tmp->share_name) != (p - path) 602 || (p == path || ph->fsphStrNICmp(path, tmp->share_name, p - path))) 603 { 604 strncpy(tmp->share_name, path, p - path); 605 tmp->share_name[p - path] = 0; 606 newlevel = 1; 607 } 608 path = *p == '\\' ? p + 1 : p;609 } 610 if (newlevel) 611 { 612 // reconnect to server here, first test new connection 613 cli_state* tmp_cli = NULL; 614 rc = smbwrp_connect( &tmpRes, &tmp_cli); 615 if (!rc) 616 { 617 // new connection is ok, disconnect old one 618 cli_state* cli = pConn->cli;619 smbwrp_disconnect( pRes, cli); 620 // save tmp data structure 621 memcpy( pRes, &tmpRes, sizeof( tmpRes)); 622 // save new connection handle 623 pConn->cli = tmp_cli;624 } 625 } 626 } 627 628 strcpy(result, "\\"); 629 strncat(result, path, CCHMAXPATH); 630 631 return rc; 632 } 633 634 635 // ------------------------------------------------------------- 479 int rootlevel; 480 int rc = NO_ERROR; 481 if (!pRes || !path || !result) 482 return ERROR_INVALID_PARAMETER; 483 484 /* handle special case when someone wants to test support of 485 * LFN or smth similar 486 */ 487 if (iftestpath(path)) 488 { 489 strcpy(result, "\\A.+,;=[].B"); 490 return NO_ERROR; 491 } 492 493 rootlevel = pRes->rootlevel; 494 if (*path == '\\') path++; 495 496 if (rootlevel < 3) 497 { 498 char * p; 499 // flag: 1 parameters changed, reconnection required, 0 do nothing 500 int newlevel = 0; 501 // use a temporary resource to test disconnection/reconnection 502 Resource tmpRes; 503 // copy exising data 504 memcpy( &tmpRes, pRes, sizeof( tmpRes)); 505 // pointer to new connection fields 506 smbwrp_server * tmp = &tmpRes.srv; 507 if (rootlevel == 0) 508 { 509 p = ph->fsphStrChr(path, '\\'); 510 if (!p) 511 p = path + strlen(path); 512 513 if (strlen(tmp->workgroup) != p - path || 514 (p == path || 515 ph->fsphStrNICmp(path, tmp->workgroup, p - path))) 516 { 517 strncpy(tmp->workgroup, path, p - path); 518 tmp->workgroup[p - path] = 0; 519 newlevel = 1; 520 } 521 path = *p == '\\' ? p + 1 : p; 522 rootlevel = 1; 523 } 524 525 if (rootlevel == 1) // root path starts from server name 526 { 527 p = ph->fsphStrChr(path, '\\'); 528 if (!p) 529 p = path + strlen(path); 530 531 if (strlen(tmp->server_name) != p - path || 532 (p == path || 533 ph->fsphStrNICmp(path, tmp->server_name, p - path))) 534 { 535 strncpy(tmp->server_name, path, p - path); 536 tmp->server_name[p - path] = 0; 537 newlevel = 1; 538 } 539 path = *p == '\\' ? p + 1 : p; 540 rootlevel = 2; 541 } 542 543 if (rootlevel == 2) // root path starts from share name 544 { 545 p = ph->fsphStrChr(path, '\\'); 546 if (!p) 547 p = path + strlen(path); 548 549 if (strlen(tmp->share_name) != (p - path) || 550 (p == path || 551 ph->fsphStrNICmp(path, tmp->share_name, p - path))) 552 { 553 strncpy(tmp->share_name, path, p - path); 554 tmp->share_name[p - path] = 0; 555 newlevel = 1; 556 } 557 path = *p == '\\' ? p + 1 : p; 558 } 559 560 if (newlevel) 561 { 562 // reconnect to server here, first test new connection 563 cli_state* tmp_cli = NULL; 564 rc = smbwrp_connect( &tmpRes, &tmp_cli); 565 if (!rc) 566 { 567 // new connection is ok, disconnect old one 568 cli_state* cli = pConn->cli; 569 smbwrp_disconnect( pRes, cli); 570 // save tmp data structure 571 memcpy( pRes, &tmpRes, sizeof( tmpRes)); 572 // save new connection handle 573 pConn->cli = tmp_cli; 574 } 575 } 576 } 577 578 strcpy(result, "\\"); 579 strncat(result, path, CCHMAXPATH); 580 return rc; 581 } 636 582 637 583 /* check if the requested resource is available */ 638 584 static int checkMountResource( Resource* pRes) 639 585 { 640 int rc; 641 unsigned long action; 642 cli_state* cli = NULL; 643 644 debug_printf("checkMountResource in tid#%d\n", _gettid()); 645 rc = smbwrp_connect( pRes, &cli); 646 /* changed to real error codes SCS 647 if (rc) 648 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_ACCESS_DENIED); */ 649 switch (rc) { 650 case 0: 651 rc = NO_ERROR; 652 break; 653 case 1: 654 case 10: 655 case 11: 656 rc = ERROR_BAD_NET_NAME; 657 break; 658 case 2: 659 rc = ERROR_INIT_ROUTINE_FAILED; 660 break; 661 case 3: 662 rc = ERROR_BAD_NET_RESP; 663 break; 664 case 4: 665 rc = ERROR_NETWORK_BUSY; 666 break; 667 case 6: 668 rc = ERROR_NETWORK_ACCESS_DENIED; 669 break; 670 case 7: 671 rc = ERROR_BAD_NETPATH; 672 break; 673 default: 674 rc = ERROR_UNEXP_NET_ERR; 675 break; 676 } /* endswitch */ 677 678 smbwrp_disconnect( pRes, cli); 679 680 return rc; 586 int rc; 587 unsigned long action; 588 cli_state* cli = NULL; 589 590 debuglocal(9, "checkMountResource in tid#%d\n", _gettid()); 591 rc = smbwrp_connect( pRes, &cli); 592 switch (rc) 593 { 594 case 0: 595 rc = NO_ERROR; 596 break; 597 case 1: 598 case 10: 599 case 11: 600 rc = ERROR_BAD_NET_NAME; 601 break; 602 case 2: 603 rc = ERROR_INIT_ROUTINE_FAILED; 604 break; 605 case 3: 606 rc = ERROR_BAD_NET_RESP; 607 break; 608 case 4: 609 rc = ERROR_NETWORK_BUSY; 610 break; 611 case 6: 612 rc = ERROR_NETWORK_ACCESS_DENIED; 613 break; 614 case 7: 615 rc = ERROR_BAD_NETPATH; 616 break; 617 default: 618 rc = ERROR_UNEXP_NET_ERR; 619 break; 620 } /* endswitch */ 621 622 smbwrp_disconnect( pRes, cli); 623 return rc; 681 624 } 682 625 683 626 int APIENTRY NdpMountResource (HRESOURCE *presource, int type, NDPROPERTYHANDLE properties) 684 627 { 685 int rc = NO_ERROR; 686 unsigned long objany = OBJ_ANY; 687 Resource *pRes = NULL; 688 689 ENTER(); 690 691 debuglocal(9,"NdpMountResource in\n"); 692 693 // init code 694 smbwrp_init(); 695 696 /* since samba plugin support only 1 type of resources we do not need */ 697 /* to check what the found type really is */ 698 pRes = malloc( sizeof(Resource)); 699 if (pRes == NULL) 700 { 701 rc = ERROR_NOT_ENOUGH_MEMORY; 702 } 703 else 704 { 705 memset(pRes, 0, sizeof(Resource)); 706 //pRes->objany = objany; 707 // parse init string 708 rc = initResource (pRes, properties); 709 // try to connect to resource (check type) only if thread!=1, so ndctl startup 710 // is not slowed down by network connections. 711 // ndctl does mounting on main thread (#1) 712 // nd/ndpm do not use main thread 713 if (!rc && _gettid()!=1) 714 rc = checkMountResource( pRes); 715 if (!rc) 716 { 717 // store resource data 718 *presource = (HRESOURCE)pRes; 719 } 720 else 721 { 722 free(pRes); 723 } 724 } 725 debuglocal(9,"NdpMountResource rc=%d\n", rc); 726 LEAVE(); 727 return rc; 728 } 729 730 // ------------------------------------------------------------- 628 int rc = NO_ERROR; 629 unsigned long objany = OBJ_ANY; 630 Resource *pRes = NULL; 631 632 ENTER(); 633 634 debuglocal(9,"NdpMountResource in\n"); 635 // init code 636 smbwrp_init(); 637 638 /* 639 * since samba plugin support only 1 type of resources we do not need 640 * to check what the found type really is 641 */ 642 pRes = malloc( sizeof(Resource)); 643 if (pRes == NULL) 644 rc = ERROR_NOT_ENOUGH_MEMORY; 645 else 646 { 647 memset(pRes, 0, sizeof(Resource)); 648 // parse init string 649 rc = initResource (pRes, properties); 650 /* 651 * try to connect to resource (check type) only if thread!=1, 652 * so ndctl startup is not slowed down by network connections. 653 * ndctl does mounting on main thread (#1) 654 * nd/ndpm do not use main thread 655 */ 656 if (!rc && _gettid()!=1) 657 rc = checkMountResource( pRes); 658 if (!rc) 659 { 660 // store resource data 661 *presource = (HRESOURCE)pRes; 662 } 663 else 664 free(pRes); 665 666 } 667 668 debuglocal(9, "NdpMountResource rc=%d\n", rc); 669 LEAVE(); 670 return rc; 671 } 731 672 732 673 int APIENTRY NdpFreeResource (HRESOURCE resource) 733 674 { 734 Resource *pRes = (Resource *)resource; 735 ENTER(); 736 dircache_delete(pRes->pdc); 737 memset(&pRes->srv, 0, sizeof(pRes->srv)); 738 free(pRes); 739 debuglocal(9,"NdpFreeResource %d\n", NO_ERROR); 740 LEAVE(); 741 return NO_ERROR; 742 } 743 744 // ------------------------------------------------------------- 675 Resource *pRes = (Resource *)resource; 676 ENTER(); 677 dircache_delete(pRes->pdc); 678 memset(&pRes->srv, 0, sizeof(pRes->srv)); 679 free(pRes); 680 debuglocal(9, "NdpFreeResource %d\n", NO_ERROR); 681 LEAVE(); 682 return NO_ERROR; 683 } 745 684 746 685 int APIENTRY NdpRsrcCompare (HRESOURCE resource, HRESOURCE resource2) 747 686 { 748 Resource *pRes = (Resource *)resource; 749 Resource *pRes2 = (Resource *)resource2; 750 int rc = ND_RSRC_DIFFERENT; 751 752 debuglocal(9,"NdpRsrcCompare in\n"); 753 if (ph->fsphStrICmp(pRes->srv.server_name, pRes2->srv.server_name) == 0 754 && ph->fsphStrICmp(pRes->srv.share_name, pRes2->srv.share_name) == 0 755 && ph->fsphStrICmp(pRes->srv.username, pRes2->srv.username) == 0 756 && ph->fsphStrICmp(pRes->srv.workgroup, pRes2->srv.workgroup) == 0) 757 { 758 // resources are equal 759 rc = ND_RSRC_EQUAL; 760 } 761 762 debuglocal(9,"NdpRsrcCompare %d\n", rc); 763 764 return rc; 687 Resource *pRes = (Resource *)resource; 688 Resource *pRes2 = (Resource *)resource2; 689 int rc = ND_RSRC_DIFFERENT; 690 691 debuglocal(9, "NdpRsrcCompare in\n"); 692 if (ph->fsphStrICmp(pRes->srv.server_name, pRes2->srv.server_name) == 0 693 && ph->fsphStrICmp(pRes->srv.share_name, pRes2->srv.share_name) == 0 694 && ph->fsphStrICmp(pRes->srv.username, pRes2->srv.username) == 0 695 && ph->fsphStrICmp(pRes->srv.workgroup, pRes2->srv.workgroup) == 0) 696 { 697 // resources are equal 698 rc = ND_RSRC_EQUAL; 699 } 700 701 debuglocal(9, "NdpRsrcCompare %d\n", rc); 702 return rc; 765 703 } 766 704 767 705 int APIENTRY NdpRsrcUpdate (HRESOURCE resource, HRESOURCE resource2) 768 706 { 769 // do nothing770 debuglocal(9,"NdpRsrcUpdate %d\n", NO_ERROR);771 return NO_ERROR;707 // do nothing 708 debuglocal(9, "NdpRsrcUpdate %d\n", NO_ERROR); 709 return NO_ERROR; 772 710 } 773 711 774 712 int APIENTRY NdpRsrcQueryInfo (HRESOURCE resource, ULONG *pulFlags, void *pdata, ULONG insize, ULONG *poutlen) 775 713 { 776 Resource *pRes = (Resource *)resource; 777 int rc = NO_ERROR; 778 char s[4096]; 779 780 debuglocal(9,"NdpRsrcQueryInfo in\n"); 781 782 switch (pRes->rootlevel) 783 { 784 case 0: 785 { 786 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\@%s", ifL ? "64" : "32", pRes->srv.username); 787 } break; 788 case 1: 789 { 790 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s %s: \\\\@%s", ifL ? "64" : "32", pRes->srv.workgroup, pRes->srv.username); 791 } break; 792 case 2: 793 { 794 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\%s%s%s@%s", ifL ? "64" : "32", *pRes->srv.workgroup ? pRes->srv.workgroup : "", *pRes->srv.workgroup ? ":" : "", pRes->srv.server_name, pRes->srv.username); 795 } break; 796 default: 797 { 798 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\%s%s%s\\%s@%s", ifL ? "64" : "32", *pRes->srv.workgroup ? pRes->srv.workgroup : "", *pRes->srv.workgroup ? ":" : "", pRes->srv.server_name, pRes->srv.share_name, pRes->srv.username); 799 } break; 800 } 801 *poutlen = strlen(s) + 1; 802 if (*poutlen > insize) 803 { 804 rc = ERROR_BUFFER_OVERFLOW; 805 } 806 else 807 { 808 memcpy(pdata, s, *poutlen); 809 } 810 811 debuglocal(9,"NdpRsrcQueryInfo %d\n", rc); 812 813 return rc; 714 Resource *pRes = (Resource *)resource; 715 int rc = NO_ERROR; 716 char s[4096]; 717 718 debuglocal(9, "NdpRsrcQueryInfo in\n"); 719 720 switch (pRes->rootlevel) 721 { 722 case 0: 723 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\@%s", ifL ? "64" : "32", pRes->srv.username); 724 break; 725 case 1: 726 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s %s: \\\\@%s", ifL ? "64" : "32", pRes->srv.workgroup, pRes->srv.username); 727 break; 728 case 2: 729 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\%s%s%s@%s", ifL ? "64" : "32", *pRes->srv.workgroup ? pRes->srv.workgroup : "", *pRes->srv.workgroup ? ":" : "", pRes->srv.server_name, pRes->srv.username); 730 break; 731 default: 732 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\%s%s%s\\%s@%s", ifL ? "64" : "32", *pRes->srv.workgroup ? pRes->srv.workgroup : "", *pRes->srv.workgroup ? ":" : "", pRes->srv.server_name, pRes->srv.share_name, pRes->srv.username); 733 break; 734 } 735 *poutlen = strlen(s) + 1; 736 if (*poutlen > insize) 737 rc = ERROR_BUFFER_OVERFLOW; 738 else 739 memcpy(pdata, s, *poutlen); 740 741 debuglocal(9, "NdpRsrcQueryInfo %d\n", rc); 742 return rc; 814 743 } 815 744 816 745 int APIENTRY NdpRsrcQueryFSAttach (HRESOURCE resource, void *pdata, ULONG insize, ULONG *poutlen) 817 746 { 818 ULONG ulDummy = 0;819 /* just return the resource info string */ 820 return NdpRsrcQueryInfo (resource, &ulDummy, pdata, insize, poutlen);747 ULONG ulDummy = 0; 748 // just return the resource info string 749 return NdpRsrcQueryInfo (resource, &ulDummy, pdata, insize, poutlen); 821 750 } 822 751 823 752 int APIENTRY NdpRsrcQueryFSAllocate (HRESOURCE resource, NDFSALLOCATE *pfsa) 824 753 { 825 Resource *pRes = (Resource *)resource; 826 int rc = NO_ERROR, rc1; 827 unsigned long action = 0; 828 cli_state* cli = NULL; 829 FSALLOCATE fsa; 830 831 ENTER(); 832 debuglocal(9,"NdpRsrcQueryFSAllocate %08x\n", pfsa); 833 834 if (!pfsa) 835 { 836 LEAVE(); 837 return NO_ERROR; 838 } 839 840 debug_printf("checkMountResource in tid#%d\n", _gettid()); 841 rc = smbwrp_connect( pRes, &cli); 842 if (rc) 843 { 844 debuglocal(9,"NdpCreateConnection failed rc=%d\n", rc); 845 pfsa->cSectorUnit = 1; 846 pfsa->cUnit = 123456; 847 pfsa->cUnitAvail = 123456; 848 pfsa->cbSector = 2048; 849 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_ACCESS_DENIED); 850 LEAVE(); 851 return rc; 852 } 853 854 rc = smbwrp_dskattr( cli, &fsa); 855 if (rc) 856 { 857 pfsa->cSectorUnit = 1; 858 pfsa->cUnit = 123456; 859 pfsa->cUnitAvail = 123456; 860 pfsa->cbSector = 2048; 861 //rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 862 } 863 else 864 { 865 pfsa->cSectorUnit = fsa.cSectorUnit; 866 pfsa->cUnit = fsa.cUnit; 867 pfsa->cUnitAvail = fsa.cUnitAvail; 868 pfsa->cbSector = fsa.cbSector; 869 } 870 871 smbwrp_disconnect( pRes, cli); 872 873 debuglocal(9,"NdpRsrcQueryFSAllocate %d/%d (cUnit = %d/cUnitAvail = %d/cbSector = %d)\n", rc, rc1, pfsa->cUnit, pfsa->cUnitAvail, pfsa->cbSector); 874 LEAVE(); 875 return rc; 876 } 877 878 // ------------------------------------------------------------- 754 Resource *pRes = (Resource *)resource; 755 int rc = NO_ERROR, rc1; 756 unsigned long action = 0; 757 cli_state* cli = NULL; 758 FSALLOCATE fsa; 759 760 ENTER(); 761 debuglocal(9, "NdpRsrcQueryFSAllocate %08x\n", pfsa); 762 763 if (!pfsa) 764 { 765 LEAVE(); 766 return NO_ERROR; 767 } 768 769 debuglocal(9, "NdpRsrcQueryFSAllocate in tid#%d\n", _gettid()); 770 rc = smbwrp_connect( pRes, &cli); 771 if (rc) 772 { 773 debuglocal(9, "NdpRsrcQueryFSAllocate smbwrp_connect failed rc=%d\n", rc); 774 pfsa->cSectorUnit = 1; 775 pfsa->cUnit = 123456; 776 pfsa->cUnitAvail = 123456; 777 pfsa->cbSector = 2048; 778 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_ACCESS_DENIED); 779 LEAVE(); 780 return rc; 781 } 782 783 rc = smbwrp_dskattr( cli, &fsa); 784 if (rc) 785 { 786 pfsa->cSectorUnit = 1; 787 pfsa->cUnit = 123456; 788 pfsa->cUnitAvail = 123456; 789 pfsa->cbSector = 2048; 790 //rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 791 } 792 else 793 { 794 pfsa->cSectorUnit = fsa.cSectorUnit; 795 pfsa->cUnit = fsa.cUnit; 796 pfsa->cUnitAvail = fsa.cUnitAvail; 797 pfsa->cbSector = fsa.cbSector; 798 } 799 800 smbwrp_disconnect( pRes, cli); 801 debuglocal(9, "NdpRsrcQueryFSAllocate %d/%d (cUnit = %d/cUnitAvail = %d/cbSector = %d)\n", rc, rc1, pfsa->cUnit, pfsa->cUnitAvail, pfsa->cbSector); 802 803 LEAVE(); 804 return rc; 805 } 879 806 880 807 int APIENTRY NdpCreateConnection (HRESOURCE resource, HCONNECTION *pconn) 881 808 { 882 int rc = 0; 883 Resource * pRes = (Resource *)resource; 884 unsigned long action; 885 Connection *pConn = NULL; 886 887 ENTER(); 888 889 debuglocal(9,"NdpCreateConnection in\n"); 890 891 pConn = malloc( sizeof(Connection)); 892 if (pConn == NULL) 893 { 894 rc = ERROR_NOT_ENOUGH_MEMORY; 895 } 896 if (rc) 897 { 898 debuglocal(9,"NdpCreateConnection ERROR_NOT_ENOUGH_MEMORY %d\n", rc); 899 LEAVE(); 900 return rc; 901 } 902 memset(pConn, 0, sizeof(Connection)); 903 pConn->pRes = pRes; 904 pConn->file.fd = -1; 905 906 debuglocal(9,"NdpCreateConnection send CONNECT\n"); 907 rc = smbwrp_connect( pRes, &pConn->cli); 908 if (rc) 909 { 910 free(pConn); 911 pConn = NULL; 912 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_INVALID_PARAMETER); 913 } 914 915 *pconn = (HCONNECTION)pConn; 916 debuglocal(9,"NdpCreateConnection [%p] %d\n", pConn, rc); 917 LEAVE(); 918 return rc; 919 } 920 921 // ------------------------------------------------------------- 809 int rc = 0; 810 Resource * pRes = (Resource *)resource; 811 unsigned long action; 812 Connection *pConn = NULL; 813 814 ENTER(); 815 816 debuglocal(9, "NdpCreateConnection in\n"); 817 818 pConn = malloc( sizeof(Connection)); 819 if (pConn == NULL) 820 rc = ERROR_NOT_ENOUGH_MEMORY; 821 822 if (rc) 823 { 824 debuglocal(9, "NdpCreateConnection ERROR_NOT_ENOUGH_MEMORY %d\n", rc); 825 LEAVE(); 826 return rc; 827 } 828 829 memset(pConn, 0, sizeof(Connection)); 830 pConn->pRes = pRes; 831 pConn->file.fd = -1; 832 833 debuglocal(9, "NdpCreateConnection send CONNECT\n"); 834 rc = smbwrp_connect( pRes, &pConn->cli); 835 if (rc) 836 { 837 free(pConn); 838 pConn = NULL; 839 rc = (rc == 7 ? ERROR_BAD_DEV_TYPE : ERROR_INVALID_PARAMETER); 840 } 841 842 *pconn = (HCONNECTION)pConn; 843 debuglocal(9, "NdpCreateConnection [%p] %d\n", pConn, rc); 844 845 LEAVE(); 846 return rc; 847 } 922 848 923 849 int APIENTRY NdpFreeConnection (HCONNECTION conn) 924 850 { 925 Connection *pConn = (Connection *)conn; 926 Resource *pRes = pConn->pRes; 927 int rc; 928 929 ENTER(); 930 931 debuglocal(9,"NdpFreeConnection in [%p]\n", pConn); 932 if (pConn->file.fd >= 0) 933 { 934 rc = smbwrp_close( pConn->cli, &pConn->file); 935 pConn->file.fd = -1; 936 } 937 938 smbwrp_disconnect( pRes, pConn->cli); 939 940 free(pConn); 941 debuglocal(9,"NdpFreeConnection %d\n", NO_ERROR); 942 LEAVE(); 943 return NO_ERROR; 944 } 945 946 // ------------------------------------------------------------- 851 Connection *pConn = (Connection *)conn; 852 Resource *pRes = pConn->pRes; 853 int rc; 854 855 ENTER(); 856 857 debuglocal(9, "NdpFreeConnection in [%p]\n", pConn); 858 if (pConn->file.fd >= 0) 859 { 860 rc = smbwrp_close( pConn->cli, &pConn->file); 861 pConn->file.fd = -1; 862 } 863 864 smbwrp_disconnect( pRes, pConn->cli); 865 866 free(pConn); 867 debuglocal(9, "NdpFreeConnection %d\n", NO_ERROR); 868 869 LEAVE(); 870 return NO_ERROR; 871 } 947 872 948 873 /* … … 965 890 int APIENTRY NdpQueryPathInfo (HCONNECTION conn, void *plist, char *szPath) 966 891 { 967 Connection *pConn = (Connection *)conn;968 Resource *pRes = pConn->pRes;969 smbwrp_fileinfo finfo;970 int rc = 0;971 int rcCon = 0;972 unsigned long action;973 char path[CCHMAXPATH+1] = {0};974 975 ENTER();976 977 debuglocal(9,"NdpQueryPathInfo in [%p] <%s>\n", pConn, szPath);892 Connection *pConn = (Connection *)conn; 893 Resource *pRes = pConn->pRes; 894 smbwrp_fileinfo finfo; 895 int rc = 0; 896 int rcCon = 0; 897 unsigned long action; 898 char path[CCHMAXPATH+1] = {0}; 899 900 ENTER(); 901 902 debuglocal(9, "NdpQueryPathInfo in [%p] <%s>\n", pConn, szPath); 978 903 979 // is wildcard is specified, we suppose parent dir exist, so exit immediately 980 if (ph->fsphStrChr(szPath, '*') || ph->fsphStrChr(szPath, '?')) 981 { 982 LEAVE(); 983 return ERROR_FILE_NOT_FOUND; 984 } 985 986 987 do { 988 /* First check if there is information in the directory cache. */ 989 unsigned long ulAge = 0; 990 if (dircache_find_path(pRes->pdc, szPath, &finfo, &ulAge)) 991 { 992 if (ulAge <= 15) /* @todo configurable. */ 993 { 994 rc = NO_ERROR; 995 finfo.easize = -1; 996 getfindinfoL(pConn, plist, &finfo, 0, NULL); 997 break; 998 } 999 } 1000 1001 rc = pathparser(pRes, pConn, szPath, path); 1002 debuglocal(9,"NdpQueryPathInfo pathparser for <%s> rc=%d\n", path, rc); 1003 switch (rc) 1004 { 1005 case NO_ERROR : 1006 case ERROR_FILE_NOT_FOUND: 1007 case ERROR_PATH_NOT_FOUND: 1008 case ERROR_ACCESS_DENIED: 1009 case ERROR_INVALID_PARAMETER: 1010 { 1011 break; 1012 } 1013 default : 1014 { 1015 rc = ERROR_PATH_NOT_FOUND; 1016 } 1017 } 1018 if (rc) 1019 { 1020 break; 1021 } 1022 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1); 1023 debuglocal(9,"NdpQueryPathInfo smbwrp_getattr for <%s>\n", path); 1024 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 1025 if (rc) 1026 { 1027 // remote server not available for first time? 1028 if (rc == ERROR_REM_NOT_LIST) 1029 { 1030 // free current cli resources 1031 smbwrp_disconnect( pRes, pConn->cli); 1032 // reconnect 1033 rcCon = smbwrp_connect( pRes, &pConn->cli); 1034 if (rcCon != NO_ERROR) 1035 debuglocal(9,"NdpQueryPathInfo smbwrp_connect rc = %d\n", rcCon); 1036 1037 // try file list again if reconnecting worked 1038 if (rcCon == NO_ERROR) 1039 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 1040 } 1041 debuglocal(9,"NdpQueryPathInfo smbwrp_getattr, rc = %d\n", rc); 1042 switch (rc) 1043 { 1044 case NO_ERROR : 1045 case ERROR_FILE_NOT_FOUND: 1046 case ERROR_PATH_NOT_FOUND: 1047 case ERROR_ACCESS_DENIED: 1048 case ERROR_INVALID_PARAMETER: 1049 case ERROR_REM_NOT_LIST: 1050 break; 1051 default : 1052 { 1053 rc = ERROR_PATH_NOT_FOUND; 1054 } 1055 } 1056 } 1057 1058 if (rc == NO_ERROR) { 1059 finfo.easize = -1; 1060 getfindinfoL(pConn, plist, &finfo, 0, NULL); 1061 } 1062 else if (rc == ERROR_FILE_NOT_FOUND) 1063 { 1064 // now try the upper path 1065 char * p = ph->fsphStrRChr(finfo.fname, '\\'); 1066 if (p && p > finfo.fname) 1067 { 1068 *p = 0; 1069 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 1070 debuglocal(9,"NdpQueryPathInfo upper path in <%s>, rc = %d\n", finfo.fname, rc); 1071 if (rc == NO_ERROR) 1072 { 1073 rc = (finfo.attr & FILE_DIRECTORY) !=0 ? 1074 ERROR_FILE_NOT_FOUND:ERROR_PATH_NOT_FOUND; 1075 } 1076 else if (rc != ERROR_REM_NOT_LIST) 1077 { 1078 rc = ERROR_PATH_NOT_FOUND; 1079 } 1080 } 1081 } 1082 } while (0); 1083 debuglocal(9,"NdpQueryPathInfo <%s> (%s) %d\n", szPath, path, rc); 1084 1085 LEAVE(); 1086 return rc; 1087 } 1088 1089 // ------------------------------------------------------------- 904 /* 905 * if wildcard is specified, we suppose parent dir exist, 906 * so exit immediately 907 */ 908 if (ph->fsphStrChr(szPath, '*') || ph->fsphStrChr(szPath, '?')) 909 { 910 LEAVE(); 911 return ERROR_FILE_NOT_FOUND; 912 } 913 914 do { 915 // First check if there is information in the directory cache. 916 unsigned long ulAge = 0; 917 if (dircache_find_path(pRes->pdc, szPath, &finfo, &ulAge)) 918 { 919 if (ulAge <= 15) /* @todo configurable. */ 920 { 921 rc = NO_ERROR; 922 finfo.easize = -1; 923 getfindinfoL(pConn, plist, &finfo, 0, NULL); 924 break; 925 } 926 } 927 928 rc = pathparser(pRes, pConn, szPath, path); 929 debuglocal(9, "NdpQueryPathInfo pathparser for <%s> rc=%d\n", path, rc); 930 switch (rc) 931 { 932 case NO_ERROR : 933 case ERROR_FILE_NOT_FOUND: 934 case ERROR_PATH_NOT_FOUND: 935 case ERROR_ACCESS_DENIED: 936 case ERROR_INVALID_PARAMETER: 937 break; 938 default : 939 rc = ERROR_PATH_NOT_FOUND; 940 } 941 942 if (rc) 943 break; 944 945 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1); 946 debuglocal(9, "NdpQueryPathInfo smbwrp_getattr for <%s>\n", path); 947 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 948 if (rc) 949 { 950 // remote server not available for first time? 951 if (rc == ERROR_REM_NOT_LIST) 952 { 953 // free current cli resources 954 smbwrp_disconnect( pRes, pConn->cli); 955 // reconnect 956 rcCon = smbwrp_connect( pRes, &pConn->cli); 957 if (rcCon != NO_ERROR) 958 debuglocal(9, "NdpQueryPathInfo smbwrp_connect rc = %d\n", rcCon); 959 // try file list again if reconnecting worked 960 if (rcCon == NO_ERROR) 961 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 962 } 963 964 debuglocal(9, "NdpQueryPathInfo smbwrp_getattr, rc = %d\n", rc); 965 switch (rc) 966 { 967 case NO_ERROR : 968 case ERROR_FILE_NOT_FOUND: 969 case ERROR_PATH_NOT_FOUND: 970 case ERROR_ACCESS_DENIED: 971 case ERROR_INVALID_PARAMETER: 972 case ERROR_REM_NOT_LIST: 973 break; 974 default : 975 rc = ERROR_PATH_NOT_FOUND; 976 } 977 } 978 979 if (rc == NO_ERROR) 980 { 981 finfo.easize = -1; 982 getfindinfoL(pConn, plist, &finfo, 0, NULL); 983 } 984 else if (rc == ERROR_FILE_NOT_FOUND) 985 { 986 // now try the upper path 987 char * p = ph->fsphStrRChr(finfo.fname, '\\'); 988 if (p && p > finfo.fname) 989 { 990 *p = 0; 991 rc = smbwrp_getattr( &pRes->srv, pConn->cli, &finfo); 992 debuglocal(9, "NdpQueryPathInfo upper path in <%s>, rc = %d\n", finfo.fname, rc); 993 if (rc == NO_ERROR) 994 rc = (finfo.attr & FILE_DIRECTORY) !=0 ? ERROR_FILE_NOT_FOUND:ERROR_PATH_NOT_FOUND; 995 else if (rc != ERROR_REM_NOT_LIST) 996 rc = ERROR_PATH_NOT_FOUND; 997 } 998 } 999 } while (0); 1000 debuglocal(9, "NdpQueryPathInfo <%s> (%s) %d\n", szPath, path, rc); 1001 1002 LEAVE(); 1003 return rc; 1004 } 1090 1005 1091 1006 int APIENTRY NdpFindStart (HCONNECTION conn, void *plist, NDFILEINFOL *pfiparent, char *szPath, ULONG ulAttribute) 1092 1007 { 1093 Connection *pConn = (Connection *)conn; 1094 Resource *pRes = pConn->pRes; 1095 int rc = NO_ERROR, count = 0; 1096 unsigned long action; 1097 char *mask = "*"; 1098 char dir[CCHMAXPATH+1] = {0}; 1099 char path[CCHMAXPATH+1] = {0}; 1100 smbwrp_fileinfo * data; 1101 NDPATHELEMENT *pel = ph->fsphNameElem(0); 1102 filelist_state state; 1103 char * p; 1104 1105 ENTER(); 1106 1107 debug_printf("NdpFindStart in [%p]\n", pConn); 1108 1109 strncpy(dir, szPath, sizeof(dir) - 1); 1110 if (pel) 1111 { 1112 mask = pel->name; 1113 dir[strlen(szPath) - pel->length] = 0; 1114 } 1115 action = strlen(dir) - 1; 1116 if (dir[action] == '\\') 1117 { 1118 dir[action] = 0; 1119 } 1120 rc = pathparser(pRes, pConn, dir, path); 1121 if (rc) 1122 { 1123 return rc; 1124 } 1125 action = strlen(path) - 1; 1126 if (path[action] != '\\') 1127 { 1128 strncat(path, "\\", sizeof(path) - 1); 1129 } 1130 strcpy(dir, path); 1131 strncat(path, mask, sizeof(path) - 1); 1132 1133 // this structure will be used by libsmb callbacks, so we store here all we need 1134 // to fill netdrive structures 1135 state.pConn = pConn; 1136 state.plist = plist; 1137 state.ulAttribute = ulAttribute; 1138 strcpy( state.dir, dir); 1139 strcpy( state.dir_mask, mask); 1140 strcpy( state.mask, path); 1141 state.fullpath = szPath; 1142 /* This plugin always reads a complete directory listing and filters results 1143 * using actual mask (state.dir_mask) in getfindinfoL. 1144 * May be this was a workaround for some server bug. 1145 * If this will be changed, then directory listing cache must be changed too, 1146 * and must remember the mask, which was used to obtain a listing. 1147 * Now the directory cache saves complete directory listings and then uses them to find 1148 * information about single files. 1149 * However, with a directory cache, it is probably faster to get a full listing and 1150 * then use it to obtain info about separate files than to perform a network 1151 * list query operation using actual wild cards for each file. Some application, 1152 * for example OpenOffice, do this. 1153 */ 1154 p = getlastslash(state.mask); 1155 if (p) 1156 { 1157 *(p + 1) = '*'; 1158 *(p + 2) = 0; 1159 } 1160 else 1161 { 1162 strcpy(state.mask, "\\*"); 1163 } 1164 debuglocal(9,"NdpFindStart: dir [%s], dir_mask [%s], mask [%s], szPath [%s]\n", 1165 state.dir, state.dir_mask, state.mask, state.fullpath); 1166 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state); 1167 // we need to handle reconnection also here, because NdpQueryPathInfo 1168 // could be called with '*' and exit then immediately (without calling libsmb) 1169 if (rc == ERROR_REM_NOT_LIST) 1170 { 1171 // free current cli resources 1172 smbwrp_disconnect( pRes, pConn->cli); 1173 // reconnect 1174 smbwrp_connect( pRes, &pConn->cli); 1175 // try file list again next loop 1176 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state); 1177 debuglocal(9,"NdpFindStart remote connection lost, rc = %d\n", rc); 1178 } 1179 1180 debuglocal(9,"NdpFindStart <%s> (%s) cnt %d %d\n", szPath, path, count, rc); 1181 LEAVE(); 1182 return rc; 1008 Connection *pConn = (Connection *)conn; 1009 Resource *pRes = pConn->pRes; 1010 int rc = NO_ERROR, count = 0; 1011 unsigned long action; 1012 char *mask = "*"; 1013 char dir[CCHMAXPATH+1] = {0}; 1014 char path[CCHMAXPATH+1] = {0}; 1015 smbwrp_fileinfo * data; 1016 NDPATHELEMENT *pel = ph->fsphNameElem(0); 1017 filelist_state state; 1018 char * p; 1019 1020 ENTER(); 1021 1022 debuglocal(9, "NdpFindStart in [%p]\n", pConn); 1023 1024 strncpy(dir, szPath, sizeof(dir) - 1); 1025 if (pel) 1026 { 1027 mask = pel->name; 1028 dir[strlen(szPath) - pel->length] = 0; 1029 } 1030 action = strlen(dir) - 1; 1031 if (dir[action] == '\\') 1032 dir[action] = 0; 1033 1034 rc = pathparser(pRes, pConn, dir, path); 1035 if (rc) 1036 return rc; 1037 1038 action = strlen(path) - 1; 1039 if (path[action] != '\\') 1040 strncat(path, "\\", sizeof(path) - 1); 1041 1042 strcpy(dir, path); 1043 strncat(path, mask, sizeof(path) - 1); 1044 1045 /* 1046 * this structure will be used by libsmb callbacks, 1047 * so we store here all we need to fill netdrive structures 1048 */ 1049 state.pConn = pConn; 1050 state.plist = plist; 1051 state.ulAttribute = ulAttribute; 1052 strcpy(state.dir, dir); 1053 strcpy(state.dir_mask, mask); 1054 strcpy(state.mask, path); 1055 state.fullpath = szPath; 1056 /* 1057 * This plugin always reads a complete directory listing and 1058 * filters results using actual mask (state.dir_mask) in getfindinfoL. 1059 * May be this was a workaround for some server bug. 1060 * If this will be changed, then directory listing cache must 1061 * be changed too, and must remember the mask, which was used to 1062 * obtain a listing. Now the directory cache saves complete directory 1063 * listings and then uses them to find information about single files. 1064 * However, with a directory cache, it is probably faster to get a full 1065 * listing and then use it to obtain info about separate files than to 1066 * perform a network list query operation using actual wild cards for 1067 * each file. Some application, for example OpenOffice, do this. 1068 */ 1069 p = getlastslash(state.mask); 1070 if (p) 1071 { 1072 *(p + 1) = '*'; 1073 *(p + 2) = 0; 1074 } 1075 else 1076 strcpy(state.mask, "\\*"); 1077 1078 debuglocal(9, "NdpFindStart: dir [%s], dir_mask [%s], mask [%s], szPath [%s]\n", 1079 state.dir, state.dir_mask, state.mask, state.fullpath); 1080 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state); 1081 /* 1082 * we need to handle reconnection also here, because NdpQueryPathInfo 1083 * could be called with '*' and exit then immediately 1084 * (without calling libsmb) 1085 */ 1086 if (rc == ERROR_REM_NOT_LIST) 1087 { 1088 // free current cli resources 1089 smbwrp_disconnect( pRes, pConn->cli); 1090 // reconnect 1091 smbwrp_connect( pRes, &pConn->cli); 1092 // try file list again next loop 1093 rc = smbwrp_filelist( &pRes->srv, pConn->cli, &state); 1094 debuglocal(9, "NdpFindStart remote connection lost, rc = %d\n", rc); 1095 } 1096 1097 debuglocal(9, "NdpFindStart <%s> (%s) cnt %d %d\n", szPath, path, count, rc); 1098 1099 LEAVE(); 1100 return rc; 1183 1101 } 1184 1102 1185 1103 int APIENTRY NdpDeletePathInfo (HRESOURCE resource, NDFILEINFOL *pfi) 1186 1104 { 1187 // debuglocal(9,"NdpDeletePathInfo %d\n", 0);1188 return NO_ERROR;1105 debuglocal(9, "NdpDeletePathInfo %d\n", 0); 1106 return NO_ERROR; 1189 1107 } 1190 1108 1191 1109 int APIENTRY NdpRefresh (HCONNECTION conn, char *path, int tree) 1192 1110 { 1193 debuglocal(9,"NdpRefresh <%s> %d\n", path, 0);1194 return NO_ERROR;1111 debuglocal(9, "NdpRefresh <%s> %d\n", path, 0); 1112 return NO_ERROR; 1195 1113 } 1196 1114 1197 1115 int APIENTRY NdpDiscardResourceData (HRESOURCE resource, NDDATABUF *pdatabuf) 1198 1116 { 1199 // The plugin do not have to deallocate anything 1200 // because resource data did not contain any pointers 1201 //to plugins data.1202 // Data stored by fsphSetResourceData will be 1203 // deallocated by NetDrive. 1204 1205 debuglocal(9,"NdpDicardresourceData %d\n", 0);1206 return NO_ERROR;1117 /* 1118 * The plugin do not have to deallocate anything, because 1119 * resource data did not contain any pointers to plugins data. 1120 * Data stored by fsphSetResourceData will be deallocated by NetDrive. 1121 */ 1122 1123 debuglocal(9, "NdpDicardresourceData %d\n", 0); 1124 return NO_ERROR; 1207 1125 } 1208 1126 1209 1127 int APIENTRY NdpSetPathInfo (HCONNECTION conn, NDFILEINFOL *pfi, char *szPathName) 1210 1128 { 1211 Connection *pConn = (Connection *)conn; 1212 Resource *pRes = pConn->pRes; 1213 int rc = 0; 1214 unsigned long action; 1215 char path[CCHMAXPATH+1] = {0}; 1216 smbwrp_fileinfo finfo; 1217 1218 ENTER(); 1219 1220 debug_printf("NdpSetPathInfo in [%p]\n", pConn); 1221 1222 // delete the dir cache 1223 dircache_invalidate(szPathName, pRes->pdc, 1); 1224 1225 do { 1226 rc = pathparser(pRes, pConn, szPathName, path); 1227 if (rc) 1228 { 1229 break; 1230 } 1231 1232 memset(&finfo, 0, sizeof(finfo)); 1233 1234 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1); 1235 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(finfo.mtime)); 1236 finfo.attr = pfi->stat.attrFile & 0x37; 1237 rc = smbwrp_setattr(pConn->cli, &finfo); 1238 } while (0); 1239 debuglocal(9,"NdpSetPathInfo <%s> (%s) %d\n", szPathName, path, rc); 1240 LEAVE(); 1241 return rc; 1129 Connection *pConn = (Connection *)conn; 1130 Resource *pRes = pConn->pRes; 1131 int rc = 0; 1132 unsigned long action; 1133 char path[CCHMAXPATH+1] = {0}; 1134 smbwrp_fileinfo finfo; 1135 1136 ENTER(); 1137 1138 debuglocal(9, "NdpSetPathInfo in [%p]\n", pConn); 1139 1140 // delete the dir cache 1141 dircache_invalidate(szPathName, pRes->pdc, 1); 1142 1143 do { 1144 rc = pathparser(pRes, pConn, szPathName, path); 1145 if (rc) 1146 break; 1147 1148 memset(&finfo, 0, sizeof(finfo)); 1149 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1); 1150 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(finfo.mtime)); 1151 finfo.attr = pfi->stat.attrFile & 0x37; 1152 rc = smbwrp_setattr(pConn->cli, &finfo); 1153 } while (0); 1154 1155 debuglocal(9, "NdpSetPathInfo <%s> (%s) %d\n", szPathName, path, rc); 1156 1157 LEAVE(); 1158 return rc; 1242 1159 } 1243 1160 1244 1161 int buildFEALIST(FEALIST *pFEASrc, GEALIST *pGEAList, FEALIST *pFEAList) 1245 1162 { 1246 int rc = 0; 1247 FEA * pfea; 1248 FEA * pfeadest; 1249 unsigned long size, done = sizeof(pFEAList->cbList), dsize, ddone = sizeof(pFEAList->cbList); 1250 1251 size = pFEASrc->cbList; 1252 pfea = pFEASrc->list; 1253 pfeadest = pFEAList->list; 1254 dsize = pFEAList->cbList; 1255 //debuglocal(9,"buildFEALIST in destsize %d srcsize %d pGEAList=%08x pGEAList->cbList=%d\n", dsize, ddone, size, pGEAList, pGEAList ? pGEAList->cbList : 0); 1256 while (done < size) 1257 { 1258 char * name = (char *)(pfea + 1); 1259 int insert = 1; 1260 if (pGEAList && pGEAList->cbList > sizeof(pGEAList->cbList)) 1261 { 1262 GEA * pgea = pGEAList->list; 1263 unsigned long size = pGEAList->cbList - sizeof(pGEAList->cbList), done = 0; 1264 insert = 0; 1265 while (done < size) 1266 { 1267 //debuglocal(9,"comp <%s> <%s>\n", name, pgea->szName); 1268 if (!ph->fsphStrNCmp(name, pgea->szName, pgea->cbName)) 1269 { 1270 insert = 1; 1271 break; 1272 } 1273 done += pgea->cbName + 2; 1274 pgea = (GEA *)((char *)pgea + pgea->cbName + 2); 1275 } 1276 } 1277 if (insert) 1278 { 1279 ddone += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1280 if (ddone <= dsize) 1281 { 1282 pfeadest->cbName = pfea->cbName; 1283 pfeadest->cbValue = pfea->cbValue; 1284 pfeadest->fEA = 0; 1285 strcpy((char *)(pfeadest + 1), name); 1286 memcpy((char *)(pfeadest + 1) + pfea->cbName + 1, (char *)(pfea + 1) + pfea->cbName + 1, pfea->cbValue); 1287 pfeadest = (FEA *)((char *)pFEAList + ddone); 1288 } 1289 } 1290 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1291 //debuglocal(9,"buuildfea <%s> insert=%d pfea->cbName=%d pfea->cbValue=%d srcdone=%d destdone=%d pfeadest=%08x pfea=%08x\n", name, insert, pfea->cbName, pfea->cbValue, done, ddone, pfeadest, pfea); 1292 pfea = (FEA *)((char *)pFEASrc + done); 1293 } 1294 pFEAList->cbList = ddone; 1295 if (ddone > dsize && dsize > sizeof(pFEAList->cbList)) 1296 { 1297 rc = ERROR_BUFFER_OVERFLOW; 1298 } 1299 debuglocal(9,"buildFEALIST rc=%d destsize=%d destdone=%d srcsize=%d pGEAList=%08x\n", rc, dsize, ddone, size, pGEAList); 1300 return rc; 1163 int rc = 0; 1164 FEA * pfea; 1165 FEA * pfeadest; 1166 unsigned long size; 1167 unsigned long done = sizeof(pFEAList->cbList); 1168 unsigned long dsize; 1169 unsigned long ddone = sizeof(pFEAList->cbList); 1170 1171 size = pFEASrc->cbList; 1172 pfea = pFEASrc->list; 1173 pfeadest = pFEAList->list; 1174 dsize = pFEAList->cbList; 1175 //debuglocal(9,"buildFEALIST in destsize %d srcsize %d pGEAList=%08x pGEAList->cbList=%d\n", dsize, ddone, size, pGEAList, pGEAList ? pGEAList->cbList : 0); 1176 1177 while (done < size) 1178 { 1179 char * name = (char *)(pfea + 1); 1180 int insert = 1; 1181 if (pGEAList && pGEAList->cbList > sizeof(pGEAList->cbList)) 1182 { 1183 GEA * pgea = pGEAList->list; 1184 unsigned long size = pGEAList->cbList - sizeof(pGEAList->cbList); 1185 unsigned long done = 0; 1186 insert = 0; 1187 while (done < size) 1188 { 1189 //debuglocal(9,"comp <%s> <%s>\n", name, pgea->szName); 1190 if (!ph->fsphStrNCmp(name, pgea->szName, pgea->cbName)) 1191 { 1192 insert = 1; 1193 break; 1194 } 1195 done += pgea->cbName + 2; 1196 pgea = (GEA *)((char *)pgea + pgea->cbName + 2); 1197 } 1198 } 1199 if (insert) 1200 { 1201 ddone += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1202 if (ddone <= dsize) 1203 { 1204 pfeadest->cbName = pfea->cbName; 1205 pfeadest->cbValue = pfea->cbValue; 1206 pfeadest->fEA = 0; 1207 strcpy((char *)(pfeadest + 1), name); 1208 memcpy((char *)(pfeadest + 1) + pfea->cbName + 1, (char *)(pfea + 1) + pfea->cbName + 1, pfea->cbValue); 1209 pfeadest = (FEA *)((char *)pFEAList + ddone); 1210 } 1211 } 1212 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1213 //debuglocal(9,"buuildfea <%s> insert=%d pfea->cbName=%d pfea->cbValue=%d srcdone=%d destdone=%d pfeadest=%08x pfea=%08x\n", name, insert, pfea->cbName, pfea->cbValue, done, ddone, pfeadest, pfea); 1214 pfea = (FEA *)((char *)pFEASrc + done); 1215 } 1216 1217 pFEAList->cbList = ddone; 1218 if (ddone > dsize && dsize > sizeof(pFEAList->cbList)) 1219 rc = ERROR_BUFFER_OVERFLOW; 1220 1221 debuglocal(9, "buildFEALIST rc=%d destsize=%d destdone=%d srcsize=%d pGEAList=%08x\n", rc, dsize, ddone, size, pGEAList); 1222 return rc; 1301 1223 } 1302 1224 1303 1225 int APIENTRY NdpEAQuery (HCONNECTION conn, GEALIST *pGEAList, NDFILEINFOL *pfi, FEALIST *pFEAList) 1304 1226 { 1305 Connection *pConn = (Connection *)conn; 1306 Resource *pRes = pConn->pRes; 1307 int rc = 0; 1308 unsigned long action; 1309 char * path = NULL; 1310 FEALIST * pFEASrc; 1311 NDDATABUF fdata = {0}; 1312 smbwrp_fileinfo *finfo; 1313 const int cbBuffer = 64*1024; 1314 1315 if (!pfi || !pfi->pszName || !pFEAList) 1316 { 1317 return ERROR_EAS_NOT_SUPPORTED; 1318 } 1319 if (!pRes->easupport) 1320 { 1321 return ERROR_EAS_NOT_SUPPORTED; 1322 } 1323 1324 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1325 if (rc || !fdata.ulSize || !fdata.pData) 1326 { 1327 debuglocal(9,"NdpEAQuery: ph->fsphGetFileInfoData = %d/%d %08x\n", rc, fdata.ulSize, fdata.pData); 1328 return ERROR_EAS_NOT_SUPPORTED; 1329 } 1330 1331 ENTER(); 1332 1333 finfo = (smbwrp_fileinfo *)fdata.pData; 1334 path = finfo->fname; 1335 1336 debuglocal(9,"NdpEAQuery in [%p] <%s> %08x %d\n", pConn, path, pGEAList, pGEAList ? pGEAList->cbList : 0); 1337 1338 char *pchBuffer = (char *)malloc(cbBuffer); 1339 if (!pchBuffer) 1340 { 1341 LEAVE(); 1342 return ERROR_NOT_ENOUGH_MEMORY; 1343 } 1344 1345 do { 1346 rc = smbwrp_listea( pConn->cli, path, pchBuffer, cbBuffer); 1347 pFEASrc = (FEALIST*) pchBuffer; 1348 if (rc) 1349 { 1350 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 1351 switch (rc) 1352 { 1353 case ERROR_FILE_NOT_FOUND : 1354 case ERROR_PATH_NOT_FOUND : 1355 { 1356 pFEAList->cbList = sizeof(pFEAList->cbList); 1357 rc = NO_ERROR; 1358 } break; 1359 case ERROR_BUFFER_OVERFLOW : 1360 { 1361 pFEAList->cbList = pFEASrc->cbList; 1362 } break; 1363 default : 1364 { 1365 rc = ERROR_EAS_NOT_SUPPORTED; 1366 } 1367 } 1368 } 1369 else 1370 { 1371 rc = buildFEALIST((FEALIST *)pFEASrc, pGEAList, pFEAList); 1372 } 1373 } while (0); 1374 free(pchBuffer); 1375 debuglocal(9,"NdpEAQuery <%s> %d %d %d\n", pfi->pszName, rc, pFEASrc->cbList, pFEAList->cbList); 1376 LEAVE(); 1377 return rc; 1227 Connection *pConn = (Connection *)conn; 1228 Resource *pRes = pConn->pRes; 1229 int rc = 0; 1230 unsigned long action; 1231 char * path = NULL; 1232 FEALIST * pFEASrc; 1233 NDDATABUF fdata = {0}; 1234 smbwrp_fileinfo *finfo; 1235 const int cbBuffer = 64*1024; 1236 1237 if (!pfi || !pfi->pszName || !pFEAList) 1238 return ERROR_EAS_NOT_SUPPORTED; 1239 1240 if (!pRes->easupport) 1241 return ERROR_EAS_NOT_SUPPORTED; 1242 1243 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1244 if (rc || !fdata.ulSize || !fdata.pData) 1245 { 1246 debuglocal(9, "NdpEAQuery: ph->fsphGetFileInfoData = %d/%d %08x\n", rc, fdata.ulSize, fdata.pData); 1247 return ERROR_EAS_NOT_SUPPORTED; 1248 } 1249 1250 ENTER(); 1251 1252 finfo = (smbwrp_fileinfo *)fdata.pData; 1253 path = finfo->fname; 1254 debuglocal(9, "NdpEAQuery in [%p] <%s> %08x %d\n", pConn, path, pGEAList, pGEAList ? pGEAList->cbList : 0); 1255 1256 char *pchBuffer = (char *)malloc(cbBuffer); 1257 if (!pchBuffer) 1258 { 1259 LEAVE(); 1260 return ERROR_NOT_ENOUGH_MEMORY; 1261 } 1262 1263 do { 1264 rc = smbwrp_listea( pConn->cli, path, pchBuffer, cbBuffer); 1265 pFEASrc = (FEALIST*) pchBuffer; 1266 if (rc) 1267 { 1268 switch (rc) 1269 { 1270 case ERROR_FILE_NOT_FOUND : 1271 case ERROR_PATH_NOT_FOUND : 1272 pFEAList->cbList = sizeof(pFEAList->cbList); 1273 rc = NO_ERROR; 1274 break; 1275 case ERROR_BUFFER_OVERFLOW : 1276 pFEAList->cbList = pFEASrc->cbList; 1277 break; 1278 default : 1279 rc = ERROR_EAS_NOT_SUPPORTED; 1280 } 1281 } 1282 else 1283 rc = buildFEALIST((FEALIST *)pFEASrc, pGEAList, pFEAList); 1284 } while (0); 1285 1286 free(pchBuffer); 1287 debuglocal(9, "NdpEAQuery <%s> %d %d %d\n", pfi->pszName, rc, pFEASrc->cbList, pFEAList->cbList); 1288 1289 LEAVE(); 1290 return rc; 1378 1291 } 1379 1292 1380 1293 int APIENTRY NdpEASet (HCONNECTION conn, FEALIST *pFEAList, NDFILEINFOL *pfi) 1381 1294 { 1382 Connection *pConn = (Connection *)conn; 1383 Resource *pRes = pConn->pRes; 1384 int rc = 0; 1385 char * path; 1386 unsigned long action; 1387 NDDATABUF fdata = {0}; 1388 smbwrp_fileinfo *finfo; 1389 1390 debuglocal(9,"NdpEASet in [%p]\n", pConn); 1391 1392 if (!pfi || !pfi->pszName) 1393 { 1394 return ERROR_EAS_NOT_SUPPORTED; 1395 } 1396 if (!pRes->easupport) 1397 { 1398 return ERROR_EAS_NOT_SUPPORTED; 1399 } 1400 1401 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1402 if (rc || !fdata.ulSize || !fdata.pData) 1403 { 1404 debuglocal(9,"NdpEASet: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData); 1405 return ERROR_EAS_NOT_SUPPORTED; 1406 } 1407 1408 finfo = (smbwrp_fileinfo *)fdata.pData; 1409 path = finfo->fname; 1410 1411 rc = helperEASet(pConn->cli, pFEAList, path); 1412 debuglocal(9,"NdpEASet %d\n", rc); 1413 return rc; 1295 Connection *pConn = (Connection *)conn; 1296 Resource *pRes = pConn->pRes; 1297 int rc = 0; 1298 char * path; 1299 unsigned long action; 1300 NDDATABUF fdata = {0}; 1301 smbwrp_fileinfo *finfo; 1302 1303 debuglocal(9, "NdpEASet in [%p]\n", pConn); 1304 1305 if (!pfi || !pfi->pszName) 1306 return ERROR_EAS_NOT_SUPPORTED; 1307 1308 if (!pRes->easupport) 1309 return ERROR_EAS_NOT_SUPPORTED; 1310 1311 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1312 if (rc || !fdata.ulSize || !fdata.pData) 1313 { 1314 debuglocal(9, "NdpEASet: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData); 1315 return ERROR_EAS_NOT_SUPPORTED; 1316 } 1317 1318 finfo = (smbwrp_fileinfo *)fdata.pData; 1319 path = finfo->fname; 1320 1321 rc = helperEASet(pConn->cli, pFEAList, path); 1322 debuglocal(9, "NdpEASet %d\n", rc); 1323 return rc; 1414 1324 } 1415 1325 1416 1326 int APIENTRY NdpEASize (HCONNECTION conn, NDFILEINFOL *pfi, ULONG *pulEASize) 1417 1327 { 1418 Connection *pConn = (Connection *)conn; 1419 Resource *pRes = pConn->pRes; 1420 int rc = 0; 1421 unsigned long action; 1422 char * path = NULL; 1423 FEALIST * pfealist; 1424 NDDATABUF fdata = {0}; 1425 smbwrp_fileinfo *finfo; 1426 const int cbBuffer = 64*1024; 1427 int easize; 1428 1429 if (!pfi || !pulEASize) 1430 { 1431 return ERROR_EAS_NOT_SUPPORTED; 1432 } 1433 if (!pRes->easupport) 1434 { 1435 return ERROR_EAS_NOT_SUPPORTED; 1436 } 1437 1438 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1439 if (rc || !fdata.ulSize || !fdata.pData) 1440 { 1441 debuglocal(9,"NdpEASize: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData); 1442 return ERROR_EAS_NOT_SUPPORTED; 1443 } 1444 1445 ENTER(); 1446 1447 finfo = (smbwrp_fileinfo *)fdata.pData; 1448 easize = finfo->easize; 1449 finfo->easize = -1; 1450 path = finfo->fname; 1451 if (easize >= 0) 1452 { 1453 *pulEASize = easize; 1454 debuglocal(9,"NdpEASize <%s> cached %d\n", path, easize); 1455 LEAVE(); 1456 return NO_ERROR; 1457 } 1458 1459 debuglocal(9,"NdpEASize in [%p] <%s> \n", pConn, path); 1460 1461 char *pchBuffer = (char *)malloc(cbBuffer); 1462 if (!pchBuffer) 1463 { 1464 LEAVE(); 1465 return ERROR_NOT_ENOUGH_MEMORY; 1466 } 1467 1468 do { 1469 rc = smbwrp_listea(pConn->cli, path, pchBuffer, cbBuffer); 1470 pfealist = (FEALIST*)pchBuffer; 1471 if (rc) 1472 { 1473 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 1474 switch (rc) 1475 { 1476 case ERROR_FILE_NOT_FOUND : 1477 case ERROR_PATH_NOT_FOUND : 1478 { 1479 pfealist->cbList = sizeof(pfealist->cbList); 1480 } /* Fall through */ 1481 case ERROR_BUFFER_OVERFLOW : 1482 { 1483 rc = NO_ERROR; 1484 } break; 1485 default : 1486 { 1487 rc = ERROR_EAS_NOT_SUPPORTED; 1488 } 1489 } 1490 } 1491 *pulEASize = pfealist->cbList; 1492 } while (0); 1493 free(pchBuffer); 1494 debuglocal(9,"NdpEASize <%s> %d %d\n", pfi->pszName, *pulEASize, rc); 1495 LEAVE(); 1496 return rc; 1328 Connection *pConn = (Connection *)conn; 1329 Resource *pRes = pConn->pRes; 1330 int rc = 0; 1331 unsigned long action; 1332 char * path = NULL; 1333 FEALIST * pfealist; 1334 NDDATABUF fdata = {0}; 1335 smbwrp_fileinfo *finfo; 1336 const int cbBuffer = 64*1024; 1337 int easize; 1338 1339 if (!pfi || !pulEASize) 1340 return ERROR_EAS_NOT_SUPPORTED; 1341 1342 if (!pRes->easupport) 1343 return ERROR_EAS_NOT_SUPPORTED; 1344 1345 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0); 1346 if (rc || !fdata.ulSize || !fdata.pData) 1347 { 1348 debuglocal(9, "NdpEASize: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData); 1349 return ERROR_EAS_NOT_SUPPORTED; 1350 } 1351 1352 ENTER(); 1353 1354 finfo = (smbwrp_fileinfo *)fdata.pData; 1355 easize = finfo->easize; 1356 finfo->easize = -1; 1357 path = finfo->fname; 1358 if (easize >= 0) 1359 { 1360 *pulEASize = easize; 1361 debuglocal(9, "NdpEASize <%s> cached %d\n", path, easize); 1362 LEAVE(); 1363 return NO_ERROR; 1364 } 1365 1366 debuglocal(9, "NdpEASize in [%p] <%s> \n", pConn, path); 1367 1368 char *pchBuffer = (char *)malloc(cbBuffer); 1369 if (!pchBuffer) 1370 { 1371 LEAVE(); 1372 return ERROR_NOT_ENOUGH_MEMORY; 1373 } 1374 1375 do { 1376 rc = smbwrp_listea(pConn->cli, path, pchBuffer, cbBuffer); 1377 pfealist = (FEALIST*)pchBuffer; 1378 if (rc) 1379 { 1380 switch (rc) 1381 { 1382 case ERROR_FILE_NOT_FOUND : 1383 case ERROR_PATH_NOT_FOUND : 1384 pfealist->cbList = sizeof(pfealist->cbList); // Fall through */ 1385 case ERROR_BUFFER_OVERFLOW : 1386 rc = NO_ERROR; 1387 break; 1388 default : 1389 rc = ERROR_EAS_NOT_SUPPORTED; 1390 } 1391 } 1392 *pulEASize = pfealist->cbList; 1393 } while (0); 1394 1395 free(pchBuffer); 1396 debuglocal(9, "NdpEASize <%s> %d %d\n", pfi->pszName, *pulEASize, rc); 1397 1398 LEAVE(); 1399 return rc; 1497 1400 } 1498 1401 1499 1402 int APIENTRY NdpSetCurrentDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szPath) 1500 1403 { 1501 Connection *pConn = (Connection *)conn;1502 Resource *pRes = pConn->pRes;1503 int rc = 0;1504 unsigned long action;1505 char path[CCHMAXPATH+1] = {0};1404 Connection *pConn = (Connection *)conn; 1405 Resource *pRes = pConn->pRes; 1406 int rc = 0; 1407 unsigned long action; 1408 char path[CCHMAXPATH+1] = {0}; 1506 1409 1507 debuglocal(9,"NdpSetCurrentDir in [%p]\n", pConn);1508 1509 ENTER();1510 1511 do {1512 rc = pathparser(pRes, pConn, szPath, path);1513 if (rc)1514 { 1515 break; 1516 } 1517 1518 rc = smbwrp_chdir(&pRes->srv, pConn->cli, path); 1519 } while (0);1520 debuglocal(9,"NdpSetCurrentDir <%s> (%s) %d\n", szPath, path, rc); 1521 LEAVE();1522 return rc;1410 debuglocal(9, "NdpSetCurrentDir in [%p]\n", pConn); 1411 1412 ENTER(); 1413 1414 do { 1415 rc = pathparser(pRes, pConn, szPath, path); 1416 if (rc) 1417 break; 1418 1419 rc = smbwrp_chdir(&pRes->srv, pConn->cli, path); 1420 } while (0); 1421 1422 debuglocal(9, "NdpSetCurrentDir <%s> (%s) %d\n", szPath, path, rc); 1423 1424 LEAVE(); 1425 return rc; 1523 1426 } 1524 1427 1525 1428 int APIENTRY NdpCopy (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption) 1526 1429 { 1527 debuglocal(9,"NdpCopy <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);1528 return ERROR_CANNOT_COPY;1430 debuglocal(9, "NdpCopy <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY); 1431 return ERROR_CANNOT_COPY; 1529 1432 } 1530 1433 1531 1434 int APIENTRY NdpCopy2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption) 1532 1435 { 1533 debuglocal(9,"NdpCopy2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);1534 return ERROR_CANNOT_COPY;1436 debuglocal(9, "NdpCopy2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY); 1437 return ERROR_CANNOT_COPY; 1535 1438 } 1536 1439 1537 1440 int APIENTRY NdpForceDelete (HCONNECTION conn, NDFILEINFOL *pfi, char *szFile) 1538 1441 { 1539 Connection *pConn = (Connection *)conn;1540 Resource *pRes = pConn->pRes;1541 int rc = 0;1542 unsigned long action;1543 char path[CCHMAXPATH+1] = {0};1544 1545 ENTER();1546 1547 debuglocal(9,"NdpForceDelete in [%p]\n", pConn);1548 1549 dircache_invalidate(szFile, pRes->pdc, 1);1550 1551 do {1552 rc = pathparser(pRes, pConn, szFile, path);1553 if (rc)1554 { 1555 break; 1556 } 1557 1558 rc = smbwrp_unlink(pConn->cli, path); 1559 } while (0);1560 debuglocal(9,"NdpForceDelete <%s> (%s) %d\n", szFile, path, rc); 1561 LEAVE();1562 return rc;1442 Connection *pConn = (Connection *)conn; 1443 Resource *pRes = pConn->pRes; 1444 int rc = 0; 1445 unsigned long action; 1446 char path[CCHMAXPATH+1] = {0}; 1447 1448 ENTER(); 1449 1450 debuglocal(9, "NdpForceDelete in [%p]\n", pConn); 1451 1452 dircache_invalidate(szFile, pRes->pdc, 1); 1453 1454 do { 1455 rc = pathparser(pRes, pConn, szFile, path); 1456 if (rc) 1457 break; 1458 1459 rc = smbwrp_unlink(pConn->cli, path); 1460 } while (0); 1461 1462 debuglocal(9, "NdpForceDelete <%s> (%s) %d\n", szFile, path, rc); 1463 1464 LEAVE(); 1465 return rc; 1563 1466 } 1564 1467 1565 1468 int APIENTRY NdpCreateDir (HCONNECTION conn, NDFILEINFOL *pfiparent, char *szDirName, FEALIST *pFEAList) 1566 1469 { 1567 Connection *pConn = (Connection *)conn; 1568 Resource *pRes = pConn->pRes; 1569 int rc = 0; 1570 int rcEASet = 0; 1571 unsigned long action; 1572 char path[CCHMAXPATH+1] = {0}; 1573 1574 ENTER(); 1575 1576 debuglocal(9,"NdpCreateDir in [%p]\n", pConn); 1577 1578 dircache_invalidate(szDirName, pRes->pdc, 1); 1579 1580 do { 1581 rc = pathparser(pRes, pConn, szDirName, path); 1582 if (rc) 1583 { 1584 break; 1585 } 1586 1587 rc = smbwrp_mkdir(pConn->cli, path); 1588 } while (0); 1589 LEAVE(); 1590 1591 if (path && pRes->easupport) 1592 { 1593 rcEASet = helperEASet(pConn->cli, pFEAList, path); 1594 } 1595 debuglocal(9,"NdpCreateDir <%s> (%s) rc=%d, EASupport=%s rc=%d\n", szDirName, path, rc, pRes->easupport?"yes":"no", rcEASet); 1596 1597 return rc; 1470 Connection *pConn = (Connection *)conn; 1471 Resource *pRes = pConn->pRes; 1472 int rc = 0; 1473 int rcEASet = 0; 1474 unsigned long action; 1475 char path[CCHMAXPATH+1] = {0}; 1476 1477 ENTER(); 1478 1479 debuglocal(9, "NdpCreateDir in [%p]\n", pConn); 1480 1481 dircache_invalidate(szDirName, pRes->pdc, 1); 1482 1483 do { 1484 rc = pathparser(pRes, pConn, szDirName, path); 1485 if (rc) 1486 break; 1487 1488 rc = smbwrp_mkdir(pConn->cli, path); 1489 } while (0); 1490 1491 LEAVE(); 1492 1493 if (path && pRes->easupport) 1494 rcEASet = helperEASet(pConn->cli, pFEAList, path); 1495 1496 debuglocal(9, "NdpCreateDir <%s> (%s) rc=%d, EASupport=%s rc=%d\n", szDirName, path, rc, pRes->easupport?"yes":"no", rcEASet); 1497 1498 return rc; 1598 1499 } 1599 1500 1600 1501 int APIENTRY NdpDeleteDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szDir) 1601 1502 { 1602 Connection *pConn = (Connection *)conn;1603 Resource *pRes = pConn->pRes;1604 int rc = 0;1605 unsigned long action;1606 char path[CCHMAXPATH+1] = {0};1607 1608 ENTER();1609 1610 debuglocal(9,"NdpDeleteDir in [%p]\n", pConn);1611 1612 dircache_invalidate(szDir, pRes->pdc, 1);1613 1614 do {1615 rc = pathparser(pRes, pConn, szDir, path);1616 if (rc)1617 { 1618 break; 1619 } 1620 1621 rc = smbwrp_rmdir(pConn->cli, path); 1622 } while (0);1623 debuglocal(9,"NdpDeleteDir <%s> (%s) %d\n", szDir, path, rc); 1624 LEAVE();1625 return rc;1503 Connection *pConn = (Connection *)conn; 1504 Resource *pRes = pConn->pRes; 1505 int rc = 0; 1506 unsigned long action; 1507 char path[CCHMAXPATH+1] = {0}; 1508 1509 ENTER(); 1510 1511 debuglocal(9, "NdpDeleteDir in [%p]\n", pConn); 1512 1513 dircache_invalidate(szDir, pRes->pdc, 1); 1514 1515 do { 1516 rc = pathparser(pRes, pConn, szDir, path); 1517 if (rc) 1518 break; 1519 1520 rc = smbwrp_rmdir(pConn->cli, path); 1521 } while (0); 1522 1523 debuglocal(9, "NdpDeleteDir <%s> (%s) %d\n", szDir, path, rc); 1524 1525 LEAVE(); 1526 return rc; 1626 1527 } 1627 1528 1628 1529 int APIENTRY NdpMove (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc) 1629 1530 { 1630 Connection *pConn = (Connection *)conn; 1631 Resource *pRes = pConn->pRes; 1632 int rc = 0; 1633 unsigned long action; 1634 char src[CCHMAXPATH+1] = {0}; 1635 int l1, l2; 1636 char * p = szDst; 1637 1638 ENTER(); 1639 1640 debuglocal(9,"NdpMove in [%p] from <%s> to <%s>\n", pConn, szSrc, szDst); 1641 1642 dircache_invalidate(szSrc, pRes->pdc, 1); 1643 dircache_invalidate(szDst, pRes->pdc, 1); 1644 1645 do 1646 { 1647 rc = pathparser(pRes, pConn, szSrc, src); 1648 if (rc) 1649 { 1650 break; 1651 } 1652 l1 = strlen(szSrc); 1653 l2 = strlen(src); 1654 if (l1 > l2) 1655 { 1656 if (ph->fsphStrNICmp(szSrc, szDst, l1 - l2)) 1657 { 1658 // the file moved accross different shares or servers or workgroups 1659 rc = ERROR_WRITE_PROTECT; 1660 break; 1661 } 1662 p = szDst + l1 - l2 + 1; 1663 } 1664 //pConn->mem[CCHMAXPATH + 1] = '\\'; 1665 rc = smbwrp_rename(pConn->cli, src, p); 1666 } while (0); 1667 debuglocal(9,"NdpMove <%s> -> <%s> (%s) %d\n", szSrc, szDst, src, rc); 1668 LEAVE(); 1669 return rc; 1531 Connection *pConn = (Connection *)conn; 1532 Resource *pRes = pConn->pRes; 1533 int rc = 0; 1534 unsigned long action; 1535 char src[CCHMAXPATH+1] = {0}; 1536 int l1, l2; 1537 char * p = szDst; 1538 1539 ENTER(); 1540 1541 debuglocal(9, "NdpMove in [%p] from <%s> to <%s>\n", pConn, szSrc, szDst); 1542 1543 dircache_invalidate(szSrc, pRes->pdc, 1); 1544 dircache_invalidate(szDst, pRes->pdc, 1); 1545 1546 do 1547 { 1548 rc = pathparser(pRes, pConn, szSrc, src); 1549 if (rc) 1550 break; 1551 1552 l1 = strlen(szSrc); 1553 l2 = strlen(src); 1554 if (l1 > l2) 1555 { 1556 if (ph->fsphStrNICmp(szSrc, szDst, l1 - l2)) 1557 { 1558 /* 1559 * the file moved accross different shares or servers or 1560 * workgroups 1561 */ 1562 rc = ERROR_WRITE_PROTECT; 1563 break; 1564 } 1565 p = szDst + l1 - l2 + 1; 1566 } 1567 rc = smbwrp_rename(pConn->cli, src, p); 1568 } while (0); 1569 1570 debuglocal(9, "NdpMove <%s> -> <%s> (%s) %d\n", szSrc, szDst, src, rc); 1571 1572 LEAVE(); 1573 return rc; 1670 1574 } 1671 1575 1672 1576 int APIENTRY NdpMove2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc) 1673 1577 { 1674 debuglocal(9,"NdpMove2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_WRITE_PROTECT);1675 return ERROR_WRITE_PROTECT;1578 debuglocal(9, "NdpMove2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_WRITE_PROTECT); 1579 return ERROR_WRITE_PROTECT; 1676 1580 } 1677 1581 … … 1679 1583 int APIENTRY NdpChangeCase (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen) 1680 1584 { 1681 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);1585 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc); 1682 1586 } 1683 1587 1684 1588 int APIENTRY NdpRename (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen) 1685 1589 { 1686 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);1590 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc); 1687 1591 } 1688 1592 1689 1593 int smbopen(Connection *pConn, char *szFileName, int flags, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList) 1690 1594 { 1691 Resource *pRes = pConn->pRes; 1692 unsigned long action; 1693 int rc = 0; 1694 char path[CCHMAXPATH+1] = {0}; 1695 1696 ENTER(); 1697 1698 debuglocal(9,"smbopen in [%p] %d\n", pConn, pConn->file.fd); 1699 1700 if (flags & O_CREAT) 1701 { 1702 dircache_invalidate(szFileName, pRes->pdc, 1); 1703 } 1704 do { 1705 if (pConn->file.fd > 0) 1706 { 1707 rc = ERROR_TOO_MANY_OPEN_FILES; 1708 break; 1709 } 1710 1711 rc = pathparser(pRes, pConn, szFileName, path); 1712 if (rc) 1713 { 1714 break; 1715 } 1716 1717 strncpy(pConn->file.fullname, szFileName, sizeof(pConn->file.fullname) - 1); 1718 strncpy(pConn->file.fname, path, sizeof(pConn->file.fname) - 1); 1719 flags |= O_BINARY; 1720 switch (ulOpenMode & 3) 1721 { 1722 case OPEN_ACCESS_READONLY : flags |= O_RDONLY; break; 1723 case OPEN_ACCESS_WRITEONLY : flags |= O_WRONLY; break; 1724 case OPEN_ACCESS_READWRITE : flags |= O_RDWR; break; 1725 default : flags |= O_RDWR; 1726 } 1727 pConn->file.openmode = flags; 1728 pConn->file.openattr = ulAttribute & 0x37; 1729 pConn->file.denymode = (ulOpenMode & 0x70) >> 4; 1730 rc = smbwrp_open(pConn->cli, &pConn->file); 1731 } while (0); 1732 debuglocal(9,"smbopen <%s> (%s) %08x %08x %08x %d. file = %d\n", szFileName, path, flags, ulOpenMode, ulAttribute, rc, pConn->file.fd); 1733 if (!rc && pFEAList) 1734 { 1735 int rc1 = NdpFileEASet((HCONNECTION)pConn, (NDFILEHANDLE)0, pFEAList); 1736 debuglocal(9,"smbopen NdpFileEASet %d. pFEAList->cbList %d\n", rc1, pFEAList->cbList); 1737 } 1738 LEAVE(); 1739 return rc; 1595 Resource *pRes = pConn->pRes; 1596 unsigned long action; 1597 int rc = 0; 1598 char path[CCHMAXPATH+1] = {0}; 1599 1600 ENTER(); 1601 1602 debuglocal(9, "smbopen in [%p] %d\n", pConn, pConn->file.fd); 1603 1604 if (flags & O_CREAT) 1605 dircache_invalidate(szFileName, pRes->pdc, 1); 1606 1607 do { 1608 if (pConn->file.fd > 0) 1609 { 1610 rc = ERROR_TOO_MANY_OPEN_FILES; 1611 break; 1612 } 1613 1614 rc = pathparser(pRes, pConn, szFileName, path); 1615 if (rc) 1616 break; 1617 1618 strncpy(pConn->file.fullname, szFileName, sizeof(pConn->file.fullname) - 1); 1619 strncpy(pConn->file.fname, path, sizeof(pConn->file.fname) - 1); 1620 flags |= O_BINARY; 1621 switch (ulOpenMode & 3) 1622 { 1623 case OPEN_ACCESS_READONLY : 1624 flags |= O_RDONLY; 1625 break; 1626 case OPEN_ACCESS_WRITEONLY : 1627 flags |= O_WRONLY; 1628 break; 1629 case OPEN_ACCESS_READWRITE : 1630 flags |= O_RDWR; 1631 break; 1632 default : 1633 flags |= O_RDWR; 1634 } 1635 1636 pConn->file.openmode = flags; 1637 pConn->file.openattr = ulAttribute & 0x37; 1638 pConn->file.denymode = (ulOpenMode & 0x70) >> 4; 1639 rc = smbwrp_open(pConn->cli, &pConn->file); 1640 } while (0); 1641 1642 debuglocal(9, "smbopen <%s> (%s) %08x %08x %08x %d. file = %d\n", szFileName, path, flags, ulOpenMode, ulAttribute, rc, pConn->file.fd); 1643 if (!rc && pFEAList) 1644 { 1645 int rc1 = NdpFileEASet((HCONNECTION)pConn, (NDFILEHANDLE)0, pFEAList); 1646 debuglocal(9, "smbopen NdpFileEASet %d. pFEAList->cbList %d\n", rc1, pFEAList->cbList); 1647 } 1648 1649 LEAVE(); 1650 return rc; 1740 1651 } 1741 1652 1742 1653 int APIENTRY NdpOpenReplace (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList) 1743 1654 { 1744 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);1655 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList); 1745 1656 } 1746 1657 1747 1658 int APIENTRY NdpOpenReplaceL(HCONNECTION conn, NDFILEINFO *pfi, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList) 1748 1659 { 1749 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);1660 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList); 1750 1661 } 1751 1662 1752 1663 int APIENTRY NdpOpenCreate (HCONNECTION conn, NDFILEINFOL *pfiparent, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList) 1753 1664 { 1754 // return smbopen((Connection *)conn, szFileName, O_CREAT, ulOpenMode, ulAttribute); 1755 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList); 1665 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList); 1756 1666 } 1757 1667 1758 1668 int APIENTRY NdpOpenCreateL(HCONNECTION conn, NDFILEINFO *pfiparent, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList) 1759 1669 { 1760 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList);1670 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList); 1761 1671 } 1762 1672 1763 1673 int APIENTRY NdpOpenExisting (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulOpenMode, USHORT *pfNeedEA) 1764 1674 { 1765 if (pfNeedEA) *pfNeedEA = 0; // wtf is this ? 1766 return smbopen((Connection *)conn, szFileName, 0, ulOpenMode, 0, NULL); 1675 if (pfNeedEA) 1676 *pfNeedEA = 0; // wtf is this ? 1677 return smbopen((Connection *)conn, szFileName, 0, ulOpenMode, 0, NULL); 1767 1678 } 1768 1679 1769 1680 int APIENTRY NdpSetFileAttribute (HCONNECTION conn, NDFILEINFOL *pfi, char *szFileName, USHORT usAttr) 1770 1681 { 1771 Connection *pConn = (Connection *)conn;1772 Resource *pRes = pConn->pRes;1773 int rc = 0;1774 unsigned long action;1775 1776 smbwrp_fileinfo finfo;1777 char path[CCHMAXPATH+1] = {0};1778 1779 ENTER();1780 1781 debuglocal(9,"NdpSetFileAttribute in [%p]\n", pConn);1782 do {1783 rc = pathparser(pRes, pConn, szFileName, path);1784 if (rc) 1785 { 1786 break; 1787 } 1788 1789 memset(&finfo, 0, sizeof(finfo));1790 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1);1791 finfo.attr = usAttr & 0x37;1792 rc = smbwrp_setattr(pConn->cli, &finfo); 1793 } while (0);1794 debuglocal(9,"NdpSetFileAttribute <%s> (%s) %04x %d\n", szFileName, path, usAttr, rc); 1795 LEAVE();1796 return rc;1682 Connection *pConn = (Connection *)conn; 1683 Resource *pRes = pConn->pRes; 1684 int rc = 0; 1685 unsigned long action; 1686 1687 smbwrp_fileinfo finfo; 1688 char path[CCHMAXPATH+1] = {0}; 1689 1690 ENTER(); 1691 1692 debuglocal(9, "NdpSetFileAttribute in [%p]\n", pConn); 1693 do { 1694 rc = pathparser(pRes, pConn, szFileName, path); 1695 if (rc) 1696 break; 1697 1698 memset(&finfo, 0, sizeof(finfo)); 1699 strncpy(finfo.fname, path, sizeof(finfo.fname) - 1); 1700 finfo.attr = usAttr & 0x37; 1701 rc = smbwrp_setattr(pConn->cli, &finfo); 1702 } while (0); 1703 1704 debuglocal(9, "NdpSetFileAttribute <%s> (%s) %04x %d\n", szFileName, path, usAttr, rc); 1705 1706 LEAVE(); 1707 return rc; 1797 1708 } 1798 1709 1799 1710 int APIENTRY NdpFlush (HRESOURCE resource) 1800 1711 { 1801 debuglocal(9,"NdpFlush %d\n", ERROR_NOT_SUPPORTED); 1802 return ERROR_NOT_SUPPORTED; 1803 } 1804 1805 // Called when a new thread will call the plugin. Allows to do per thread init, like disable signals. 1712 debuglocal(9, "NdpFlush %d\n", ERROR_NOT_SUPPORTED); 1713 return ERROR_NOT_SUPPORTED; 1714 } 1715 1716 /* 1717 * Called when a new thread will call the plugin. 1718 * Allows to do per thread init, like disable signals. 1719 */ 1806 1720 #define ND_PL_INIT_THREAD 0xFFFF0000 1807 1721 1808 1722 int APIENTRY NdpIOCTL (int type, HRESOURCE resource, char *path, int function, void *in, ULONG insize, PULONG poutlen) 1809 1723 { 1810 if (function == ND_PL_INIT_THREAD)1811 {1812 smbwrp_initthread();1813 debuglocal(9, "NdpIOCTL init thread\n");1814 return NO_ERROR;1815 }1816 1817 debuglocal(9,"NdpIOCTL <%s> %d\n", path, function);1818 1819 if (in && insize > 4096)1820 {1821 char out[4096];1822 sprintf (out, "SAMBA IOCTL function = %d, parms [%s] insize = %d, *poutlen = %d", function, in, insize, *poutlen);1823 *poutlen = strlen(out);1824 strcpy (in, out);1825 return NO_ERROR;1826 }1827 1828 return ERROR_NOT_SUPPORTED;1724 if (function == ND_PL_INIT_THREAD) 1725 { 1726 smbwrp_initthread(); 1727 debuglocal(9, "NdpIOCTL init thread\n"); 1728 return NO_ERROR; 1729 } 1730 1731 debuglocal(9, "NdpIOCTL <%s> %d\n", path, function); 1732 1733 if (in && insize > 4096) 1734 { 1735 char out[4096]; 1736 sprintf (out, "SAMBA IOCTL function = %d, parms [%s] insize = %d, *poutlen = %d", function, in, insize, *poutlen); 1737 *poutlen = strlen(out); 1738 strcpy (in, out); 1739 return NO_ERROR; 1740 } 1741 1742 return ERROR_NOT_SUPPORTED; 1829 1743 } 1830 1744 1831 1745 int APIENTRY NdpFileQueryInfo (HCONNECTION conn, NDFILEHANDLE handle, void *plist) 1832 1746 { 1833 Connection *pConn = (Connection *)conn; 1834 Resource *pRes = pConn->pRes; 1835 int rc = 0; 1836 unsigned long action; 1837 smbwrp_fileinfo finfo; 1838 1839 ENTER(); 1840 1841 debug_printf("NdpFileQueryInfo in [%p]\n", pConn); 1842 do { 1843 if (pConn->file.fd < 0 || !*pConn->file.fname) 1844 { 1845 rc = ERROR_INVALID_HANDLE; 1846 break; 1847 } 1848 strncpy(finfo.fname, pConn->file.fname, sizeof(finfo.fname) - 1); 1849 rc = smbwrp_fgetattr(pConn->cli, &pConn->file, &finfo); 1850 if (!rc) 1851 { 1852 finfo.easize = -1; 1853 getfindinfoL(pConn, plist, &finfo, 0, NULL); 1854 } 1855 } while (0); 1856 debuglocal(9,"NdpFileQueryInfo <%s> %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, rc); 1857 LEAVE(); 1858 return rc; 1747 Connection *pConn = (Connection *)conn; 1748 Resource *pRes = pConn->pRes; 1749 int rc = 0; 1750 unsigned long action; 1751 smbwrp_fileinfo finfo; 1752 1753 ENTER(); 1754 1755 debuglocal(9, "NdpFileQueryInfo in [%p]\n", pConn); 1756 do { 1757 if (pConn->file.fd < 0 || !*pConn->file.fname) 1758 { 1759 rc = ERROR_INVALID_HANDLE; 1760 break; 1761 } 1762 strncpy(finfo.fname, pConn->file.fname, sizeof(finfo.fname) - 1); 1763 rc = smbwrp_fgetattr(pConn->cli, &pConn->file, &finfo); 1764 if (!rc) 1765 { 1766 finfo.easize = -1; 1767 getfindinfoL(pConn, plist, &finfo, 0, NULL); 1768 } 1769 } while (0); 1770 1771 debuglocal(9, "NdpFileQueryInfo <%s> %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, rc); 1772 1773 LEAVE(); 1774 return rc; 1859 1775 } 1860 1776 1861 1777 int APIENTRY NdpFileEAQuery (HCONNECTION conn, NDFILEHANDLE handle, GEALIST *pGEAList, FEALIST *pFEAList) 1862 1778 { 1863 Connection *pConn = (Connection *)conn; 1864 Resource *pRes = pConn->pRes; 1865 int rc = 0; 1866 unsigned long action; 1867 const int cbBuffer = 64*1024; 1868 FEALIST * pFEASrc; 1869 1870 if (!pFEAList) 1871 { 1872 return ERROR_EAS_NOT_SUPPORTED; 1873 } 1874 if (!pRes->easupport) 1875 { 1876 return ERROR_EAS_NOT_SUPPORTED; 1877 } 1878 1879 debuglocal(9,"NdpFileEAQuery in [%p] <%s>/%d pGEAList=%08x\n", pConn, pConn->file.fname, pConn->file.fd, pGEAList); 1880 1881 char *pchBuffer = (char *)malloc(cbBuffer); 1882 if (!pchBuffer) 1883 return ERROR_NOT_ENOUGH_MEMORY; 1884 1885 ENTER(); 1886 1887 do { 1888 if (pConn->file.fd < 0) 1889 { 1890 rc = ERROR_INVALID_HANDLE; 1891 break; 1892 } 1893 rc = smbwrp_flistea(pConn->cli, &pConn->file, pchBuffer, cbBuffer); 1894 pFEASrc = (FEALIST *)pchBuffer; 1895 if (rc) 1896 { 1897 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 1898 switch (rc) 1899 { 1900 case ERROR_FILE_NOT_FOUND : 1901 case ERROR_PATH_NOT_FOUND : 1902 { 1903 pFEAList->cbList = sizeof(pFEAList->cbList); 1904 rc = NO_ERROR; 1905 } break; 1906 case ERROR_BUFFER_OVERFLOW : 1907 { 1908 pFEAList->cbList = pFEASrc->cbList; 1909 } break; 1910 default : 1911 { 1912 rc = ERROR_EAS_NOT_SUPPORTED; 1913 } 1914 } 1915 } 1916 else 1917 { 1918 rc = buildFEALIST(pFEASrc, pGEAList, pFEAList); 1919 } 1920 } while (0); 1921 free(pchBuffer); 1922 debuglocal(9,"NdpFileEAQuery out <%s>/%d pFEASrc->cbList=%d pFEAList->cbList=%d rc=%d\n", pConn->file.fname, pConn->file.fd, pFEASrc->cbList, pFEAList->cbList, rc); 1923 LEAVE(); 1924 return rc; 1779 Connection *pConn = (Connection *)conn; 1780 Resource *pRes = pConn->pRes; 1781 int rc = 0; 1782 unsigned long action; 1783 const int cbBuffer = 64*1024; 1784 FEALIST * pFEASrc; 1785 1786 if (!pFEAList) 1787 return ERROR_EAS_NOT_SUPPORTED; 1788 if (!pRes->easupport) 1789 return ERROR_EAS_NOT_SUPPORTED; 1790 1791 debuglocal(9, "NdpFileEAQuery in [%p] <%s>/%d pGEAList=%08x\n", pConn, pConn->file.fname, pConn->file.fd, pGEAList); 1792 1793 char *pchBuffer = (char *)malloc(cbBuffer); 1794 if (!pchBuffer) 1795 return ERROR_NOT_ENOUGH_MEMORY; 1796 1797 ENTER(); 1798 1799 do { 1800 if (pConn->file.fd < 0) 1801 { 1802 rc = ERROR_INVALID_HANDLE; 1803 break; 1804 } 1805 rc = smbwrp_flistea(pConn->cli, &pConn->file, pchBuffer, cbBuffer); 1806 pFEASrc = (FEALIST *)pchBuffer; 1807 if (rc) 1808 { 1809 switch (rc) 1810 { 1811 case ERROR_FILE_NOT_FOUND : 1812 case ERROR_PATH_NOT_FOUND : 1813 pFEAList->cbList = sizeof(pFEAList->cbList); 1814 rc = NO_ERROR; 1815 break; 1816 case ERROR_BUFFER_OVERFLOW : 1817 pFEAList->cbList = pFEASrc->cbList; 1818 break; 1819 default : 1820 rc = ERROR_EAS_NOT_SUPPORTED; 1821 } 1822 } 1823 else 1824 rc = buildFEALIST(pFEASrc, pGEAList, pFEAList); 1825 1826 } while (0); 1827 1828 free(pchBuffer); 1829 debuglocal(9, "NdpFileEAQuery out <%s>/%d pFEASrc->cbList=%d pFEAList->cbList=%d rc=%d\n", pConn->file.fname, pConn->file.fd, pFEASrc->cbList, pFEAList->cbList, rc); 1830 1831 LEAVE(); 1832 return rc; 1925 1833 } 1926 1834 1927 1835 int APIENTRY NdpFileEASet (HCONNECTION conn, NDFILEHANDLE handle, FEALIST *pFEAList) 1928 1836 { 1929 Connection *pConn = (Connection *)conn; 1930 Resource *pRes = pConn->pRes; 1931 int rc = 0; 1932 unsigned long action; 1933 1934 debuglocal(9,"NdpFileEASet in [%p]\n", pConn); 1935 1936 if (!pFEAList || pFEAList->cbList <= sizeof(long)) 1937 { 1938 return ERROR_EAS_NOT_SUPPORTED; 1939 } 1940 if (!pRes->easupport) 1941 { 1942 return ERROR_EAS_NOT_SUPPORTED; 1943 } 1944 1945 ENTER(); 1946 1947 do { 1948 // got FEA there 1949 FEA * pfea; 1950 unsigned long done = sizeof(long); 1951 if (pConn->file.fd < 0) 1952 { 1953 rc = ERROR_INVALID_HANDLE; 1954 break; 1955 } 1956 1957 pfea = pFEAList->list; 1958 while (done < pFEAList->cbList) 1959 { 1960 rc = smbwrp_fsetea(pConn->cli, &pConn->file, (char *)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue); 1961 if (rc) 1962 { 1963 break; 1964 } 1965 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue); 1966 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1967 } 1968 1969 } while (0); 1970 debuglocal(9,"NdpFileEASet %d\n", rc); 1971 LEAVE(); 1972 return rc; 1837 Connection *pConn = (Connection *)conn; 1838 Resource *pRes = pConn->pRes; 1839 int rc = 0; 1840 unsigned long action; 1841 1842 debuglocal(9, "NdpFileEASet in [%p]\n", pConn); 1843 1844 if (!pFEAList || pFEAList->cbList <= sizeof(long)) 1845 return ERROR_EAS_NOT_SUPPORTED; 1846 1847 if (!pRes->easupport) 1848 return ERROR_EAS_NOT_SUPPORTED; 1849 1850 ENTER(); 1851 1852 do { 1853 // got FEA there 1854 FEA * pfea; 1855 unsigned long done = sizeof(long); 1856 if (pConn->file.fd < 0) 1857 { 1858 rc = ERROR_INVALID_HANDLE; 1859 break; 1860 } 1861 1862 pfea = pFEAList->list; 1863 while (done < pFEAList->cbList) 1864 { 1865 rc = smbwrp_fsetea(pConn->cli, &pConn->file, (char *)(pfea + 1), pfea->cbValue ? (char *)(pfea + 1) + pfea->cbName + 1: NULL, pfea->cbValue); 1866 if (rc) 1867 break; 1868 1869 pfea = (FEA *)((char *)(pfea + 1) + pfea->cbName + 1 + pfea->cbValue); 1870 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue; 1871 } 1872 1873 } while (0); 1874 1875 debuglocal(9, "NdpFileEASet %d\n", rc); 1876 1877 LEAVE(); 1878 return rc; 1973 1879 } 1974 1880 1975 1881 int APIENTRY NdpFileEASize (HCONNECTION conn, NDFILEHANDLE handle, ULONG *pulEASize) 1976 1882 { 1977 Connection *pConn = (Connection *)conn; 1978 Resource *pRes = pConn->pRes; 1979 int rc = 0; 1980 unsigned long action; 1981 char path[CCHMAXPATH+1] = {0}; 1982 FEALIST * pFEAList; 1983 const int cbBuffer = 64*1024; 1984 1985 if (!pulEASize) 1986 { 1987 return ERROR_EAS_NOT_SUPPORTED; 1988 } 1989 if (!pRes->easupport) 1990 { 1991 return ERROR_EAS_NOT_SUPPORTED; 1992 } 1993 1994 debuglocal(9,"NdpFileEASize in [%p] <%s>/%d \n", pConn, pConn->file.fname, pConn->file.fd); 1995 1996 char *pchBuffer = (char *)malloc(cbBuffer); 1997 if (!pchBuffer) 1998 return ERROR_NOT_ENOUGH_MEMORY; 1999 2000 ENTER(); 2001 2002 do { 2003 if (pConn->file.fd < 0) 2004 { 2005 rc = ERROR_INVALID_HANDLE; 2006 break; 2007 } 2008 rc = smbwrp_flistea(pConn->cli, &pConn->file, pchBuffer, cbBuffer); 2009 pFEAList = (FEALIST*)pchBuffer; 2010 if (rc) 2011 { 2012 //rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER); 2013 switch (rc) 2014 { 2015 case ERROR_FILE_NOT_FOUND : 2016 case ERROR_PATH_NOT_FOUND : 2017 { 2018 pFEAList->cbList = sizeof(pFEAList->cbList); 2019 } /* Fall through */ 2020 case ERROR_BUFFER_OVERFLOW : 2021 { 2022 rc = NO_ERROR; 2023 } break; 2024 default : 2025 { 2026 rc = ERROR_EAS_NOT_SUPPORTED; 2027 } 2028 } 2029 } 2030 *pulEASize = pFEAList->cbList; 2031 } while (0); 2032 free(pchBuffer); 2033 debuglocal(9,"NdpFileEASize %d %d\n", *pulEASize, rc); 2034 LEAVE(); 2035 return rc; 1883 Connection *pConn = (Connection *)conn; 1884 Resource *pRes = pConn->pRes; 1885 int rc = 0; 1886 unsigned long action; 1887 char path[CCHMAXPATH+1] = {0}; 1888 FEALIST * pFEAList; 1889 const int cbBuffer = 64*1024; 1890 1891 if (!pulEASize) 1892 return ERROR_EAS_NOT_SUPPORTED; 1893 1894 if (!pRes->easupport) 1895 return ERROR_EAS_NOT_SUPPORTED; 1896 1897 debuglocal(9, "NdpFileEASize in [%p] <%s>/%d \n", pConn, pConn->file.fname, pConn->file.fd); 1898 1899 char *pchBuffer = (char *)malloc(cbBuffer); 1900 if (!pchBuffer) 1901 return ERROR_NOT_ENOUGH_MEMORY; 1902 1903 ENTER(); 1904 1905 do { 1906 if (pConn->file.fd < 0) 1907 { 1908 rc = ERROR_INVALID_HANDLE; 1909 break; 1910 } 1911 rc = smbwrp_flistea(pConn->cli, &pConn->file, pchBuffer, cbBuffer); 1912 pFEAList = (FEALIST*)pchBuffer; 1913 if (rc) 1914 { 1915 switch (rc) 1916 { 1917 case ERROR_FILE_NOT_FOUND : 1918 case ERROR_PATH_NOT_FOUND : 1919 pFEAList->cbList = sizeof(pFEAList->cbList);// Fall through */ 1920 case ERROR_BUFFER_OVERFLOW : 1921 rc = NO_ERROR; 1922 break; 1923 default : 1924 rc = ERROR_EAS_NOT_SUPPORTED; 1925 } 1926 } 1927 *pulEASize = pFEAList->cbList; 1928 } while (0); 1929 1930 free(pchBuffer); 1931 debuglocal(9, "NdpFileEASize %d %d\n", *pulEASize, rc); 1932 1933 LEAVE(); 1934 return rc; 2036 1935 } 2037 1936 2038 1937 int APIENTRY NdpFileSetInfo (HCONNECTION conn, NDFILEHANDLE handle, NDFILEINFOL *pfi) 2039 1938 { 2040 Connection *pConn = (Connection *)conn; 2041 Resource *pRes = pConn->pRes; 2042 int rc = 0; 2043 unsigned long action, attrFile; 2044 2045 ENTER(); 2046 2047 debug_printf("NdpFileSetInfo in [%p]\n", pConn); 2048 2049 // delete the dir cache 2050 dircache_invalidate(pConn->file.fullname, pRes->pdc, 1); 2051 2052 do { 2053 if (pConn->file.fd < 0 || !*pConn->file.fname) 2054 { 2055 rc = ERROR_INVALID_HANDLE; 2056 break; 2057 } 2058 attrFile = pfi->stat.attrFile; 2059 // deferred setinfo - on closing the file 2060 pConn->file.openattr = attrFile; 2061 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(pConn->file.mtime)); 2062 fsphDosDateToUnixTime(pfi->stat.fdateCreation, pfi->stat.ftimeCreation, &(pConn->file.ctime)); 2063 pConn->file.updatetime = 2; 2064 debug_printf("NdpFileSetInfo mtime %d\n", pConn->file.mtime); 2065 } while (0); 2066 debuglocal(9,"NdpFileSetInfo <%s> %08x %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, attrFile, rc); 2067 LEAVE(); 2068 return NO_ERROR; 1939 Connection *pConn = (Connection *)conn; 1940 Resource *pRes = pConn->pRes; 1941 int rc = 0; 1942 unsigned long action, attrFile; 1943 1944 ENTER(); 1945 1946 debuglocal(9, "NdpFileSetInfo in [%p]\n", pConn); 1947 1948 // delete the dir cache 1949 dircache_invalidate(pConn->file.fullname, pRes->pdc, 1); 1950 1951 do { 1952 if (pConn->file.fd < 0 || !*pConn->file.fname) 1953 { 1954 rc = ERROR_INVALID_HANDLE; 1955 break; 1956 } 1957 attrFile = pfi->stat.attrFile; 1958 // deferred setinfo - on closing the file 1959 pConn->file.openattr = attrFile; 1960 fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, &(pConn->file.mtime)); 1961 fsphDosDateToUnixTime(pfi->stat.fdateCreation, pfi->stat.ftimeCreation, &(pConn->file.ctime)); 1962 pConn->file.updatetime = 2; 1963 debuglocal(9, "NdpFileSetInfo mtime %d\n", pConn->file.mtime); 1964 } while (0); 1965 1966 debuglocal(9, "NdpFileSetInfo <%s> %08x %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, attrFile, rc); 1967 1968 LEAVE(); 1969 return NO_ERROR; 2069 1970 } 2070 1971 2071 1972 int APIENTRY NdpFileSetFilePtrL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llOffset, ULONG ulMethod, LONGLONG *pllActual) 2072 1973 { 2073 Connection *pConn = (Connection *)conn; 2074 Resource *pRes = pConn->pRes; 2075 int rc = 0; 2076 unsigned long action; 2077 2078 ENTER(); 2079 2080 debuglocal(9,"NdpFileSetFilePtrL in [%p]\n", pConn); 2081 2082 do { 2083 if (pConn->file.fd < 0) 2084 { 2085 rc = ERROR_INVALID_HANDLE; 2086 break; 2087 } 2088 2089 rc = smbwrp_lseek(pConn->cli, &pConn->file, ulMethod, llOffset); 2090 if (!rc) 2091 *pllActual = pConn->file.offset; 2092 2093 } while (0); 2094 debuglocal(9,"NdpFileSetFilePtrL <%s> %lld %lu %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llOffset, ulMethod, *pllActual, rc); 2095 LEAVE(); 2096 return rc; 1974 Connection *pConn = (Connection *)conn; 1975 Resource *pRes = pConn->pRes; 1976 int rc = 0; 1977 unsigned long action; 1978 1979 ENTER(); 1980 1981 debuglocal(9, "NdpFileSetFilePtrL in [%p]\n", pConn); 1982 1983 do { 1984 if (pConn->file.fd < 0) 1985 { 1986 rc = ERROR_INVALID_HANDLE; 1987 break; 1988 } 1989 1990 rc = smbwrp_lseek(pConn->cli, &pConn->file, ulMethod, llOffset); 1991 if (!rc) 1992 *pllActual = pConn->file.offset; 1993 1994 } while (0); 1995 1996 debuglocal(9, "NdpFileSetFilePtrL <%s> %lld %lu %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llOffset, ulMethod, *pllActual, rc); 1997 1998 LEAVE(); 1999 return rc; 2097 2000 } 2098 2001 2099 2002 int APIENTRY NdpFileSetFilePtr (HCONNECTION conn, NDFILEHANDLE handle, LONG lOffset, ULONG ulMethod, ULONG *pulActual) 2100 2003 { 2101 LONGLONG llActual;2102 int rc = NdpFileSetFilePtrL(conn, handle, lOffset, ulMethod, &llActual);2103 *pulActual = llActual & 0xFFFFFFFF;2104 debuglocal(9,"NdpFileSetFilePtr %ld %lu %ld %d\n", lOffset, ulMethod, *pulActual, rc);2105 return rc;2004 LONGLONG llActual; 2005 int rc = NdpFileSetFilePtrL(conn, handle, lOffset, ulMethod, &llActual); 2006 *pulActual = llActual & 0xFFFFFFFF; 2007 debuglocal(9, "NdpFileSetFilePtr %ld %lu %ld %d\n", lOffset, ulMethod, *pulActual, rc); 2008 return rc; 2106 2009 } 2107 2010 2108 2011 int APIENTRY NdpFileClose (HCONNECTION conn, NDFILEHANDLE handle) 2109 2012 { 2110 Connection *pConn = (Connection *)conn; 2111 Resource *pRes = pConn->pRes; 2112 int rc = 0; 2113 unsigned long action; 2114 2115 ENTER(); 2116 2117 debuglocal(9,"NdpFileClose in [%p] %d <%s>\n", pConn, pConn->file.fd, pConn->file.fd < 0 ? "!null!" : pConn->file.fname); 2118 2119 do { 2120 if (pConn->file.fd < 0) 2121 { 2122 rc = ERROR_INVALID_HANDLE; 2123 break; 2124 } 2125 2126 rc = smbwrp_close(pConn->cli, &pConn->file); 2127 2128 } while (0); 2129 debuglocal(9,"NdpFileClose %d %d\n", pConn->file.fd, rc); 2130 2131 pConn->file.fd = -1; 2132 LEAVE(); 2133 return rc; 2013 Connection *pConn = (Connection *)conn; 2014 Resource *pRes = pConn->pRes; 2015 int rc = 0; 2016 unsigned long action; 2017 2018 ENTER(); 2019 2020 debuglocal(9, "NdpFileClose in [%p] %d <%s>\n", pConn, pConn->file.fd, pConn->file.fd < 0 ? "!null!" : pConn->file.fname); 2021 2022 do { 2023 if (pConn->file.fd < 0) 2024 { 2025 rc = ERROR_INVALID_HANDLE; 2026 break; 2027 } 2028 2029 rc = smbwrp_close(pConn->cli, &pConn->file); 2030 2031 } while (0); 2032 2033 debuglocal(9, "NdpFileClose %d %d\n", pConn->file.fd, rc); 2034 pConn->file.fd = -1; 2035 2036 LEAVE(); 2037 return rc; 2134 2038 } 2135 2039 2136 2040 int APIENTRY NdpFileCommit (HCONNECTION conn, NDFILEHANDLE handle) 2137 2041 { 2138 debuglocal(9,"NdpFileCommit %d\n", NO_ERROR); 2139 return NO_ERROR; 2140 } 2141 2042 debuglocal(9, "NdpFileCommit %d\n", NO_ERROR); 2043 return NO_ERROR; 2044 } 2142 2045 2143 2046 int APIENTRY NdpFileNewSize (HCONNECTION conn, NDFILEHANDLE handle, ULONG ulLen) 2144 2047 { 2145 int rc = NdpFileNewSizeL(conn, handle, ulLen);2146 debuglocal(9,"NdpFileNewSize %ld %d\n", ulLen, rc);2147 return rc;2048 int rc = NdpFileNewSizeL(conn, handle, ulLen); 2049 debuglocal(9, "NdpFileNewSize %ld %d\n", ulLen, rc); 2050 return rc; 2148 2051 } 2149 2052 2150 2053 int APIENTRY NdpFileNewSizeL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llLen) 2151 2054 { 2152 Connection *pConn = (Connection *)conn; 2153 Resource *pRes = pConn->pRes; 2154 int rc = 0; 2155 unsigned long action; 2156 2157 ENTER(); 2158 2159 debuglocal(9,"NdpFileNewSizeL in [%p]\n", pConn); 2160 2161 do { 2162 if (pConn->file.fd < 0) 2163 { 2164 rc = ERROR_INVALID_HANDLE; 2165 break; 2166 } 2167 2168 rc = smbwrp_setfilesize(pConn->cli, &pConn->file, llLen); 2169 2170 } while (0); 2171 debuglocal(9,"NdpFileNewSizeL <%s> %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llLen, rc); 2172 LEAVE(); 2173 return rc; 2055 Connection *pConn = (Connection *)conn; 2056 Resource *pRes = pConn->pRes; 2057 int rc = 0; 2058 unsigned long action; 2059 2060 ENTER(); 2061 2062 debuglocal(9, "NdpFileNewSizeL in [%p]\n", pConn); 2063 2064 do { 2065 if (pConn->file.fd < 0) 2066 { 2067 rc = ERROR_INVALID_HANDLE; 2068 break; 2069 } 2070 2071 rc = smbwrp_setfilesize(pConn->cli, &pConn->file, llLen); 2072 2073 } while (0); 2074 2075 debuglocal(9, "NdpFileNewSizeL <%s> %lld %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llLen, rc); 2076 2077 LEAVE(); 2078 return rc; 2174 2079 } 2175 2080 … … 2178 2083 int APIENTRY NdpFileRead (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulRead, ULONG *pulActual) 2179 2084 { 2180 Connection *pConn = (Connection *)conn; 2181 Resource *pRes = pConn->pRes; 2182 int rc = 0; 2183 unsigned long done = 0; 2184 unsigned long onedone; 2185 unsigned long action; 2186 ULONG ulReadCompleted = 0; 2187 2188 ENTER(); 2189 2190 debuglocal(9,"NdpFileRead in [%p]\n", pConn); 2191 2192 do { 2193 if (pConn->file.fd < 0) 2194 { 2195 rc = ERROR_INVALID_HANDLE; 2196 break; 2197 } 2198 while (ulReadCompleted < ulRead) 2199 { 2200 ULONG ulActual; 2201 ULONG ulToRead = ulRead - ulReadCompleted; 2202 debuglocal(9,"NdpFileRead completed %d, to read %d\n", ulReadCompleted, ulToRead); 2203 if (ulToRead > NDPSMB_READ_MAX_SIZE) 2204 { 2205 ulToRead = NDPSMB_READ_MAX_SIZE; 2206 } 2207 rc = smbwrp_read(pConn->cli, &pConn->file, (char *)pBuffer + ulReadCompleted, ulToRead, &ulActual); 2208 if (ulActual == 0 || rc != NO_ERROR) 2209 { 2210 break; 2211 } 2212 ulReadCompleted += ulActual; 2213 } 2214 //*pulActual = ulRead; 2215 //DosSleep(0); 2216 2217 } while (0); 2218 2219 if (ulReadCompleted > 0) 2220 { 2221 rc = NO_ERROR; /* Still were able to read some data. */ 2222 } 2223 2224 if (rc == NO_ERROR) 2225 { 2226 *pulActual = ulReadCompleted; 2227 } 2228 2229 debuglocal(9,"NdpFileRead <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulRead, *pulActual, rc); 2230 LEAVE(); 2231 return rc; 2085 Connection *pConn = (Connection *)conn; 2086 Resource *pRes = pConn->pRes; 2087 int rc = 0; 2088 unsigned long done = 0; 2089 unsigned long onedone; 2090 unsigned long action; 2091 ULONG ulReadCompleted = 0; 2092 2093 ENTER(); 2094 2095 debuglocal(9, "NdpFileRead in [%p]\n", pConn); 2096 2097 do { 2098 if (pConn->file.fd < 0) 2099 { 2100 rc = ERROR_INVALID_HANDLE; 2101 break; 2102 } 2103 2104 while (ulReadCompleted < ulRead) 2105 { 2106 ULONG ulActual; 2107 ULONG ulToRead = ulRead - ulReadCompleted; 2108 debuglocal(9, "NdpFileRead completed %d, to read %d\n", ulReadCompleted, ulToRead); 2109 2110 if (ulToRead > NDPSMB_READ_MAX_SIZE) 2111 ulToRead = NDPSMB_READ_MAX_SIZE; 2112 2113 rc = smbwrp_read(pConn->cli, &pConn->file, (char *)pBuffer + ulReadCompleted, ulToRead, &ulActual); 2114 if (ulActual == 0 || rc != NO_ERROR) 2115 break; 2116 2117 ulReadCompleted += ulActual; 2118 } 2119 } while (0); 2120 2121 if (ulReadCompleted > 0) 2122 rc = NO_ERROR; // Still were able to read some data. 2123 2124 if (rc == NO_ERROR) 2125 *pulActual = ulReadCompleted; 2126 2127 debuglocal(9, "NdpFileRead <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulRead, *pulActual, rc); 2128 2129 LEAVE(); 2130 return rc; 2232 2131 } 2233 2132 2234 2133 int APIENTRY NdpFileWrite (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulWrite, ULONG *pulActual) 2235 2134 { 2236 Connection *pConn = (Connection *)conn; 2237 Resource *pRes = pConn->pRes; 2238 int rc = 0; 2239 unsigned long done = 0; 2240 unsigned long onedone; 2241 unsigned long action; 2242 2243 ENTER(); 2244 2245 debuglocal(9,"NdpFileWrite in [%p]\n", pConn); 2246 2247 /* delete the dir cache 2248 this was moved from NdpFileClose() becasue if there are a lot files in the tree all are reread 2249 the problem when moved to here is, that last accessed time is not refreshed 2250 if this is needed, a new function needs to be done to update only one file in the cache */ 2251 dircache_invalidate(pConn->file.fullname, pRes->pdc, 1); 2252 2253 do { 2254 if (pConn->file.fd < 0) 2255 { 2256 rc = ERROR_INVALID_HANDLE; 2257 break; 2258 } 2259 rc = smbwrp_write(pConn->cli, &pConn->file, pBuffer, ulWrite, pulActual); 2260 2261 } while (0); 2262 debuglocal(9,"NdpFileWrite <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulWrite, *pulActual, rc); 2263 LEAVE(); 2264 return rc; 2265 } 2266 2135 Connection *pConn = (Connection *)conn; 2136 Resource *pRes = pConn->pRes; 2137 int rc = 0; 2138 unsigned long done = 0; 2139 unsigned long onedone; 2140 unsigned long action; 2141 2142 ENTER(); 2143 2144 debuglocal(9, "NdpFileWrite in [%p]\n", pConn); 2145 2146 /* 2147 * delete the dir cache 2148 * This was moved from NdpFileClose() becasue if there are a lot files 2149 * in the tree, all are reread. The problem when moved to here is, that 2150 * the last accessed time is not refreshed. If this is needed, 2151 * a new function needs to be done to update only one file in the cache 2152 */ 2153 dircache_invalidate(pConn->file.fullname, pRes->pdc, 1); 2154 2155 do { 2156 if (pConn->file.fd < 0) 2157 { 2158 rc = ERROR_INVALID_HANDLE; 2159 break; 2160 } 2161 rc = smbwrp_write(pConn->cli, &pConn->file, pBuffer, ulWrite, pulActual); 2162 2163 } while (0); 2164 2165 debuglocal(9, "NdpFileWrite <%s> %lu %lu %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulWrite, *pulActual, rc); 2166 2167 LEAVE(); 2168 return rc; 2169 } -
trunk/client/src/smbwrp.c
r957 r959 34 34 int os2cli_errno(cli_state * cli) 35 35 { 36 if (cli->fd == -1) 37 { 38 return maperror( ENOTCONN); 39 } 40 return maperror(cli_errno(cli)); 36 if (cli->fd == -1) 37 return maperror(ENOTCONN); 38 39 return maperror(cli_errno(cli)); 41 40 } 42 41 43 42 void smbwrp_Logging() 44 43 { 45 char slogfile[_MAX_PATH +1] = {0};46 char slogfilename[] = "log.smbc";47 char *env = getenv("LOGFILES");48 if (env != NULL)49 {50 strncpy(slogfile, env, sizeof(slogfile) -1);51 strncat(slogfile, "\\", sizeof(slogfile) - strlen(slogfile) -1);52 strncat(slogfile, slogfilename, sizeof(slogfile) - strlen(slogfile) -1);53 }54 else55 { 56 strncpy(slogfile, slogfilename, sizeof(slogfile) -1); 57 } 58 59 // init samba for debug messages 60 setup_logging("ndpsmb", DEBUG_FILE);61 lp_set_logfile(slogfile);62 lp_set_cmdline("log level", "10"); 63 reopen_logs();64 65 } 44 char slogfile[_MAX_PATH +1] = {0}; 45 char slogfilename[] = "log.smbc"; 46 char *env = getenv("LOGFILES"); 47 if (env != NULL) 48 { 49 strncpy(slogfile, env, sizeof(slogfile) -1); 50 strncat(slogfile, "\\", sizeof(slogfile) - strlen(slogfile) -1); 51 strncat(slogfile, slogfilename, sizeof(slogfile) - strlen(slogfile) -1); 52 } 53 else 54 strncpy(slogfile, slogfilename, sizeof(slogfile) -1); 55 56 // init samba for debug messages 57 setup_logging("ndpsmb", DEBUG_FILE); 58 lp_set_logfile(slogfile); 59 lp_set_cmdline("log level", "10"); 60 reopen_logs(); 61 62 return; 63 } 64 66 65 const char * smbwrp_getVersion() 67 66 { 68 return samba_version_string();67 return samba_version_string(); 69 68 } 70 69 71 70 int _System smbwrp_getclisize(void) 72 71 { 73 return sizeof(struct cli_state);74 } 75 76 /* ****************************************************77 initialise structures78 *******************************************************/72 return sizeof(struct cli_state); 73 } 74 75 /* 76 * initialise structures 77 */ 79 78 int _System smbwrp_init(void) 80 79 { 81 static int initialised = 0; 82 char *p; 83 84 if (initialised) 85 { 86 return 0; 87 } 88 initialised = 1; 89 90 lp_set_in_client(true); /* Make sure that we tell lp_load we are client */ 91 92 load_case_tables(); 93 94 if (!lp_load(get_dyn_CONFIGFILE(),true,false,false,true)) { 95 debuglocal(0,("The initial smb.conf is missing, defaults are used!\n")); 96 } 97 98 load_interfaces(); 99 100 if (!init_names()) 101 { 102 return 1; 103 } 104 105 if (writeLog()) 106 { 107 smbwrp_Logging(); 108 } 109 110 /* 111 if ((p=smbw_getshared("RESOLVE_ORDER"))) { 112 lp_set_name_resolve_order(p); 113 } 114 */ 115 return 0; 80 static int initialised = 0; 81 char *p; 82 83 if (initialised) 84 return 0; 85 86 initialised = 1; 87 88 lp_set_in_client(true); // Make sure that we tell lp_load we are client 89 90 load_case_tables(); 91 92 if (!lp_load(get_dyn_CONFIGFILE(),true,false,false,true)) 93 debuglocal(0,("The initial smb.conf is missing, defaults are used!\n")); 94 95 load_interfaces(); 96 97 if (!init_names()) 98 return 1; 99 100 if (writeLog()) 101 smbwrp_Logging(); 102 103 /* 104 if ((p=smbw_getshared("RESOLVE_ORDER"))) 105 lp_set_name_resolve_order(p); 106 */ 107 return 0; 116 108 117 109 } … … 119 111 void smbwrp_initthread(void) 120 112 { 121 /*122 Block SIGPIPE (from lib/util_sock.c: write())123 It is not needed and should not stop execution124 */125 BlockSignals(True, SIGPIPE);113 /* 114 * Block SIGPIPE (from lib/util_sock.c: write()) 115 * It is not needed and should not stop execution 116 */ 117 BlockSignals(True, SIGPIPE); 126 118 } 127 119 128 120 #if 0 129 /* ****************************************************130 remove redundent stuff from a filename131 *******************************************************/121 /* 122 * remove redundent stuff from a filename 123 */ 132 124 void clean_fname(char *name) 133 125 { 134 char *p, *p2;135 int l;136 int modified = 1;137 138 if (!name) return;139 140 while (modified) {141 modified = 0;142 143 if ((p=strstr(name,"/./"))) {144 modified = 1;145 while (*p) {146 p[0] = p[2];147 p++;148 }149 }150 151 if ((p=strstr(name,"//"))) {152 modified = 1;153 while (*p) {154 p[0] = p[1];155 p++;156 }157 }158 159 if (strcmp(name,"/../")==0) {160 modified = 1;161 name[1] = 0;162 }163 164 if ((p=strstr(name,"/../"))) {165 modified = 1;166 for (p2=(p>name?p-1:p);p2>name;p2--) {167 if (p2[0] == '/') break; 168 } 169 while (*p2) { 170 p2[0] = p2[3]; 171 p2++;172 } 173 }174 175 if (strcmp(name,"/..")==0) { 176 modified = 1; 177 name[1] = 0;178 } 179 180 l = strlen(name); 181 p = l>=3?(name+l-3):name;182 if (strcmp(p,"/..")==0) { 183 modified = 1; 184 for (p2=p-1;p2>name;p2--) { 185 if (p2[0] == '/') break; 186 } 187 if (p2==name) { 188 p[0] = '/'; 189 p[1] = 0; 190 } else { 191 p2[0] = 0;192 } 193 } 194 195 l = strlen(name); 196 p = l>=2?(name+l-2):name;197 if (strcmp(p,"/.")==0) { 198 if (p == name) {199 p[1] = 0; 200 } else { 201 p[0] = 0; 202 } 203 }204 205 if (strncmp(p=name,"./",2) == 0) {206 modified = 1;207 do {208 p[0] = p[2];209 } while (*p++);210 }211 212 l = strlen(p=name);213 if (l > 1 && p[l-1] == '/') {214 modified = 1;215 p[l-1] = 0;216 }217 }126 char *p, *p2; 127 int l; 128 int modified = 1; 129 130 if (!name) return; 131 132 while (modified) { 133 modified = 0; 134 135 if ((p=strstr(name,"/./"))) { 136 modified = 1; 137 while (*p) { 138 p[0] = p[2]; 139 p++; 140 } 141 } 142 143 if ((p=strstr(name,"//"))) { 144 modified = 1; 145 while (*p) { 146 p[0] = p[1]; 147 p++; 148 } 149 } 150 151 if (strcmp(name,"/../")==0) { 152 modified = 1; 153 name[1] = 0; 154 } 155 156 if ((p=strstr(name,"/../"))) { 157 modified = 1; 158 for (p2=(p>name?p-1:p);p2>name;p2--) { 159 if (p2[0] == '/') 160 break; 161 } 162 while (*p2) { 163 p2[0] = p2[3]; 164 p2++; 165 } 166 } 167 168 if (strcmp(name,"/..")==0) { 169 modified = 1; 170 name[1] = 0; 171 } 172 173 l = strlen(name); 174 p = l >= 3 ? (name+l-3):name; 175 if (strcmp(p,"/..")==0) { 176 modified = 1; 177 for (p2=p-1;p2>name;p2--) { 178 if (p2[0] == '/') 179 break; 180 } 181 if (p2==name) { 182 p[0] = '/'; 183 p[1] = 0; 184 } else 185 p2[0] = 0; 186 } 187 188 l = strlen(name); 189 p = l >= 2 ? (name+l-2):name; 190 if (strcmp(p,"/.")==0) { 191 if (p == name) 192 p[1] = 0; 193 else 194 p[0] = 0; 195 } 196 197 if (strncmp(p=name,"./",2) == 0) { 198 modified = 1; 199 do { 200 p[0] = p[2]; 201 } while (*p++); 202 } 203 204 l = strlen(p=name); 205 if (l > 1 && p[l-1] == '/') { 206 modified = 1; 207 p[l-1] = 0; 208 } 209 } 218 210 } 219 211 #endif 220 212 221 /* ****************************************************222 return a connection to a server223 *******************************************************/213 /* 214 * return a connection to a server 215 */ 224 216 int _System smbwrp_connect( Resource* pRes, cli_state ** cli) 225 217 { 226 smbwrp_server * srv = &pRes->srv; 227 char * server = srv->server_name; 228 char * share = *(srv->share_name) ? srv->share_name : "IPC$"; 229 char * workgroup = srv->workgroup; 230 struct nmb_name called, calling; 231 char *p, *server_n = server; 232 fstring group; 233 struct sockaddr_storage ss; 234 struct cli_state * c; 235 char* dev_type; 236 int loginerror = 0; 237 NTSTATUS status; 238 239 zero_sockaddr(&ss); 240 241 debuglocal(1,"Connecting to \\\\%s:*********@%s:%s\\%s. Master %s:%d\n", srv->username, workgroup, server, share, srv->master, srv->ifmastergroup); 242 243 if (!*server) { 244 struct sockaddr_storage sip; 245 246 if (*workgroup) 247 { 248 if (!find_master_ip(workgroup, &sip)) { 249 return 1; 250 } 251 fstrcpy(group, inet_ntoa(sip.sin_addr)); 252 server_n = group; 253 } else 254 if (*srv->master) 255 { 256 if (srv->ifmastergroup) 257 { 258 if (!find_master_ip(srv->master, &sip)) { 259 return 11; 260 } 261 strncpy(srv->master, inet_ntoa(sip.sin_addr), sizeof(srv->master) - 1); 262 srv->ifmastergroup = 0; 263 } 264 server_n = srv->master; 265 } else 266 { 267 return 10; 268 } 269 } 270 271 make_nmb_name(&calling, global_myname(), 0x0); 272 // make_nmb_name(&calling, "WORK", 0x0); // this machine name 273 make_nmb_name(&called , server_n, 0x20); 218 smbwrp_server * srv = &pRes->srv; 219 char * server = srv->server_name; 220 char * share = *(srv->share_name) ? srv->share_name : "IPC$"; 221 char * workgroup = srv->workgroup; 222 struct nmb_name called, calling; 223 char *p, *server_n = server; 224 fstring group; 225 struct sockaddr_storage ss; 226 struct cli_state * c; 227 char* dev_type; 228 int loginerror = 0; 229 NTSTATUS status; 230 231 zero_sockaddr(&ss); 232 233 debuglocal(1,"Connecting to \\\\%s:*********@%s:%s\\%s. Master %s:%d\n", srv->username, workgroup, server, share, srv->master, srv->ifmastergroup); 234 235 if (!*server) { 236 struct sockaddr_storage sip; 237 238 if (*workgroup) 239 { 240 if (!find_master_ip(workgroup, &sip)) 241 return 1; 242 243 fstrcpy(group, inet_ntoa(sip.sin_addr)); 244 server_n = group; 245 } else if (*srv->master) 246 { 247 if (srv->ifmastergroup) 248 { 249 if (!find_master_ip(srv->master, &sip)) 250 return 11; 251 252 strncpy(srv->master, inet_ntoa(sip.sin_addr), sizeof(srv->master) - 1); 253 srv->ifmastergroup = 0; 254 } 255 server_n = srv->master; 256 } else 257 return 10; 258 } 259 260 make_nmb_name(&calling, global_myname(), 0x0); 261 //make_nmb_name(&calling, "WORK", 0x0); // this machine name 262 make_nmb_name(&called , server_n, 0x20); 274 263 275 264 again: 276 zero_sockaddr(&ss); 277 278 /* have to open a new connection */ 279 if (!(c=cli_initialise())) 280 { 281 return 2; 282 } 283 284 cli_set_timeout(c, 10000); /* 10 seconds. */ 285 286 if (pRes->krb5support == 1) 287 { 288 debuglocal(1,"Kerberos support enabled\n"); 289 c->use_kerberos = True; 290 } 291 292 if (!NT_STATUS_IS_OK(cli_connect(c, server_n, &ss))) 293 { 294 return 3; 295 } 296 297 if (!cli_session_request(c, &calling, &called)) { 298 cli_shutdown(c); 299 if (strcmp(called.name, "*SMBSERVER")) { 300 make_nmb_name(&called , "*SMBSERVER", 0x20); 301 goto again; 302 } 303 return 4; 304 } 305 306 debuglocal(4," session request ok\n"); 307 308 if (!NT_STATUS_IS_OK(cli_negprot(c))) { 309 cli_shutdown(c); 310 return 5; 311 } 312 313 debuglocal(4," session setuping for <%s>/<********> in <%s> %08x %08x %08x\n", srv->username, workgroup, c->protocol, c->sec_mode, c->capabilities); 314 315 if (!NT_STATUS_IS_OK(cli_session_setup(c, srv->username, 316 srv->password, strlen(srv->password), 317 srv->password, strlen(srv->password), 318 workgroup))) { 319 debuglocal(4,"%s/******** login failed\n", srv->username); 320 loginerror = 1; // save the login error 321 322 /* try an anonymous login if it failed */ 323 if (!NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0,"", 0, workgroup))) { 324 debuglocal(4,"Anonymous login failed\n"); 325 cli_shutdown(c); 326 return 6; 327 } 328 debuglocal(4,"Anonymous login successful\n"); 329 status = cli_init_creds(c, "", lp_workgroup(), ""); 330 } else { 331 status = cli_init_creds(c, srv->username, workgroup, srv->password); 332 } 333 334 if (!NT_STATUS_IS_OK(status)) { 335 debuglocal(4,"cli_init_creds() failed\n"); 336 cli_shutdown(c); 337 // if loginerror is != 0 means normal login failed, but anonymous login worked 338 if (loginerror !=0) 339 return 6; 340 else 341 return 7; 342 } 343 344 debuglocal(4," session setup ok. Sending tconx <%s> <********>\n", share); 345 346 // YD ticket:58 we need to check resource type to avoid connecting to printers. 347 // dev type is set to IPC for IPC$, A: for everything else (printers use LPT1:) 348 if (!strcmp( share, "IPC$")) 349 dev_type = "IPC"; 350 else 351 dev_type = "A:"; 352 353 if (!NT_STATUS_IS_OK(cli_tcon_andx(c, share, dev_type, 354 srv->password, strlen(srv->password)+1))) { 355 cli_shutdown(c); 356 // if loginerror is != 0 means normal login failed, but anonymous login worked 357 if (loginerror !=0) 358 return 6; 359 else 360 return 7; 361 } 362 363 debuglocal(4," tconx ok. cli caps %08x\n", c->capabilities); 265 zero_sockaddr(&ss); 266 267 // have to open a new connection 268 if (!(c=cli_initialise())) 269 return 2; 270 271 cli_set_timeout(c, 10000); // 10 seconds 272 273 if (pRes->krb5support == 1) 274 { 275 debuglocal(1,"Kerberos support enabled\n"); 276 c->use_kerberos = True; 277 } 278 279 if (!NT_STATUS_IS_OK(cli_connect(c, server_n, &ss))) 280 return 3; 281 282 if (!cli_session_request(c, &calling, &called)) { 283 cli_shutdown(c); 284 if (strcmp(called.name, "*SMBSERVER")) { 285 make_nmb_name(&called , "*SMBSERVER", 0x20); 286 goto again; 287 } 288 return 4; 289 } 290 291 debuglocal(4," session request ok\n"); 292 293 if (!NT_STATUS_IS_OK(cli_negprot(c))) { 294 cli_shutdown(c); 295 return 5; 296 } 297 298 debuglocal(4," session setuping for <%s>/<********> in <%s> %08x %08x %08x\n", srv->username, workgroup, c->protocol, c->sec_mode, c->capabilities); 299 300 if (!NT_STATUS_IS_OK(cli_session_setup(c, srv->username, 301 srv->password, strlen(srv->password), 302 srv->password, strlen(srv->password), 303 workgroup))) 304 { 305 debuglocal(4,"%s/******** login failed\n", srv->username); 306 loginerror = 1; // save the login error 307 308 // try an anonymous login if it failed 309 if (!NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0,"", 0, workgroup))) { 310 debuglocal(4,"Anonymous login failed\n"); 311 cli_shutdown(c); 312 return 6; 313 } 314 debuglocal(4,"Anonymous login successful\n"); 315 status = cli_init_creds(c, "", lp_workgroup(), ""); 316 } else { 317 status = cli_init_creds(c, srv->username, workgroup, srv->password); 318 } 319 320 if (!NT_STATUS_IS_OK(status)) { 321 debuglocal(4,"cli_init_creds() failed\n"); 322 cli_shutdown(c); 323 // if loginerror is != 0 means normal login failed, but anonymous login worked 324 if (loginerror !=0) 325 return 6; 326 else 327 return 7; 328 } 329 330 debuglocal(4," session setup ok. Sending tconx <%s> <********>\n", share); 331 332 // YD ticket:58 we need to check resource type to avoid connecting to printers. 333 // dev type is set to IPC for IPC$, A: for everything else (printers use LPT1:) 334 if (!strcmp( share, "IPC$")) 335 dev_type = "IPC"; 336 else 337 dev_type = "A:"; 338 339 if (!NT_STATUS_IS_OK(cli_tcon_andx(c, share, dev_type, 340 srv->password, strlen(srv->password)+1))) 341 { 342 cli_shutdown(c); 343 // if loginerror is != 0 means normal login failed, but anonymous login worked 344 if (loginerror !=0) 345 return 6; 346 else 347 return 7; 348 } 349 350 debuglocal(4," tconx ok. cli caps %08x\n", c->capabilities); 364 351 365 // save cli_state pointer366 *cli = c;367 368 return 0;369 } 370 371 /* ****************************************************372 close a connection to a server373 *******************************************************/352 // save cli_state pointer 353 *cli = c; 354 355 return 0; 356 } 357 358 /* 359 * close a connection to a server 360 */ 374 361 void _System smbwrp_disconnect( Resource* pRes, cli_state * cli) 375 362 { 376 if (pRes && cli) 377 { 378 // this call will free all buffers, close handles and free cli mem 379 cli_shutdown( cli); 380 } 381 } 382 383 384 385 /***************************************************** 386 a wrapper for open() 387 *******************************************************/ 363 // this call will free all buffers, close handles and free cli mem 364 if (pRes && cli) 365 cli_shutdown( cli); 366 } 367 368 /* 369 * a wrapper for open() 370 */ 388 371 int _System smbwrp_open(cli_state * cli, smbwrp_file * file) 389 372 { 390 uint16_t fd = 0; 391 392 if (!cli || !file || !*file->fname) 393 { 394 return maperror(EINVAL); 395 } 396 if (file->denymode < DENY_ALL || file->denymode > DENY_NONE) 397 { 398 file->denymode = DENY_NONE; 399 } 400 401 debuglocal(4,"cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 402 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 403 { 404 return os2cli_errno(cli); 405 } 406 file->fd = fd; 407 file->updatetime = 0; 408 file->offset = 0; 409 return 0; 410 } 411 412 /***************************************************** 413 a wrapper for read() 414 *******************************************************/ 373 uint16_t fd = 0; 374 375 if (!cli || !file || !*file->fname) 376 return maperror(EINVAL); 377 378 if (file->denymode < DENY_ALL || file->denymode > DENY_NONE) 379 file->denymode = DENY_NONE; 380 381 debuglocal(4,"cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 382 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 383 return os2cli_errno(cli); 384 385 file->fd = fd; 386 file->updatetime = 0; 387 file->offset = 0; 388 return 0; 389 } 390 391 /* 392 * a wrapper for read() 393 */ 415 394 int _System smbwrp_read(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result) 416 395 { 417 int ret; 418 419 if (!cli || !file || !buf || !result) 420 { 421 return maperror(EINVAL); 422 } 396 int ret; 397 398 if (!cli || !file || !buf || !result) 399 return maperror(EINVAL); 423 400 424 *result = 0; 425 ret = cli_read(cli, file->fd, buf, file->offset, count); 426 if (ret == -1) 427 { 428 return os2cli_errno(cli); 429 } 430 431 file->offset += ret; 432 *result = ret; 433 return 0; 434 } 435 401 *result = 0; 402 ret = cli_read(cli, file->fd, buf, file->offset, count); 403 if (ret == -1) 404 return os2cli_errno(cli); 405 406 file->offset += ret; 407 *result = ret; 408 return 0; 409 } 410 411 /* 412 * a wrapper for write() 413 */ 414 int _System smbwrp_write(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result) 415 { 416 NTSTATUS status; 417 size_t ret; 418 419 if (!cli || !file || !buf || !result) 420 return maperror(EINVAL); 436 421 437 438 /***************************************************** 439 a wrapper for write() 440 *******************************************************/ 441 int _System smbwrp_write(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result) 442 { 443 NTSTATUS status; 444 size_t ret; 445 446 if (!cli || !file || !buf || !result) 447 { 448 return maperror(EINVAL); 449 } 422 *result = 0; 423 //debuglocal(1,("Write %x %d %lld %d", cli, file->fd, file->offset, count)); 424 status = cli_writeall(cli, file->fd, 0, buf, file->offset, count, &ret); 425 if (!NT_STATUS_IS_OK(status)) 426 return os2cli_errno(cli); 427 428 file->updatetime = 1; 429 file->offset += ret; 430 *result = ret; 431 return 0; 432 } 433 434 /* 435 * a wrapper for close() 436 */ 437 int _System smbwrp_close(cli_state * cli, smbwrp_file * file) 438 { 439 int rc = 0; 440 if (!cli || !file) 441 return maperror(EINVAL); 442 443 debuglocal(4,"smpwrp_close updatetime: %d\n", file->updatetime); 444 445 if (file->updatetime == 1) 446 { 447 file->mtime = time(NULL); 448 debuglocal(4,"cli_close new mtime %lu\n", file->mtime); 449 } 450 450 451 *result = 0; 452 //debuglocal(1,("Write %x %d %lld %d", cli, file->fd, file->offset, count)); 453 status = cli_writeall(cli, file->fd, 0, buf, file->offset, count, &ret); 454 if (!NT_STATUS_IS_OK(status)) { 455 return os2cli_errno(cli); 456 } 457 458 file->updatetime = 1; 459 file->offset += ret; 460 *result = ret; 461 return 0; 462 } 463 464 /***************************************************** 465 a wrapper for close() 466 *******************************************************/ 467 int _System smbwrp_close(cli_state * cli, smbwrp_file * file) 468 { 469 int rc = 0; 470 if (!cli || !file) 471 { 472 return maperror(EINVAL); 473 } 474 475 debuglocal(4,"smpwrp_close updatetime: %d\n", file->updatetime); 476 477 if (file->updatetime == 1) 478 { 479 file->mtime = time(NULL); 480 debuglocal(4,"cli_close new mtime %lu\n", file->mtime); 481 } 451 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 452 rc = os2cli_errno(cli); 453 454 if (!rc && (file->openattr || file->mtime || file->ctime)) 455 { 456 debuglocal(4,"Set pathinfo on close %s %08x %d %d\n", file->fname, file->openattr, file->mtime, file->ctime); 457 if (!NT_STATUS_IS_OK(cli_setpathinfo_basic(cli, file->fname, file->ctime, 0, file->mtime, 0, file->openattr))) 458 debuglocal(4,"Set pathinfo on close failed %d\n", os2cli_errno(cli)); 459 } 460 461 file->openattr = 0; 462 file->mtime = 0; 463 file->ctime = 0; 464 file->updatetime = 0; 465 file->fd = -1; 466 file->offset = 0; 467 *file->fname = 0; 468 return rc; 469 } 470 471 int _System smbwrp_setfilesize(cli_state * cli, smbwrp_file * file, long long newsize) 472 { 473 int rc = 0; 474 if (!cli || !file) 475 return maperror(EINVAL); 476 477 debuglocal(4,"cli_setnewfilesize(%s) %lld\n", file->fname, newsize); 478 if (!NT_STATUS_IS_OK(cli_ftruncate(cli, file->fd, newsize))) 479 { 480 if (newsize) 481 rc = os2cli_errno(cli); 482 483 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 484 return os2cli_errno(cli); 485 486 uint16_t fd = 0; 487 file->fd = -1; 488 file->offset = 0; 489 file->openmode &= ~(O_CREAT | O_EXCL); 490 file->openmode |= O_TRUNC; 491 debuglocal(4,"cli_setnewfileszie : cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 492 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 493 return os2cli_errno(cli); 494 495 file->fd = fd; 496 } 497 return 0; 498 } 499 500 /* 501 * a wrapper for rename() 502 */ 503 int _System smbwrp_rename(cli_state * cli, char *oldname, char *newname) 504 { 505 if (!cli || !oldname || !newname) 506 return maperror(EINVAL); 507 508 debuglocal(1,"Rename <%s> -> <%s>\n", oldname, newname); 509 if (!NT_STATUS_IS_OK(cli_rename(cli, oldname, newname))) 510 return os2cli_errno(cli); 511 512 return 0; 513 } 514 515 516 /* 517 * a wrapper for chmod() 518 */ 519 int _System smbwrp_setattr(cli_state * cli, smbwrp_fileinfo *finfo) 520 { 521 if (!cli || !finfo || !*finfo->fname) 522 return maperror(EINVAL); 523 524 debuglocal(4,"Setting on <%s> attr %04x, time %lu (timezone /%lu\n", finfo->fname, finfo->attr, finfo->mtime, finfo->mtime + get_time_zone(finfo->mtime)); 525 // we already have gmt time, so no need to add timezone 526 // if (!cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime + (finfo->mtime == 0 ? 0 : get_time_zone(finfo->mtime))) 527 if (!NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime)) 528 && !NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, 0))) 529 return os2cli_errno(cli); 482 530 483 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 484 { 485 rc = os2cli_errno(cli); 486 } 487 488 if (!rc && (file->openattr || file->mtime || file->ctime)) 489 { 490 debuglocal(4,"Set pathinfo on close %s %08x %d %d\n", file->fname, file->openattr, file->mtime, file->ctime); 491 if (!NT_STATUS_IS_OK(cli_setpathinfo_basic(cli, file->fname, file->ctime, 0, file->mtime, 0, file->openattr))) 492 { 493 debuglocal(4,"Set pathinfo on close failed %d\n", os2cli_errno(cli)); 494 //rc = os2cli_errno(cli); 495 } 496 } 497 498 file->openattr = 0; 499 file->mtime = 0; 500 file->ctime = 0; 501 file->updatetime = 0; 502 file->fd = -1; 503 file->offset = 0; 504 *file->fname = 0; 505 return rc; 506 } 507 508 int _System smbwrp_setfilesize(cli_state * cli, smbwrp_file * file, long long newsize) 509 { 510 int rc = 0; 511 if (!cli || !file) 512 { 513 return maperror(EINVAL); 514 } 515 516 debuglocal(4,"cli_setnewfilesize(%s) %lld\n", file->fname, newsize); 517 if (!NT_STATUS_IS_OK(cli_ftruncate(cli, file->fd, newsize))) 518 { 519 if (newsize) 520 { 521 rc = os2cli_errno(cli); 522 } 523 524 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 525 { 526 return os2cli_errno(cli); 527 } 528 uint16_t fd = 0; 529 file->fd = -1; 530 file->offset = 0; 531 file->openmode &= ~(O_CREAT | O_EXCL); 532 file->openmode |= O_TRUNC; 533 debuglocal(4,"cli_setnewfileszie : cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 534 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 535 { 536 return os2cli_errno(cli); 537 } 538 file->fd = fd; 539 } 540 return 0; 541 } 542 543 /***************************************************** 544 a wrapper for rename() 545 *******************************************************/ 546 int _System smbwrp_rename(cli_state * cli, char *oldname, char *newname) 547 { 548 if (!cli || !oldname || !newname) 549 { 550 return maperror(EINVAL); 551 } 552 553 debuglocal(1,"Rename <%s> -> <%s>\n", oldname, newname); 554 if (!NT_STATUS_IS_OK(cli_rename(cli, oldname, newname))) 555 { 556 return os2cli_errno(cli); 557 } 558 return 0; 559 } 560 561 562 /***************************************************** 563 a wrapper for chmod() 564 *******************************************************/ 565 int _System smbwrp_setattr(cli_state * cli, smbwrp_fileinfo *finfo) 566 { 567 if (!cli || !finfo || !*finfo->fname) 568 { 569 return maperror(EINVAL); 570 } 571 572 debuglocal(4,"Setting on <%s> attr %04x, time %lu (timezone /%lu\n", finfo->fname, finfo->attr, finfo->mtime, finfo->mtime + get_time_zone(finfo->mtime)); 573 // we already have gmt time, so no need to add timezone 574 // if (!cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime + (finfo->mtime == 0 ? 0 : get_time_zone(finfo->mtime))) 575 if (!NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime)) 576 && !NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, 0))) 577 { 578 return os2cli_errno(cli); 579 } 580 return 0; 581 } 582 583 /***************************************************** 584 a wrapper for unlink() 585 *******************************************************/ 531 return 0; 532 } 533 534 /* 535 * a wrapper for unlink() 536 */ 586 537 int _System smbwrp_unlink(cli_state * cli, const char *fname) 587 538 { 588 if (!cli || !fname) 589 { 590 return maperror(EINVAL); 591 } 539 if (!cli || !fname) 540 return maperror(EINVAL); 541 592 542 #if 0 593 if (strncmp(cli->dev, "LPT", 3) == 0) 594 { 595 int job = smbw_stat_printjob(cli, fname, NULL, NULL); 596 if (job == -1) 597 { 598 goto failed; 599 } 600 if (cli_printjob_del(cli, job) != 0) 601 { 602 goto failed; 603 } 604 } else 543 if (strncmp(cli->dev, "LPT", 3) == 0) 544 { 545 int job = smbw_stat_printjob(cli, fname, NULL, NULL); 546 if (job == -1) 547 goto failed; 548 549 if (cli_printjob_del(cli, job) != 0) 550 goto failed; 551 552 } else 605 553 #endif 606 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) 607 { 608 return os2cli_errno(cli); 609 } 610 return 0; 611 } 612 613 /***************************************************** 614 a wrapper for lseek() 615 *******************************************************/ 554 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) 555 return os2cli_errno(cli); 556 557 return 0; 558 } 559 560 /* 561 * a wrapper for lseek() 562 */ 616 563 int _System smbwrp_lseek(cli_state * cli, smbwrp_file * file, int whence, long long offset) 617 564 { 618 off_t size; 619 if (!cli || !file) 620 { 621 return maperror(EINVAL); 622 } 623 624 debuglocal(4,"lseek %d %lld %lld\n", whence, offset, file->offset); 625 626 switch (whence) { 627 case SEEK_SET: 628 if (offset < 0) 629 { 630 return maperror(EINVAL); 631 } 632 file->offset = offset; 633 break; 634 case SEEK_CUR: 635 file->offset += offset; 636 break; 637 case SEEK_END: 638 if (offset > 0) 639 { 640 return maperror(EINVAL); 641 } 642 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 643 NULL, &size, NULL, NULL, NULL, 644 NULL, NULL)) && 645 !NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 646 NULL, &size, NULL, NULL, NULL))) 647 { 648 return os2cli_errno(cli); 649 } 650 file->offset = size + offset; 651 break; 652 default: return maperror(EINVAL); 653 } 654 655 return 0; 656 } 657 658 /***************************************************** 659 try to do a QPATHINFO and if that fails then do a getatr 660 this is needed because win95 sometimes refuses the qpathinfo 661 *******************************************************/ 565 off_t size; 566 if (!cli || !file) 567 return maperror(EINVAL); 568 569 debuglocal(4,"lseek %d %lld %lld\n", whence, offset, file->offset); 570 571 switch (whence) { 572 case SEEK_SET: 573 if (offset < 0) 574 return maperror(EINVAL); 575 file->offset = offset; 576 break; 577 case SEEK_CUR: 578 file->offset += offset; 579 break; 580 case SEEK_END: 581 if (offset > 0) 582 return maperror(EINVAL); 583 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 584 NULL, &size, NULL, NULL, NULL,NULL, NULL)) && 585 !NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 586 NULL, &size, NULL, NULL, NULL))) 587 return os2cli_errno(cli); 588 file->offset = size + offset; 589 break; 590 default: 591 return maperror(EINVAL); 592 } 593 594 return 0; 595 } 596 597 /* 598 * try to do a QPATHINFO and if that fails then do a getatr 599 * this is needed because win95 sometimes refuses the qpathinfo 600 */ 662 601 int _System smbwrp_getattr(smbwrp_server *srv, cli_state * cli, smbwrp_fileinfo *finfo) 663 602 { 664 SMB_INO_T ino = 0; 665 struct timespec ctime; 666 struct timespec mtime; 667 struct timespec atime; 668 669 if (!cli || !finfo || !*finfo->fname) 670 { 671 return maperror(EINVAL); 672 } 673 debuglocal(4,"getattr %d %d <%s>\n", cli->capabilities & CAP_NOPATHINFO2, cli->capabilities & CAP_NT_SMBS, finfo->fname); 674 if (!(cli->capabilities & CAP_NOPATHINFO2) && 675 NT_STATUS_IS_OK(cli_qpathinfo2(cli, finfo->fname, &ctime, &atime, &mtime, NULL, 676 (off_t *)&finfo->size, (unsigned short *)&finfo->attr, &ino))) 677 { 678 finfo->attr &= 0x7F; 679 finfo->ctime = convert_timespec_to_time_t(ctime); 680 finfo->atime = convert_timespec_to_time_t(atime); 681 finfo->mtime = convert_timespec_to_time_t(mtime); 682 return 0; 683 } 684 685 if (cli->fd == -1) 686 { 687 /* fd == -1 means the connection is broken */ 688 return maperror(ENOTCONN); 689 } 690 691 /* If the path is not on a share (it is a workgroup or a server), 692 * then cli_qpathinfo2 obviously fails. Return some fake information 693 * about the directory. 694 */ 695 if ( *srv->server_name == 0 696 || (strcmp(cli->dev,"IPC") == 0) 697 || *srv->share_name == 0 698 || (stricmp(srv->share_name,"IPC$") == 0) 699 || (strncmp(cli->dev,"LPT",3) == 0) 700 ) 701 { 702 debuglocal(4,"getattr not a share.\n"); 703 *(time_t *)&finfo->ctime = time (NULL); 704 *(time_t *)&finfo->atime = time (NULL); 705 *(time_t *)&finfo->mtime = time (NULL); 706 finfo->size = 0; 707 finfo->easize = 0; 708 finfo->attr = aDIR; 709 return 0; 710 } 603 SMB_INO_T ino = 0; 604 struct timespec ctime; 605 struct timespec mtime; 606 struct timespec atime; 607 608 if (!cli || !finfo || !*finfo->fname) 609 return maperror(EINVAL); 610 611 debuglocal(4,"getattr %d %d <%s>\n", cli->capabilities & CAP_NOPATHINFO2, cli->capabilities & CAP_NT_SMBS, finfo->fname); 612 if (!(cli->capabilities & CAP_NOPATHINFO2) && 613 NT_STATUS_IS_OK(cli_qpathinfo2(cli, finfo->fname, &ctime, &atime, 614 &mtime, NULL, (off_t *)&finfo->size, (unsigned short *)&finfo->attr, 615 &ino))) 616 { 617 finfo->attr &= 0x7F; 618 finfo->ctime = convert_timespec_to_time_t(ctime); 619 finfo->atime = convert_timespec_to_time_t(atime); 620 finfo->mtime = convert_timespec_to_time_t(mtime); 621 return 0; 622 } 623 624 // fd == -1 means the connection is broken */ 625 if (cli->fd == -1) 626 return maperror(ENOTCONN); 627 628 /* If the path is not on a share (it is a workgroup or a server), 629 * then cli_qpathinfo2 obviously fails. Return some fake information 630 * about the directory. 631 */ 632 if (*srv->server_name == 0 633 || (strcmp(cli->dev,"IPC") == 0) 634 || *srv->share_name == 0 635 || (stricmp(srv->share_name,"IPC$") == 0) 636 || (strncmp(cli->dev,"LPT",3) == 0)) 637 { 638 debuglocal(4,"getattr not a share.\n"); 639 *(time_t *)&finfo->ctime = time (NULL); 640 *(time_t *)&finfo->atime = time (NULL); 641 *(time_t *)&finfo->mtime = time (NULL); 642 finfo->size = 0; 643 finfo->easize = 0; 644 finfo->attr = aDIR; 645 return 0; 646 } 711 647 712 /* if this is NT then don't bother with the getatr */ 713 if (cli->capabilities & CAP_NT_SMBS && !(cli->capabilities & CAP_NOPATHINFO2)) 714 { 715 int ret = cli_errno(cli); 716 // cli_qpathinfo* reports EINVAL when path of given file not exists 717 // thus there is no real situation when EINVAL should be returned to 718 // client at this point, we just replace it to ENOTDIR 719 if (ret == EINVAL) 720 { 721 ret = ENOTDIR; 722 } 723 return maperror(ret); 724 } 725 726 if (NT_STATUS_IS_OK(cli_getatr(cli, finfo->fname, (unsigned short *)&finfo->attr, &finfo->size, (time_t *)&finfo->mtime))) 727 { 728 //debuglocal(2,("gotattr1 %08x <%s>\n", finfo->attr, finfo->fname)); 729 finfo->mtime -= get_time_zone(finfo->mtime); 730 finfo->atime = finfo->atime; //was mtime 731 finfo->ctime = finfo->ctime; //was mtime 732 cli->capabilities &= CAP_NOPATHINFO2; 733 return 0; 734 } 735 return os2cli_errno(cli); 736 } 737 738 /***************************************************** 739 try to do a QPATHINFO and if that fails then do a getatr 740 this is needed because win95 sometimes refuses the qpathinfo 741 *******************************************************/ 648 // if this is NT then don't bother with the getatr */ 649 if (cli->capabilities & CAP_NT_SMBS && !(cli->capabilities & CAP_NOPATHINFO2)) 650 { 651 int ret = cli_errno(cli); 652 /* 653 * cli_qpathinfo* reports EINVAL when path of given file not exists 654 * thus there is no real situation when EINVAL should be returned to 655 * client at this point, we just replace it to ENOTDIR 656 */ 657 if (ret == EINVAL) 658 ret = ENOTDIR; 659 660 return maperror(ret); 661 } 662 663 if (NT_STATUS_IS_OK(cli_getatr(cli, finfo->fname, (unsigned short *)&finfo->attr, &finfo->size, (time_t *)&finfo->mtime))) 664 { 665 //debuglocal(2,("gotattr1 %08x <%s>\n", finfo->attr, finfo->fname)); 666 finfo->mtime -= get_time_zone(finfo->mtime); 667 finfo->atime = finfo->atime; //was mtime 668 finfo->ctime = finfo->ctime; //was mtime 669 cli->capabilities &= CAP_NOPATHINFO2; 670 return 0; 671 } 672 673 return os2cli_errno(cli); 674 } 675 676 /* 677 * try to do a QPATHINFO and if that fails then do a getatr 678 * this is needed because win95 sometimes refuses the qpathinfo 679 */ 742 680 int _System smbwrp_fgetattr(cli_state * cli, smbwrp_file *file, smbwrp_fileinfo *finfo) 743 681 { 744 struct timespec ctime; 745 struct timespec mtime; 746 struct timespec atime; 747 SMB_INO_T ino = 0; 748 749 if (!cli || !file || !finfo) 750 { 751 return maperror(EINVAL); 752 } 753 754 strncpy(finfo->fname, file->fname, sizeof(finfo->fname) - 1); 755 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 756 (unsigned short *)&finfo->attr, (off_t *)&finfo->size, &ctime, &atime, &mtime, NULL, 757 &ino))) 758 { 759 if (!NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 760 (unsigned short *)&finfo->attr, (&finfo->size), (time_t *)&finfo->ctime, (time_t *)&finfo->atime, (time_t *)&finfo->mtime))) 761 { 762 return os2cli_errno(cli); 763 } 764 else 765 { 766 finfo->ctime -= get_time_zone(finfo->ctime); 767 finfo->atime -= get_time_zone(finfo->atime); 768 finfo->mtime -= get_time_zone(finfo->mtime); 769 } 770 } 771 else 772 { 773 finfo->ctime = convert_timespec_to_time_t(ctime); 774 finfo->atime = convert_timespec_to_time_t(atime); 775 finfo->mtime = convert_timespec_to_time_t(mtime); 776 } 777 778 return 0; 682 struct timespec ctime; 683 struct timespec mtime; 684 struct timespec atime; 685 SMB_INO_T ino = 0; 686 687 if (!cli || !file || !finfo) 688 return maperror(EINVAL); 689 690 691 strncpy(finfo->fname, file->fname, sizeof(finfo->fname) - 1); 692 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 693 (unsigned short *)&finfo->attr, (off_t *)&finfo->size, &ctime, 694 &atime, &mtime, NULL, &ino))) 695 { 696 if (!NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 697 (unsigned short *)&finfo->attr, (&finfo->size), 698 (time_t *)&finfo->ctime, (time_t *)&finfo->atime, 699 (time_t *)&finfo->mtime))) 700 return os2cli_errno(cli); 701 else 702 { 703 finfo->ctime -= get_time_zone(finfo->ctime); 704 finfo->atime -= get_time_zone(finfo->atime); 705 finfo->mtime -= get_time_zone(finfo->mtime); 706 } 707 } 708 else 709 { 710 finfo->ctime = convert_timespec_to_time_t(ctime); 711 finfo->atime = convert_timespec_to_time_t(atime); 712 finfo->mtime = convert_timespec_to_time_t(mtime); 713 } 714 715 return 0; 779 716 } 780 717 781 718 // =============================DIRECTORY ROUTINES============================ 782 719 783 /* ****************************************************784 add a entry to a directory listing785 *******************************************************/720 /* 721 * add a entry to a directory listing 722 */ 786 723 static void smbwrp_dir_add(const char* mnt, smbwrp_fileinfo *finfo, const char *mask, void *state) 787 724 { 788 if (state && finfo) 789 { 790 filelist_state * st = (filelist_state *)state; 791 char fullname[ _MAX_PATH] = {0}; 792 debuglocal(8,"adding <%s> %d %d %d\n", finfo->fname, sizeof(st->finfo), st->datalen, sizeof(st->finfo.fname)); 793 memcpy(&st->finfo, finfo, sizeof(st->finfo)); 794 strncpy(fullname, st->dir, strlen(st->dir)); 795 strncat(fullname, finfo->fname, sizeof(fullname) - strlen(fullname) -1); 796 strncpy(st->finfo.fname, fullname, sizeof(st->finfo.fname)); 797 getfindinfoL( st->pConn, st->plist, &st->finfo, st->ulAttribute, st->dir_mask); 798 } 725 if (state && finfo) 726 { 727 filelist_state * st = (filelist_state *)state; 728 char fullname[ _MAX_PATH] = {0}; 729 debuglocal(8,"adding <%s> %d %d %d\n", finfo->fname, sizeof(st->finfo), st->datalen, sizeof(st->finfo.fname)); 730 memcpy(&st->finfo, finfo, sizeof(st->finfo)); 731 strncpy(fullname, st->dir, strlen(st->dir)); 732 strncat(fullname, finfo->fname, sizeof(fullname) - strlen(fullname) -1); 733 strncpy(st->finfo.fname, fullname, sizeof(st->finfo.fname)); 734 getfindinfoL( st->pConn, st->plist, &st->finfo, st->ulAttribute, st->dir_mask); 735 } 736 return; 799 737 } 800 738 801 739 static void smbwrp_special_add(const char * name, void * state) 802 740 { 803 smbwrp_fileinfo finfo = {0}; 804 805 if (!name) 806 { 807 return; 808 } 809 810 ZERO_STRUCT(finfo); 811 812 strncpy(finfo.fname, name, sizeof(finfo.fname) - 1); 813 finfo.attr = aRONLY | aDIR; 814 815 smbwrp_dir_add("", &finfo, NULL, state); 741 smbwrp_fileinfo finfo = {0}; 742 743 if (!name) 744 return; 745 746 ZERO_STRUCT(finfo); 747 748 strncpy(finfo.fname, name, sizeof(finfo.fname) - 1); 749 finfo.attr = aRONLY | aDIR; 750 751 smbwrp_dir_add("", &finfo, NULL, state); 752 return; 816 753 } 817 754 818 755 static void smbwrp_printjob_add(struct print_job_info *job, void * state) 819 756 { 820 smbwrp_fileinfo finfo = {0}; 821 822 ZERO_STRUCT(finfo); 823 824 //printf("Printjob <%s>\n", job->name); 825 826 strncpy(finfo.fname, job->name, sizeof(finfo.fname) - 1); 827 finfo.mtime = job->t - get_time_zone(job->t); 828 finfo.atime = finfo.atime; //was mtime 829 finfo.ctime = finfo.ctime; //was mtime 830 finfo.attr = aRONLY; 831 finfo.size = job->size; 832 833 smbwrp_dir_add("", &finfo, NULL, state); 757 smbwrp_fileinfo finfo = {0}; 758 759 ZERO_STRUCT(finfo); 760 761 //printf("Printjob <%s>\n", job->name); 762 763 strncpy(finfo.fname, job->name, sizeof(finfo.fname) - 1); 764 finfo.mtime = job->t - get_time_zone(job->t); 765 finfo.atime = finfo.atime; //was mtime 766 finfo.ctime = finfo.ctime; //was mtime 767 finfo.attr = aRONLY; 768 finfo.size = job->size; 769 770 smbwrp_dir_add("", &finfo, NULL, state); 771 return; 834 772 } 835 773 … … 837 775 const char *comment, void *state) 838 776 { 839 smbwrp_fileinfo finfo = {0}; 840 841 // strip administrative names and printers from list 842 if (type == STYPE_PRINTQ || strcmp(share,"IPC$") == 0) return; 843 844 ZERO_STRUCT(finfo); 845 846 strncpy(finfo.fname, share, sizeof(finfo.fname) - 1); 847 finfo.attr = aRONLY | aDIR; 848 849 smbwrp_dir_add("", &finfo, NULL, state); 850 } 851 852 /**************************************************************************** 853 Do a directory listing, calling fn on each file found. 854 Modified from cli_list 855 ****************************************************************************/ 777 smbwrp_fileinfo finfo = {0}; 778 779 // strip administrative names and printers from list 780 if (type == STYPE_PRINTQ || strcmp(share,"IPC$") == 0) 781 return; 782 783 ZERO_STRUCT(finfo); 784 785 strncpy(finfo.fname, share, sizeof(finfo.fname) - 1); 786 finfo.attr = aRONLY | aDIR; 787 788 smbwrp_dir_add("", &finfo, NULL, state); 789 return; 790 } 791 792 /* 793 * Do a directory listing, calling fn on each file found. 794 * Modified from cli_list 795 */ 856 796 static int list_files(struct cli_state *cli, const char *mask, uint16 attribute, 857 797 void (*fn)(const char *, smbwrp_fileinfo *, const char *, 858 798 void *), void *state) 859 799 { 860 TALLOC_CTX *frame = talloc_stackframe(); 861 struct event_context *ev; 862 struct tevent_req *req; 863 NTSTATUS status = NT_STATUS_NO_MEMORY; 864 struct file_info *finfo; 865 size_t i, num_finfo; 866 uint16_t info_level; 867 void *dircachectx = NULL; 868 smbwrp_fileinfo wrpfinfo; 869 870 /* Try to get the listing from cache. */ 871 if (dircache_list_files(fn, state, &num_finfo)) 872 { 873 /* Got from cache. */ 874 return(num_finfo); 875 } 876 877 if (cli_has_async_calls(cli)) { 878 /* 879 * Can't use sync call while an async call is in flight 880 */ 881 status = NT_STATUS_INVALID_PARAMETER; 882 goto fail; 883 } 884 ev = event_context_init(frame); 885 if (ev == NULL) { 886 goto fail; 887 } 888 889 info_level = (cli->capabilities & CAP_NT_SMBS) 890 ? SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_EA_SIZE; 891 892 debuglocal(4,"list_files level %d. mask <%s>\n", info_level, mask); 893 894 req = cli_list_send(frame, ev, cli, mask, attribute, info_level); 895 if (req == NULL) { 896 goto fail; 897 } 898 if (!tevent_req_poll(req, ev)) { 899 status = map_nt_error_from_unix(errno); 900 goto fail; 901 } 902 903 status = cli_list_recv(req, frame, &finfo, &num_finfo); 904 if (!NT_STATUS_IS_OK(status)) { 905 goto fail; 906 } 907 908 dircachectx = dircache_write_begin(state, num_finfo); 909 910 debuglocal(4,"list_files: got %d files\n", num_finfo); 911 912 913 for (i=0; i<num_finfo; i++) { 914 //as samba and this client have different finfo, we need to convert 915 memset(&wrpfinfo, 0, sizeof(wrpfinfo)); 916 wrpfinfo.size = finfo[i].size; 917 wrpfinfo.attr = finfo[i].mode; 918 wrpfinfo.ctime = convert_timespec_to_time_t(finfo[i].ctime_ts); 919 wrpfinfo.mtime = convert_timespec_to_time_t(finfo[i].mtime_ts); 920 wrpfinfo.atime = convert_timespec_to_time_t(finfo[i].atime_ts); 921 wrpfinfo.easize = finfo[i].easize; 922 strncpy(wrpfinfo.fname, finfo[i].name, sizeof(wrpfinfo.fname) -1); 923 924 fn(cli->dfs_mountpoint, &wrpfinfo, mask, state); 925 // Also add the entry to the cache. 926 dircache_write_entry(dircachectx, &wrpfinfo); 927 } 928 929 dircache_write_end(dircachectx); 800 TALLOC_CTX *frame = talloc_stackframe(); 801 struct event_context *ev; 802 struct tevent_req *req; 803 NTSTATUS status = NT_STATUS_NO_MEMORY; 804 struct file_info *finfo; 805 size_t i, num_finfo; 806 uint16_t info_level; 807 void *dircachectx = NULL; 808 smbwrp_fileinfo wrpfinfo; 809 810 // Try to get the listing from cache. 811 if (dircache_list_files(fn, state, &num_finfo)) 812 return(num_finfo); // Got from cache 813 814 if (cli_has_async_calls(cli)) { 815 /* 816 * Can't use sync call while an async call is in flight 817 */ 818 status = NT_STATUS_INVALID_PARAMETER; 819 goto fail; 820 } 821 ev = event_context_init(frame); 822 if (ev == NULL) 823 goto fail; 824 825 info_level = (cli->capabilities & CAP_NT_SMBS) 826 ? SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_EA_SIZE; 827 828 debuglocal(4,"list_files level %d. mask <%s>\n", info_level, mask); 829 830 req = cli_list_send(frame, ev, cli, mask, attribute, info_level); 831 if (req == NULL) 832 goto fail; 833 834 if (!tevent_req_poll(req, ev)) { 835 status = map_nt_error_from_unix(errno); 836 goto fail; 837 } 838 839 status = cli_list_recv(req, frame, &finfo, &num_finfo); 840 if (!NT_STATUS_IS_OK(status)) 841 goto fail; 842 843 dircachectx = dircache_write_begin(state, num_finfo); 844 845 debuglocal(4,"list_files: got %d files\n", num_finfo); 846 847 for (i=0; i<num_finfo; i++) { 848 //as samba and this client have different finfo, we need to convert 849 memset(&wrpfinfo, 0, sizeof(wrpfinfo)); 850 wrpfinfo.size = finfo[i].size; 851 wrpfinfo.attr = finfo[i].mode; 852 wrpfinfo.ctime = convert_timespec_to_time_t(finfo[i].ctime_ts); 853 wrpfinfo.mtime = convert_timespec_to_time_t(finfo[i].mtime_ts); 854 wrpfinfo.atime = convert_timespec_to_time_t(finfo[i].atime_ts); 855 wrpfinfo.easize = finfo[i].easize; 856 strncpy(wrpfinfo.fname, finfo[i].name, sizeof(wrpfinfo.fname) -1); 857 fn(cli->dfs_mountpoint, &wrpfinfo, mask, state); 858 // Also add the entry to the cache. 859 dircache_write_entry(dircachectx, &wrpfinfo); 860 } 861 862 dircache_write_end(dircachectx); 930 863 fail: 931 TALLOC_FREE(frame);932 return num_finfo;933 } 934 935 /* ****************************************************936 open a directory on the server937 *******************************************************/864 TALLOC_FREE(frame); 865 return num_finfo; 866 } 867 868 /* 869 * open a directory on the server 870 */ 938 871 int _System smbwrp_filelist(smbwrp_server *srv, cli_state * cli, filelist_state * state) 939 872 { 940 if (!srv || !cli || !state || !*state->mask) 941 { 942 return maperror(EINVAL); 943 } 944 debuglocal(1,"Filelist <%s> on master <%s> wgrp <%s> server <%s> share <%s> clidev <%s>\n", state->mask, srv->master, srv->workgroup, srv->server_name, srv->share_name, cli->dev); 945 if (*srv->workgroup == 0 && *srv->server_name == 0) 946 { 947 smbwrp_special_add(".", state); 948 smbwrp_special_add("..", state); 949 cli_NetServerEnum(cli, srv->master, SV_TYPE_DOMAIN_ENUM, 950 smbwrp_share_add, state); 951 } else 952 if (*srv->server_name == 0) 953 { 954 smbwrp_special_add(".", state); 955 smbwrp_special_add("..", state); 956 957 cli_NetServerEnum(cli, srv->workgroup, SV_TYPE_ALL, 958 smbwrp_share_add, state); 959 } else 960 if ((strcmp(cli->dev,"IPC") == 0) || *srv->share_name == 0 || (stricmp(srv->share_name,"IPC$") == 0)) 961 { 962 smbwrp_special_add(".", state); 963 smbwrp_special_add("..", state); 964 965 if (net_share_enum_rpc(cli, smbwrp_share_add, state) < 0 && 966 cli_RNetShareEnum(cli,smbwrp_share_add, state) < 0) 967 { 968 return os2cli_errno(cli); 969 } 970 } else 971 if (strncmp(cli->dev,"LPT",3) == 0) 972 { 973 smbwrp_special_add(".", state); 974 smbwrp_special_add("..", state); 975 if (cli_print_queue_state(cli, smbwrp_printjob_add, state) < 0) 976 { 977 return os2cli_errno(cli); 978 } 979 } 980 else 981 { 982 if (list_files(cli, state->mask, aHIDDEN|aSYSTEM|aDIR, 983 smbwrp_dir_add, state) < 0) 984 { 985 return os2cli_errno(cli); 986 } 987 } 988 989 return 0; 990 } 991 992 /***************************************************** 993 a wrapper for chdir() 994 *******************************************************/ 873 if (!srv || !cli || !state || !*state->mask) 874 return maperror(EINVAL); 875 876 debuglocal(1,"Filelist <%s> on master <%s> wgrp <%s> server <%s> share <%s> clidev <%s>\n", state->mask, srv->master, srv->workgroup, srv->server_name, srv->share_name, cli->dev); 877 if (*srv->workgroup == 0 && *srv->server_name == 0) 878 { 879 smbwrp_special_add(".", state); 880 smbwrp_special_add("..", state); 881 cli_NetServerEnum(cli, srv->master, SV_TYPE_DOMAIN_ENUM, 882 smbwrp_share_add, state); 883 } else if (*srv->server_name == 0) 884 { 885 smbwrp_special_add(".", state); 886 smbwrp_special_add("..", state); 887 cli_NetServerEnum(cli, srv->workgroup, SV_TYPE_ALL, 888 smbwrp_share_add, state); 889 } else if ((strcmp(cli->dev,"IPC") == 0) || *srv->share_name == 0 || 890 (stricmp(srv->share_name,"IPC$") == 0)) 891 { 892 smbwrp_special_add(".", state); 893 smbwrp_special_add("..", state); 894 if (net_share_enum_rpc(cli, smbwrp_share_add, state) < 0 && 895 cli_RNetShareEnum(cli,smbwrp_share_add, state) < 0) 896 return os2cli_errno(cli); 897 } else if (strncmp(cli->dev,"LPT",3) == 0) 898 { 899 smbwrp_special_add(".", state); 900 smbwrp_special_add("..", state); 901 if (cli_print_queue_state(cli, smbwrp_printjob_add, state) < 0) 902 return os2cli_errno(cli); 903 } 904 else 905 { 906 if (list_files(cli, state->mask, aHIDDEN|aSYSTEM|aDIR, 907 smbwrp_dir_add, state) < 0) 908 return os2cli_errno(cli); 909 } 910 911 return 0; 912 } 913 914 /* 915 * a wrapper for chdir() 916 */ 995 917 int _System smbwrp_chdir(smbwrp_server *srv, cli_state * cli, char *fname) 996 918 { 997 unsigned short mode = aDIR; 998 smbwrp_fileinfo finfo = {0}; 999 if (!cli || !fname) 1000 { 1001 return maperror(EINVAL); 1002 } 1003 1004 strncpy(finfo.fname, fname, sizeof(finfo.fname) - 1); 1005 if (smbwrp_getattr(srv, cli, &finfo)) 1006 { 1007 return os2cli_errno(cli); 1008 } 1009 1010 if (!(finfo.attr & aDIR)) { 1011 return maperror(ENOTDIR); 1012 } 1013 1014 return 0; 1015 } 1016 1017 1018 /***************************************************** 1019 a wrapper for mkdir() 1020 *******************************************************/ 919 unsigned short mode = aDIR; 920 smbwrp_fileinfo finfo = {0}; 921 if (!cli || !fname) 922 return maperror(EINVAL); 923 924 strncpy(finfo.fname, fname, sizeof(finfo.fname) - 1); 925 if (smbwrp_getattr(srv, cli, &finfo)) 926 return os2cli_errno(cli); 927 928 929 if (!(finfo.attr & aDIR)) 930 return maperror(ENOTDIR); 931 932 933 return 0; 934 } 935 936 937 /* 938 * a wrapper for mkdir() 939 */ 1021 940 int _System smbwrp_mkdir(cli_state * cli, char *fname) 1022 941 { 1023 if (!cli || !fname) 1024 { 1025 return maperror(EINVAL); 1026 } 1027 1028 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) 1029 { 1030 return os2cli_errno(cli); 1031 } 1032 return 0; 1033 } 1034 1035 /***************************************************** 1036 a wrapper for rmdir() 1037 *******************************************************/ 942 if (!cli || !fname) 943 return maperror(EINVAL); 944 945 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) 946 return os2cli_errno(cli); 947 948 return 0; 949 } 950 951 /* 952 * a wrapper for rmdir() 953 */ 1038 954 int _System smbwrp_rmdir(cli_state * cli, char *fname) 1039 955 { 1040 if (!cli || !fname) 1041 { 1042 return maperror(EINVAL); 1043 } 1044 1045 if (!NT_STATUS_IS_OK(cli_rmdir(cli, fname))) 1046 { 1047 return os2cli_errno(cli); 1048 } 1049 return 0; 1050 } 1051 1052 /***************************************************** 1053 set EA for a path 1054 *******************************************************/ 956 if (!cli || !fname) 957 return maperror(EINVAL); 958 959 if (!NT_STATUS_IS_OK(cli_rmdir(cli, fname))) 960 return os2cli_errno(cli); 961 962 return 0; 963 } 964 965 /* 966 * set EA for a path 967 */ 1055 968 int _System smbwrp_setea(cli_state * cli, char *fname, char * name, unsigned char * value, int size) 1056 969 { 1057 if (!cli || !fname || !name) 1058 { 1059 return maperror(EINVAL); 1060 } 1061 if (!NT_STATUS_IS_OK(cli_set_ea_path(cli, fname, name, value, size))) 1062 { 1063 return os2cli_errno(cli); 1064 } 1065 return 0; 1066 } 1067 1068 /***************************************************** 1069 set EA for a file 1070 *******************************************************/ 970 if (!cli || !fname || !name) 971 return maperror(EINVAL); 972 973 if (!NT_STATUS_IS_OK(cli_set_ea_path(cli, fname, name, value, size))) 974 return os2cli_errno(cli); 975 976 return 0; 977 } 978 979 /* 980 * set EA for a file 981 */ 1071 982 int _System smbwrp_fsetea(cli_state * cli, smbwrp_file *file, char * name, unsigned char * value, int size) 1072 983 { 1073 if (!cli || !file || !name) 1074 { 1075 return maperror(EINVAL); 1076 } 1077 if (!NT_STATUS_IS_OK(cli_set_ea_fnum(cli, file->fd, name, value, size))) 1078 { 1079 return os2cli_errno(cli); 1080 } 1081 return 0; 984 if (!cli || !file || !name) 985 return maperror(EINVAL); 986 987 if (!NT_STATUS_IS_OK(cli_set_ea_fnum(cli, file->fd, name, value, size))) 988 return os2cli_errno(cli); 989 990 return 0; 1082 991 } 1083 992 1084 993 1085 994 #pragma pack(1) 1086 typedef struct _FEA /* fea */1087 { 1088 unsigned char fEA; /* flags */ 1089 unsigned char cbName; /* name length not including NULL */ 1090 unsigned short cbValue; /* value length */ 995 typedef struct _FEA 996 { 997 unsigned char fEA; // flags 998 unsigned char cbName; // name length not including NULL 999 unsigned short cbValue; // value length 1091 1000 } FEA; 1092 1001 1093 typedef struct _FEALIST /* feal */1094 { 1095 unsigned long cbList; /* total bytes of structure including full list */ 1096 FEA list[1]; /* variable length FEA structures */ 1002 typedef struct _FEALIST 1003 { 1004 unsigned long cbList; // total bytes of structure including full list 1005 FEA list[1]; // variable length FEA structures 1097 1006 } FEALIST; 1098 1007 #pragma pack() … … 1100 1009 static int unilistea(cli_state * cli, char *fname, void * buffer, unsigned long size) 1101 1010 { 1102 int fnum, i;1103 int gotsize = sizeof(unsigned long);1104 size_t num_eas;1105 struct ea_struct *ea_list = NULL;1106 TALLOC_CTX *mem_ctx;1107 FEA * p;1108 FEALIST * pfealist;1109 char * q;1110 1111 mem_ctx = talloc_init("%d: ealist", _gettid());1112 pfealist = (FEALIST *)buffer;1113 pfealist->cbList = 0;1114 1115 if (!NT_STATUS_IS_OK(cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)))1116 {1117 debuglocal(4,"ea_get_file list failed - %s\n", cli_errstr(cli));1118 talloc_destroy(mem_ctx);1119 return os2cli_errno(cli);1120 }1121 1122 debuglocal(4,"num_eas = %d\n", num_eas);1123 1124 // we will count that os/2 max EA size for file is 64kb1125 p = pfealist->list;1126 for (i = 0; i < num_eas; i++)1127 {1128 int namelen = strlen(ea_list[i].name);1129 debuglocal(4, "%d Got EA <%s> with namelen %d, size %d. Gross %d. Buf %d\n", i, ea_list[i].name, namelen, ea_list[i].value.length, gotsize, size);1130 if (namelen > 0xFF || ea_list[i].value.length > 0xFFFF)1131 {1132 debuglocal(4, "Skip EA <%s> with namelen %d, size %d\n", ea_list[i].name, namelen, ea_list[i].value.length);1133 continue;1134 }1135 gotsize += sizeof(FEA) + namelen + ea_list[i].value.length + 1;1136 if (size >= gotsize)1137 {1138 p->fEA = 0;1139 p->cbName = namelen;1140 p->cbValue = ea_list[i].value.length;1141 q = (char *)(p + 1);1142 strncpy(q, ea_list[i].name, namelen + 1);1143 q += namelen + 1;1144 memcpy(q, ea_list[i].value.data, ea_list[i].value.length);1145 p = (FEA *)(q + ea_list[i].value.length);1146 }1147 }1148 pfealist->cbList = gotsize;1149 debuglocal(4,"ret size = %d\n", gotsize);1150 1151 talloc_destroy(mem_ctx);1152 return 0;1153 } 1154 1155 /* ****************************************************1156 lists EA of a path1157 *******************************************************/1011 int fnum, i; 1012 int gotsize = sizeof(unsigned long); 1013 size_t num_eas; 1014 struct ea_struct *ea_list = NULL; 1015 TALLOC_CTX *mem_ctx; 1016 FEA * p; 1017 FEALIST * pfealist; 1018 char * q; 1019 1020 mem_ctx = talloc_init("%d: ealist", _gettid()); 1021 pfealist = (FEALIST *)buffer; 1022 pfealist->cbList = 0; 1023 1024 if (!NT_STATUS_IS_OK(cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list))) 1025 { 1026 debuglocal(4,"ea_get_file list failed - %s\n", cli_errstr(cli)); 1027 talloc_destroy(mem_ctx); 1028 return os2cli_errno(cli); 1029 } 1030 1031 debuglocal(4,"num_eas = %d\n", num_eas); 1032 1033 // we will count that os/2 max EA size for file is 64kb 1034 p = pfealist->list; 1035 for (i = 0; i < num_eas; i++) 1036 { 1037 int namelen = strlen(ea_list[i].name); 1038 debuglocal(4, "%d Got EA <%s> with namelen %d, size %d. Gross %d. Buf %d\n", i, ea_list[i].name, namelen, ea_list[i].value.length, gotsize, size); 1039 if (namelen > 0xFF || ea_list[i].value.length > 0xFFFF) 1040 { 1041 debuglocal(4, "Skip EA <%s> with namelen %d, size %d\n", ea_list[i].name, namelen, ea_list[i].value.length); 1042 continue; 1043 } 1044 gotsize += sizeof(FEA) + namelen + ea_list[i].value.length + 1; 1045 if (size >= gotsize) 1046 { 1047 p->fEA = 0; 1048 p->cbName = namelen; 1049 p->cbValue = ea_list[i].value.length; 1050 q = (char *)(p + 1); 1051 strncpy(q, ea_list[i].name, namelen + 1); 1052 q += namelen + 1; 1053 memcpy(q, ea_list[i].value.data, ea_list[i].value.length); 1054 p = (FEA *)(q + ea_list[i].value.length); 1055 } 1056 } 1057 pfealist->cbList = gotsize; 1058 debuglocal(4,"ret size = %d\n", gotsize); 1059 1060 talloc_destroy(mem_ctx); 1061 return 0; 1062 } 1063 1064 /* 1065 * lists EA of a path 1066 */ 1158 1067 int _System smbwrp_listea(cli_state * cli, char *fname, void * buffer, unsigned long size) 1159 1068 { 1160 if (!cli || !fname || !buffer) 1161 { 1162 return maperror(EINVAL); 1163 } 1164 1165 debuglocal(4,"EALIst for <%s>\n", fname); 1166 return unilistea(cli, fname, buffer, size); 1167 } 1168 1169 /***************************************************** 1170 lists EA of a file 1171 *******************************************************/ 1069 if (!cli || !fname || !buffer) 1070 return maperror(EINVAL); 1071 1072 debuglocal(4,"EALIst for <%s>\n", fname); 1073 return unilistea(cli, fname, buffer, size); 1074 } 1075 1076 /* 1077 * lists EA of a file 1078 */ 1172 1079 int _System smbwrp_flistea(cli_state * cli, smbwrp_file *file, void * buffer, unsigned long size) 1173 1080 { 1174 if (!cli || !file || !buffer) 1175 { 1176 return maperror(EINVAL); 1177 } 1178 1179 debuglocal(4,"FEALIst for <%s>\n", file->fname); 1180 return unilistea(cli, file->fname, buffer, size); 1181 } 1182 1183 /**************************************************************************** 1184 Check the space on a device. 1185 ****************************************************************************/ 1081 if (!cli || !file || !buffer) 1082 return maperror(EINVAL); 1083 1084 debuglocal(4,"FEALIst for <%s>\n", file->fname); 1085 return unilistea(cli, file->fname, buffer, size); 1086 } 1087 1088 /* 1089 * Check the space on a device. 1090 */ 1186 1091 int _System smbwrp_dskattr(cli_state * cli, FSALLOCATE *pfsa) 1187 1092 { 1188 int total, bsize, avail; 1189 1190 if (!cli || !pfsa) 1191 { 1192 return maperror(EINVAL); 1193 } 1194 1195 if (!NT_STATUS_IS_OK(cli_dskattr(cli, &bsize, &total, &avail))) 1196 { 1197 debuglocal(4,"Error in dskattr: %s\n",cli_errstr(cli)); 1198 return os2cli_errno(cli); 1199 } 1200 1201 debuglocal(4,"\n\t\t%d blocks of size %d. %d blocks available\n", 1202 total, bsize, avail); 1203 1204 // YD currently Samba return it in MB! 1205 pfsa->cSectorUnit = 1; 1206 if (bsize >= 65536) 1207 { 1208 pfsa->cUnit = total*1024; 1209 pfsa->cUnitAvail = avail*1024; 1210 pfsa->cbSector = bsize/1024; 1211 } 1212 else 1213 { 1214 pfsa->cUnit = total; 1215 pfsa->cUnitAvail = avail; 1216 pfsa->cbSector = bsize; 1217 } 1218 1219 return 0; 1220 } 1221 1093 int total, bsize, avail; 1094 1095 if (!cli || !pfsa) 1096 return maperror(EINVAL); 1097 1098 if (!NT_STATUS_IS_OK(cli_dskattr(cli, &bsize, &total, &avail))) 1099 { 1100 debuglocal(4,"Error in dskattr: %s\n",cli_errstr(cli)); 1101 return os2cli_errno(cli); 1102 } 1103 1104 debuglocal(4,"\n\t\t%d blocks of size %d. %d blocks available\n", 1105 total, bsize, avail); 1106 1107 // YD currently Samba return it in MB! 1108 pfsa->cSectorUnit = 1; 1109 if (bsize >= 65536) 1110 { 1111 pfsa->cUnit = total*1024; 1112 pfsa->cUnitAvail = avail*1024; 1113 pfsa->cbSector = bsize/1024; 1114 } 1115 else 1116 { 1117 pfsa->cUnit = total; 1118 pfsa->cUnitAvail = avail; 1119 pfsa->cbSector = bsize; 1120 } 1121 1122 return 0; 1123 } -
trunk/client/src/smbwrp.h
r957 r959 74 74 typedef struct smbwrp_server 75 75 { 76 char server_name[256];77 char share_name[256];78 char workgroup[256];79 char username[256];80 char password[256];81 char master[256];82 int ifmastergroup;83 int no_pathinfo2;76 char server_name[256]; 77 char share_name[256]; 78 char workgroup[256]; 79 char username[256]; 80 char password[256]; 81 char master[256]; 82 int ifmastergroup; 83 int no_pathinfo2; 84 84 } smbwrp_server; 85 85 86 86 typedef struct smbwrp_file 87 87 { 88 int fd;89 unsigned long long offset;90 int openmode;91 int openattr;92 int denymode;93 unsigned long mtime;94 unsigned long ctime;95 int updatetime;96 // 0 = time is not updated upon file close97 // 1 = modified time is updated to current time98 // 2 = create and modified time are updated according local file99 char fullname[261];100 char fname[261];88 int fd; 89 unsigned long long offset; 90 int openmode; 91 int openattr; 92 int denymode; 93 unsigned long mtime; 94 unsigned long ctime; 95 int updatetime; 96 // 0 = time is not updated upon file close 97 // 1 = modified time is updated to current time 98 // 2 = create and modified time are updated according local file 99 char fullname[261]; 100 char fname[261]; 101 101 } smbwrp_file; 102 102 103 103 typedef struct smbwrp_fileinfo 104 104 { 105 unsigned long long size;106 unsigned long attr;107 unsigned long ctime;108 unsigned long mtime;109 unsigned long atime;110 int easize;111 char fname[261];105 unsigned long long size; 106 unsigned long attr; 107 unsigned long ctime; 108 unsigned long mtime; 109 unsigned long atime; 110 int easize; 111 char fname[261]; 112 112 } smbwrp_fileinfo; 113 113 114 114 typedef struct smbwrp_fileseek 115 115 { 116 int whence;117 long offset;118 unsigned long result;116 int whence; 117 long offset; 118 unsigned long result; 119 119 } smbwrp_fileseek; 120 120 … … 123 123 typedef struct _FSALLOCATE /* fsalloc */ 124 124 { 125 unsigned long idFileSystem;126 unsigned long cSectorUnit;127 unsigned long cUnit;128 unsigned long cUnitAvail;129 unsigned short cbSector;125 unsigned long idFileSystem; 126 unsigned long cSectorUnit; 127 unsigned long cUnit; 128 unsigned long cUnitAvail; 129 unsigned short cbSector; 130 130 } FSALLOCATE; 131 131 #endif … … 135 135 typedef struct _Resource 136 136 { 137 int rootlevel; 138 smbwrp_server srv; 139 char logfile[_MAX_PATH + 1]; 140 char loglevel; 141 int easupport; 142 int krb5support; 137 int rootlevel; 138 smbwrp_server srv; 139 int easupport; 140 int krb5support; 143 141 int cachetimeout; 144 142 int cachedepth; 145 struct DirectoryCache *pdc; 143 int loglevel; 144 struct DirectoryCache *pdc; 146 145 } Resource; 147 146 148 147 typedef struct _Connection 149 148 { 150 Resource *pRes;151 cli_state* cli;152 smbwrp_file file;149 Resource *pRes; 150 cli_state* cli; 151 smbwrp_file file; 153 152 } Connection; 154 153 … … 156 155 typedef struct filelist_state 157 156 { 158 unsigned long pipe;159 char * data;160 int datalen;161 int bufferlen;162 void ( * _System add_dir_entry)(void * st);163 char mask[ _MAX_PATH];164 char dir[ _MAX_PATH];165 char dir_mask[ _MAX_PATH];166 smbwrp_fileinfo finfo;167 Connection* pConn;168 void *plist;169 unsigned long ulAttribute;170 const char *fullpath;157 unsigned long pipe; 158 char * data; 159 int datalen; 160 int bufferlen; 161 void ( * _System add_dir_entry)(void * st); 162 char mask[ _MAX_PATH]; 163 char dir[ _MAX_PATH]; 164 char dir_mask[ _MAX_PATH]; 165 smbwrp_fileinfo finfo; 166 Connection* pConn; 167 void *plist; 168 unsigned long ulAttribute; 169 const char *fullpath; 171 170 } filelist_state; 172 171 -
trunk/client/src/util.c
r957 r959 26 26 #include <stdlib.h> 27 27 #include <string.h> 28 #include <stdio.h> 28 29 29 30 #include "smbwrp.h" … … 32 33 int maperror(int rc) 33 34 { 34 switch (rc) 35 { 36 case 0 : return NO_ERROR ; /* NO_ERROR */ 37 case 1 : return ERROR_ACCESS_DENIED ; /* EPERM - Operation not permitted */ 38 case 2 : return ERROR_FILE_NOT_FOUND ; /* ENOENT - No such file or directory */ 39 case 3 : return ERROR_PID_MISMATCH ; /* ESRCH - No such process */ 40 case 4 : return ERROR_INTERRUPT ; /* EINTR - Interrupted system call */ 41 case 5 : return ERROR_READ_FAULT ; /* EIO - I/O error */ 42 case 6 : return ERROR_BAD_UNIT ; /* ENXIO - No such device or address */ 43 case 7 : return ERROR_INVALID_DATA ; /* E2BIG - Arguments or environment too big */ 44 case 8 : return ERROR_BAD_EXE_FORMAT ; /* ENOEXEC - Invalid executable file format */ 45 case 9 : return ERROR_INVALID_HANDLE ; /* EBADF - Bad file number */ 46 case 10 : return ERROR_NO_CHILD_PROCESS ; /* ECHILD - No child processes */ 47 case 11 : return ERROR_BUSY ; /* EAGAIN - Resource temporarily unavailable */ 48 case 12 : return ERROR_NOT_ENOUGH_MEMORY ; /* ENOMEM - Not enough memory */ 49 case 13 : return ERROR_ACCESS_DENIED ; /* EACCES - Permission denied */ 50 case 14 : return ERROR_INVALID_ADDRESS ; /* EFAULT - Bad address */ 51 case 15 : return ERROR_NOT_LOCKED ; /* ENOLCK - No locks available */ 52 case 16 : return ERROR_BUSY ; /* EBUSY - Resource busy */ 53 case 17 : return ERROR_FILE_EXISTS ; /* EEXIST - File exists */ 54 case 18 : return ERROR_NOT_SAME_DEVICE ; /* EXDEV - Cross-device link */ 55 case 19 : return ERROR_REM_NOT_LIST ; /* ENODEV - No such device */ 56 case 20 : return ERROR_PATH_NOT_FOUND ; /* ENOTDIR - Not a directory */ 57 case 21 : return ERROR_DIRECTORY ; /* EISDIR - Is a directory */ 58 case 22 : return ERROR_INVALID_PARAMETER ; /* EINVAL - Invalid argument */ 59 case 23 : return ERROR_TOO_MANY_OPEN_FILES ; /* ENFILE - Too many open files in system */ 60 case 24 : return ERROR_TOO_MANY_OPENS ; /* EMFILE - Too many open files */ 61 case 25 : return ERROR_MOD_NOT_FOUND ; /* ENOTTY - Inappropriate ioctl */ 62 case 26 : return ERROR_LOCK_VIOLATION ; /* EDEADLK - Resource deadlock avoided */ 63 case 27 : return ERROR_TRANSFER_TOO_LONG ; /* EFBIG - File too large */ 64 case 28 : return ERROR_DISK_FULL ; /* ENOSPC - Disk full */ 65 case 29 : return ERROR_SEEK ; /* ESPIPE - Invalid seek */ 66 case 30 : return ERROR_WRITE_PROTECT ; /* EROFS - Read-only file system */ 67 case 31 : return ERROR_TOO_MANY_OPEN_FILES ; /* EMLINK - Too many links */ 68 case 32 : return ERROR_BROKEN_PIPE ; /* EPIPE - Broken pipe */ 69 case 33 : return ERROR_INVALID_LEVEL ; /* EDOM - Domain error */ 70 case 34 : return ERROR_FILENAME_EXCED_RANGE ; /* ERANGE - Result too large */ 71 case 35 : return ERROR_DIR_NOT_EMPTY ; /* ENOTEMPTY - Directory not empty */ 72 case 36 : return ERROR_BUSY_DRIVE ; /* EINPROGRESS - Operation now in progress */ 73 case 37 : return ERROR_INVALID_FUNCTION ; /* ENOSYS - Function not implemented */ 74 case 38 : return ERROR_FILENAME_EXCED_RANGE ; /* ENAMETOOLONG - File name too long */ 75 case 39 : return ERROR_KBD_FOCUS_REQUIRED ; /* EDESTADDRREQ - Destination address required */ 76 case 40 : return ERROR_TRANSFER_TOO_LONG ; /* EMSGSIZE - Message too long */ 77 case 48 : return ERROR_NETWORK_BUSY ; /* EADDRINUSE - Address already in use */ 78 case 49 : return ERROR_INFO_NOT_AVAIL ; /* EADDRNOTAVAIL - Can't assigned requested address */ 79 case 50 : return ERROR_NETWORK_ACCESS_DENIED ; /* ENETDOWN - Network is down */ 80 case 51 : return ERROR_NETWORK_ACCESS_DENIED ; /* ENETUNREACH - Network is unreachable */ 81 case 52 : return ERROR_NETWORK_ACCESS_DENIED ; /* ENETRESET - Network dropped connection on reset */ 82 case 53 : return ERROR_NETWORK_ACCESS_DENIED ; /* ECONNABORTED - Software caused connection abort */ 83 case 54 : return ERROR_NETWORK_ACCESS_DENIED ; /* ECONNRESET - Connection reset by peer */ 84 case 55 : return ERROR_BUFFER_OVERFLOW ; /* ENOBUFS - No buffer space available */ 85 case 56 : return ERROR_PIPE_BUSY ; /* EISCONN - Socket is already connected */ 86 case 57 : return ERROR_REM_NOT_LIST ; /* ENOTCONN - Socket is not connected */ 87 case 58 : return ERROR_ALREADY_SHUTDOWN ; /* ESHUTDOWN - Can't send after socket shutdown */ 88 case 60 : return ERROR_TIMEOUT ; /* ETIMEDOUT - Connection timed out */ 89 case 61 : return ERROR_NETWORK_ACCESS_DENIED ; /* ECONNREFUSED - Connection refused */ 90 case 63 : return ERROR_INVALID_BLOCK ; /* ENOTSOCK - Socket operation on non-socket */ 91 case 64 : return ERROR_BAD_FORMAT ; /* EHOSTDOWN - Host is down */ 92 case 65 : return ERROR_BAD_NETPATH ; /* EHOSTUNREACH - No route to host */ 93 case 66 : return ERROR_BUSY_DRIVE ; /* EALREADY - Operation already in progress */ 94 } 35 switch (rc) 36 { 37 case 0 : // NO_ERROR 38 return NO_ERROR; 39 case 1 : // EPERM - Operation nt permitted 40 case 13 : // EACCES - Permission denied 41 return ERROR_ACCESS_DENIED; 42 case 2 : // ENOENT - No such file or directory 43 return ERROR_FILE_NOT_FOUND; 44 case 3 : // ESRCH - No such process 45 return ERROR_PID_MISMATCH; 46 case 4 : // EINTR - Interrupted system call 47 return ERROR_INTERRUPT; 48 case 5 : // EIO - I/O error 49 return ERROR_READ_FAULT; 50 case 6 : // ENXIO - No such device or address 51 return ERROR_BAD_UNIT; 52 case 7 : // E2BIG - Arguments or environment too big 53 return ERROR_INVALID_DATA; 54 case 8 : // ENOEXEC - Invalid executable file format 55 return ERROR_BAD_EXE_FORMAT; 56 case 9 : // EBADF - Bad file number 57 return ERROR_INVALID_HANDLE; 58 case 10 : // ECHILD - No child processes 59 return ERROR_NO_CHILD_PROCESS; 60 case 11 : // EAGAIN - Resource temporarily unavailable 61 case 16 : // EBUSY - Resource busy 62 return ERROR_BUSY; 63 case 12 : // ENOMEM - Not enough memory 64 return ERROR_NOT_ENOUGH_MEMORY; 65 case 14 : // EFAULT - Bad address 66 return ERROR_INVALID_ADDRESS; 67 case 15 : // ENOLCK - No locks available 68 return ERROR_NOT_LOCKED; 69 case 17 : // EEXIST - File exists 70 return ERROR_FILE_EXISTS; 71 case 18 : // EXDEV - Cross-device link 72 return ERROR_NOT_SAME_DEVICE; 73 case 19 : // ENODEV - No such device 74 case 57 : // ENOTCONN - Socket is not connected 75 return ERROR_REM_NOT_LIST; 76 case 20 : // ENOTDIR - Not a directory 77 return ERROR_PATH_NOT_FOUND; 78 case 21 : // EISDIR - Is a directory 79 return ERROR_DIRECTORY; 80 case 22 : // EINVAL - Invalid argument 81 return ERROR_INVALID_PARAMETER; 82 case 23 : // ENFILE - Too many open files in system 83 case 31 : // EMLINK - Too many links 84 return ERROR_TOO_MANY_OPEN_FILES; 85 case 24 : // EMFILE - Too many open files 86 return ERROR_TOO_MANY_OPENS; 87 case 25 : // ENOTTY - Inappropriate ioctl 88 return ERROR_MOD_NOT_FOUND; 89 case 26 : // EDEADLK - Resource deadlock avoided 90 return ERROR_LOCK_VIOLATION; 91 case 27 : // EFBIG - File too large 92 case 40 : // EMSGSIZE - Message too long 93 return ERROR_TRANSFER_TOO_LONG; 94 case 28 : // ENOSPC - Disk full 95 return ERROR_DISK_FULL; 96 case 29 : // ESPIPE - Invalid seek 97 return ERROR_SEEK; 98 case 30 : // EROFS - Read-only file system 99 return ERROR_WRITE_PROTECT; 100 case 32 : // EPIPE - Broken pipe 101 return ERROR_BROKEN_PIPE; 102 case 33 : // EDOM - Domain error 103 return ERROR_INVALID_LEVEL; 104 case 34 : // ENAMETOOLONG - File name too long 105 case 38 : // ERANGE - Result too large 106 return ERROR_FILENAME_EXCED_RANGE; 107 case 35 : // ENOTEMPTY - Directory not empty 108 return ERROR_DIR_NOT_EMPTY; 109 case 36 : // EINPROGRESS - Operation now in progress 110 case 66 : // EALREADY - Operation already in progress 111 return ERROR_BUSY_DRIVE; 112 case 37 : // ENOSYS - Function not implemented 113 return ERROR_INVALID_FUNCTION; 114 case 39 : // EDESTADDRREQ - Destination address required 115 return ERROR_KBD_FOCUS_REQUIRED; 116 case 48 : // EADDRINUSE - Address already in use 117 return ERROR_NETWORK_BUSY; 118 case 49 : // EADDRNOTAVAIL - Can't assigned requested address 119 return ERROR_INFO_NOT_AVAIL; 120 case 50 : // ENETDOWN - Network is down 121 case 51 : // ENETUNREACH - Network is unreachable 122 case 52 : // ENETRESET - Network dropped connection on reset 123 case 53 : // ECONNABORTED - Software caused connection abort 124 case 54 : // ECONNRESET - Connection reset by peer 125 return ERROR_NETWORK_ACCESS_DENIED; 126 case 55 : // ENOBUFS - No buffer space available 127 return ERROR_BUFFER_OVERFLOW; 128 case 56 : // EISCONN - Socket is already connected 129 return ERROR_PIPE_BUSY; 130 case 58 : // ESHUTDOWN - Can't send after socket shutdown 131 return ERROR_ALREADY_SHUTDOWN; 132 case 60 : // ETIMEDOUT - Connection timed out 133 return ERROR_TIMEOUT; 134 case 61 : // ECONNREFUSED - Connection refused 135 return ERROR_NETWORK_ACCESS_DENIED; 136 case 63 : // ENOTSOCK - Socket operation on non-socket 137 return ERROR_INVALID_BLOCK; 138 case 64 : // EHOSTDOWN - Host is down 139 return ERROR_BAD_FORMAT; 140 case 65 : // EHOSTUNREACH - No route to host 141 return ERROR_BAD_NETPATH; 142 } 95 143 // debug_printf( "Unhandled return code %d\n"); 96 return rc + 40000;144 return rc + 40000; 97 145 } 98 146 99 147 char * getlastslash(char * path) 100 148 { 101 char * p; 102 if (!path) 103 { 104 return NULL; 105 } 106 for (p = path + strlen(path) - 1; p >= path; p--) 107 { 108 if (*p == '\\' || *p == '/') 109 { 110 return p; 111 } 112 } 113 return NULL; 149 char * p; 150 if (!path) 151 return NULL; 152 153 for (p = path + strlen(path) - 1; p >= path; p--) 154 { 155 if (*p == '\\' || *p == '/') 156 return p; 157 } 158 return NULL; 114 159 } 115
Note:
See TracChangeset
for help on using the changeset viewer.
