Changeset 959


Ignore:
Timestamp:
Aug 16, 2016, 5:35:07 PM (9 years ago)
Author:
Silvan Scherrer
Message:

samba client: remove tabs in source and beautify it completely

Location:
trunk/client/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/client/src/debug.c

    r957 r959  
    4343int debuglvl(int level)
    4444{
    45         return (level <= debuglevel) ? 1 : 0;
     45        return (level <= debuglevel) ? 1 : 0;
    4646}
    4747
     
    7979        }
    8080        else
    81         {
    8281           strncat(logfile, logfilename, sizeof(logfile) -1);
    83         }
     82       
    8483        // set the samba logging stuff
    8584        do_logging = TRUE;
     
    8887        rc = DosCreateMutexSem(nameMutex, &logMutex, 0, FALSE);
    8988        if (rc == ERROR_DUPLICATE_NAME)
    90         {
    91         rc = DosOpenMutexSem(nameMutex, &logMutex);
    92         }
     89           rc = DosOpenMutexSem(nameMutex, &logMutex);
    9390
    9491        return;
     
    107104        // do we have to log at all
    108105        if (!do_logging)
    109         {
    110                 return;
    111         }
     106           return;
    112107
    113108        // if the sem is created we request it
    114109        if (logMutex)
    115         {
    116110           DosRequestMutexSem(logMutex, (ULONG) SEM_INDEFINITE_WAIT);
    117         }
    118111
    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;
    136124
    137                 // in the first log line we write our version of the client
    138                 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           }
    144132
    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);
    158143
    159144        // if the sem is created we release it
    160145        if (logMutex)
    161         {
    162146           DosReleaseMutexSem(logMutex);
    163         }
    164147
    165148        return;
  • trunk/client/src/ndpsmb.c

    r957 r959  
    3232#include "util.h"
    3333
    34 #define debug_printf(...) debuglocal(9, __VA_ARGS__)
    35 
    3634// -------------------------------------------------------------
    3735
     
    4341void fsphUnixTimeToDosDate( time_t time, FDATE* fdate, FTIME *ftime)
    4442{
    45         struct tm* gmt = localtime( &time);
     43        struct tm* gmt = localtime( &time);
    4644#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        }
    5251#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;
    5958}
    6059
    6160void fsphDosDateToUnixTime( FDATE fdate, FTIME ftime, ULONG* time)
    6261{
    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 saving
    73 
    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));
    7675#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));
    8484#endif
    8585}
     
    9090const char *NdpTypes[] =
    9191{
    92         "SMBFS",
    93         NULL
     92        "SMBFS",
     93        NULL
    9494}
    9595;
     
    100100static const NDPROPERTYINFO smbProperties[] =
    101101{
    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}
    114114};
    115115
     
    118118const NDPROPERTYINFO *NdpPropertiesInfo[] =
    119119{
    120         smbProperties
     120        smbProperties
    121121};
    122122
     
    130130static int lockInit (void)
    131131{
    132         return ph->fsphCreateMutex (&mutex);
     132        return ph->fsphCreateMutex (&mutex);
    133133}
    134134
    135135static void lockClose (void)
    136136{
    137         ph->fsphCloseMutex (mutex);
     137        ph->fsphCloseMutex (mutex);
    138138}
    139139
    140140static int lockRequest (void)
    141141{
    142         return ph->fsphRequestMutex (mutex, SEM_INDEFINITE_WAIT);
     142        return ph->fsphRequestMutex (mutex, SEM_INDEFINITE_WAIT);
    143143}
    144144
    145145static void lockRelease (void)
    146146{
    147         ph->fsphReleaseMutex (mutex);
     147        ph->fsphReleaseMutex (mutex);
    148148}
    149149
    150150#if LIBSMB_THREAD_SAFE==0
    151151
    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;           \
    156156} while (0)
    157157
    158 #define LEAVE() do {    \
    159         lockRelease();  \
     158#define LEAVE() do {   \
     159        lockRelease(); \
    160160} while (0)
    161161
     
    167167int helperEASet (cli_state *cli, FEALIST *pFEAList, char *path)
    168168{
    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;
    196193}
    197194
    198195int APIENTRY NdpPluginLoad (PLUGINHELPERTABLE2L *pPHT)
    199196{
    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;
    219206}
    220207
     
    222209int APIENTRY NdpPluginFree (void)
    223210{
    224         debugDelete();
    225         lockClose();
    226         return NO_ERROR;
     211        debugDelete();
     212        lockClose();
     213        return NO_ERROR;
    227214}
    228215
     
    230217void getfindinfo(Connection * pConn, FILEFINDBUF3 * stat, smbwrp_fileinfo * finfo)
    231218{
    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;
    255240}
    256241
    257242int getfindinfoL(Connection * pConn, void * plist, smbwrp_fileinfo * finfo, ULONG ulAttribute, char * mask)
    258243{
    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;
    291270}
    292271
    293272static unsigned char fromhex (char c)
    294273{
    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;
    311284}
    312285
    313286static char tohex (unsigned char b)
    314287{
    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);
    323294}
    324295
    325296static void decryptPassword (const char *pszCrypt, char *pszPlain)
    326297{
    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;
    337309}
    338310
    339311static void encryptPassword (const char *pszPlain, char *pszCrypt)
    340312{
    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;
    353326}
    354327
     
    358331int initResource (Resource *pRes, NDPROPERTYHANDLE properties)
    359332{
    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;
    367340#ifdef HAVE_KRB5_H
    368         pRes->krb5support = 1;
     341        pRes->krb5support = 1;
    369342#else
    370         pRes->krb5support = 0;
     343        pRes->krb5support = 0;
    371344#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;
    511460}
    512461
    513462int iftestpath(char * path)
    514463{
    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;
    529475}
    530476
    531477int pathparser(Resource *pRes, Connection * pConn, char * path, char * result)
    532478{
    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 of LFN or smth similar
    540         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}
    636582
    637583/* check if the requested resource is available */
    638584static int checkMountResource( Resource* pRes)
    639585{
    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;
    681624}
    682625
    683626int APIENTRY NdpMountResource (HRESOURCE *presource, int type, NDPROPERTYHANDLE properties)
    684627{
    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}
    731672
    732673int APIENTRY NdpFreeResource (HRESOURCE resource)
    733674{
    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}
    745684
    746685int APIENTRY NdpRsrcCompare (HRESOURCE resource, HRESOURCE resource2)
    747686{
    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;
    765703}
    766704
    767705int APIENTRY NdpRsrcUpdate (HRESOURCE resource, HRESOURCE resource2)
    768706{
    769         // do nothing
    770         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;
    772710}
    773711
    774712int APIENTRY NdpRsrcQueryInfo (HRESOURCE resource, ULONG *pulFlags, void *pdata, ULONG insize, ULONG *poutlen)
    775713{
    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;
    814743}
    815744
    816745int APIENTRY NdpRsrcQueryFSAttach (HRESOURCE resource, void *pdata, ULONG insize, ULONG *poutlen)
    817746{
    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);
    821750}
    822751
    823752int APIENTRY NdpRsrcQueryFSAllocate (HRESOURCE resource, NDFSALLOCATE *pfsa)
    824753{
    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}
    879806
    880807int APIENTRY NdpCreateConnection (HRESOURCE resource, HCONNECTION *pconn)
    881808{
    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}
    922848
    923849int APIENTRY NdpFreeConnection (HCONNECTION conn)
    924850{
    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}
    947872
    948873/*
     
    965890int APIENTRY NdpQueryPathInfo (HCONNECTION conn, void *plist, char *szPath)
    966891{
    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);
    978903       
    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}
    10901005
    10911006int APIENTRY NdpFindStart (HCONNECTION conn, void *plist, NDFILEINFOL *pfiparent, char *szPath, ULONG ulAttribute)
    10921007{
    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;
    11831101}
    11841102
    11851103int APIENTRY NdpDeletePathInfo (HRESOURCE resource, NDFILEINFOL *pfi)
    11861104{
    1187 //      debuglocal(9,"NdpDeletePathInfo %d\n", 0);
    1188         return NO_ERROR;
     1105        debuglocal(9, "NdpDeletePathInfo %d\n", 0);
     1106        return NO_ERROR;
    11891107}
    11901108
    11911109int APIENTRY NdpRefresh (HCONNECTION conn, char *path, int tree)
    11921110{
    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;
    11951113}
    11961114
    11971115int APIENTRY NdpDiscardResourceData (HRESOURCE resource, NDDATABUF *pdatabuf)
    11981116{
    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;
    12071125}
    12081126
    12091127int APIENTRY NdpSetPathInfo (HCONNECTION conn, NDFILEINFOL *pfi, char *szPathName)
    12101128{
    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;
    12421159}
    12431160
    12441161int buildFEALIST(FEALIST *pFEASrc, GEALIST *pGEAList, FEALIST *pFEAList)
    12451162{
    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;
    13011223}
    13021224
    13031225int APIENTRY NdpEAQuery (HCONNECTION conn, GEALIST *pGEAList, NDFILEINFOL *pfi, FEALIST *pFEAList)
    13041226{
    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;
    13781291}
    13791292
    13801293int APIENTRY NdpEASet (HCONNECTION conn, FEALIST *pFEAList, NDFILEINFOL *pfi)
    13811294{
    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;
    14141324}
    14151325
    14161326int APIENTRY NdpEASize (HCONNECTION conn, NDFILEINFOL *pfi, ULONG *pulEASize)
    14171327{
    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;
    14971400}
    14981401
    14991402int APIENTRY NdpSetCurrentDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szPath)
    15001403{
    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};
    15061409       
    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;
    15231426}
    15241427
    15251428int APIENTRY NdpCopy (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
    15261429{
    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;
    15291432}
    15301433
    15311434int APIENTRY NdpCopy2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
    15321435{
    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;
    15351438}
    15361439
    15371440int APIENTRY NdpForceDelete (HCONNECTION conn, NDFILEINFOL *pfi, char *szFile)
    15381441{
    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;
    15631466}
    15641467
    15651468int APIENTRY NdpCreateDir (HCONNECTION conn, NDFILEINFOL *pfiparent, char *szDirName, FEALIST *pFEAList)
    15661469{
    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;
    15981499}
    15991500
    16001501int APIENTRY NdpDeleteDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szDir)
    16011502{
    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;
    16261527}
    16271528
    16281529int APIENTRY NdpMove (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
    16291530{
    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;
    16701574}
    16711575
    16721576int APIENTRY NdpMove2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
    16731577{
    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;
    16761580}
    16771581
     
    16791583int APIENTRY NdpChangeCase (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
    16801584{
    1681         return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
     1585        return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
    16821586}
    16831587
    16841588int APIENTRY NdpRename (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
    16851589{
    1686         return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
     1590        return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
    16871591}
    16881592
    16891593int smbopen(Connection *pConn, char *szFileName, int flags, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
    16901594{
    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;
    17401651}
    17411652
    17421653int APIENTRY NdpOpenReplace (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
    17431654{
    1744         return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
     1655        return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
    17451656}
    17461657
    17471658int APIENTRY NdpOpenReplaceL(HCONNECTION conn, NDFILEINFO *pfi, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
    17481659{
    1749         return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
     1660        return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
    17501661}
    17511662
    17521663int APIENTRY NdpOpenCreate (HCONNECTION conn, NDFILEINFOL *pfiparent, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
    17531664{
    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);
    17561666}
    17571667
    17581668int APIENTRY NdpOpenCreateL(HCONNECTION conn, NDFILEINFO *pfiparent, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
    17591669{
    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);
    17611671}
    17621672
    17631673int APIENTRY NdpOpenExisting (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulOpenMode, USHORT *pfNeedEA)
    17641674{
    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);
    17671678}
    17681679
    17691680int APIENTRY NdpSetFileAttribute (HCONNECTION conn, NDFILEINFOL *pfi, char *szFileName, USHORT usAttr)
    17701681{
    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;
    17971708}
    17981709
    17991710int APIENTRY NdpFlush (HRESOURCE resource)
    18001711{
    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*/
    18061720#define ND_PL_INIT_THREAD 0xFFFF0000
    18071721
    18081722int APIENTRY NdpIOCTL (int type, HRESOURCE resource, char *path, int function, void *in, ULONG insize, PULONG poutlen)
    18091723{
    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;
    18291743}
    18301744
    18311745int APIENTRY NdpFileQueryInfo (HCONNECTION conn, NDFILEHANDLE handle, void *plist)
    18321746{
    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;
    18591775}
    18601776
    18611777int APIENTRY NdpFileEAQuery (HCONNECTION conn, NDFILEHANDLE handle, GEALIST *pGEAList, FEALIST *pFEAList)
    18621778{
    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;
    19251833}
    19261834
    19271835int APIENTRY NdpFileEASet (HCONNECTION conn, NDFILEHANDLE handle, FEALIST *pFEAList)
    19281836{
    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;
    19731879}
    19741880
    19751881int APIENTRY NdpFileEASize (HCONNECTION conn, NDFILEHANDLE handle, ULONG *pulEASize)
    19761882{
    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;
    20361935}
    20371936
    20381937int APIENTRY NdpFileSetInfo (HCONNECTION conn, NDFILEHANDLE handle, NDFILEINFOL *pfi)
    20391938{
    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;
    20691970}
    20701971
    20711972int APIENTRY NdpFileSetFilePtrL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llOffset, ULONG ulMethod, LONGLONG *pllActual)
    20721973{
    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;
    20972000}
    20982001
    20992002int APIENTRY NdpFileSetFilePtr (HCONNECTION conn, NDFILEHANDLE handle, LONG lOffset, ULONG ulMethod, ULONG *pulActual)
    21002003{
    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;
    21062009}
    21072010
    21082011int APIENTRY NdpFileClose (HCONNECTION conn, NDFILEHANDLE handle)
    21092012{
    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;
    21342038}
    21352039
    21362040int APIENTRY NdpFileCommit (HCONNECTION conn, NDFILEHANDLE handle)
    21372041{
    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}
    21422045
    21432046int APIENTRY NdpFileNewSize (HCONNECTION conn, NDFILEHANDLE handle, ULONG ulLen)
    21442047{
    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;
    21482051}
    21492052
    21502053int APIENTRY NdpFileNewSizeL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llLen)
    21512054{
    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;
    21742079}
    21752080
     
    21782083int APIENTRY NdpFileRead (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulRead, ULONG *pulActual)
    21792084{
    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;
    22322131}
    22332132
    22342133int APIENTRY NdpFileWrite (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulWrite, ULONG *pulActual)
    22352134{
    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  
    3434int os2cli_errno(cli_state * cli)
    3535{
    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));
    4140}
    4241
    4342void smbwrp_Logging()
    4443{
    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         else
    55         {
    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
    6665const char * smbwrp_getVersion()
    6766{
    68         return samba_version_string();
     67        return samba_version_string();
    6968}
    7069
    7170int _System smbwrp_getclisize(void)
    7271{
    73         return sizeof(struct cli_state);
    74 }
    75 
    76 /*****************************************************
    77 initialise structures
    78 *******************************************************/
     72        return sizeof(struct cli_state);
     73}
     74
     75/*
     76 * initialise structures
     77 */
    7978int _System smbwrp_init(void)
    8079{
    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;
    116108
    117109}
     
    119111void smbwrp_initthread(void)
    120112{
    121         /*
    122         Block SIGPIPE (from lib/util_sock.c: write())
    123         It is not needed and should not stop execution
    124         */
    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);
    126118}
    127119
    128120#if 0
    129 /*****************************************************
    130 remove redundent stuff from a filename
    131 *******************************************************/
     121/*
     122 * remove redundent stuff from a filename
     123 */
    132124void clean_fname(char *name)
    133125{
    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        }
    218210}
    219211#endif
    220212
    221 /*****************************************************
    222 return a connection to a server
    223 *******************************************************/
     213/*
     214 * return a connection to a server
     215 */
    224216int _System smbwrp_connect( Resource* pRes, cli_state ** cli)
    225217{
    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);
    274263
    275264 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);
    364351       
    365         // save cli_state pointer
    366         *cli = c;
    367 
    368         return 0;
    369 }
    370 
    371 /*****************************************************
    372 close a connection to a server
    373 *******************************************************/
     352        // save cli_state pointer
     353        *cli = c;
     354
     355        return 0;
     356}
     357
     358/*
     359 * close a connection to a server
     360 */
    374361void _System smbwrp_disconnect( Resource* pRes, cli_state * cli)
    375362{
    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 */
    388371int _System smbwrp_open(cli_state * cli, smbwrp_file * file)
    389372{
    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 */
    415394int _System smbwrp_read(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result)
    416395{
    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);
    423400       
    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 */
     414int _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);
    436421       
    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 */
     437int _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        }
    450450       
    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
     471int _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 */
     503int _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 */
     519int _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);
    482530       
    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 */
    586537int _System smbwrp_unlink(cli_state * cli, const char *fname)
    587538{
    588         if (!cli || !fname)
    589         {
    590                 return maperror(EINVAL);
    591         }
     539        if (!cli || !fname)
     540           return maperror(EINVAL);
     541
    592542#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
    605553#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 */
    616563int _System smbwrp_lseek(cli_state * cli, smbwrp_file * file, int whence, long long offset)
    617564{
    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 */
    662601int _System smbwrp_getattr(smbwrp_server *srv, cli_state * cli, smbwrp_fileinfo *finfo)
    663602{
    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        }
    711647       
    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 */
    742680int _System smbwrp_fgetattr(cli_state * cli, smbwrp_file *file, smbwrp_fileinfo *finfo)
    743681{
    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;
    779716}
    780717
    781718// =============================DIRECTORY ROUTINES============================
    782719                                                                                                               
    783 /*****************************************************
    784 add a entry to a directory listing
    785 *******************************************************/
     720/*
     721 * add a entry to a directory listing
     722 */
    786723static void smbwrp_dir_add(const char* mnt, smbwrp_fileinfo *finfo, const char *mask, void *state)
    787724{
    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;
    799737}
    800738
    801739static void smbwrp_special_add(const char * name, void * state)
    802740{
    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);
     741smbwrp_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;
    816753}
    817754
    818755static void smbwrp_printjob_add(struct print_job_info *job, void * state)
    819756{
    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;
    834772}
    835773
     
    837775                           const char *comment, void *state)
    838776{
    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 */
    856796static int list_files(struct cli_state *cli, const char *mask, uint16 attribute,
    857797                  void (*fn)(const char *, smbwrp_fileinfo *, const char *,
    858798                             void *), void *state)
    859799{
    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);
    930863 fail:
    931         TALLOC_FREE(frame);
    932         return num_finfo;
    933 }
    934 
    935 /*****************************************************
    936 open a directory on the server
    937 *******************************************************/
     864        TALLOC_FREE(frame);
     865        return num_finfo;
     866}
     867
     868/*
     869 * open a directory on the server
     870 */
    938871int _System smbwrp_filelist(smbwrp_server *srv, cli_state * cli, filelist_state * state)
    939872{
    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 */
    995917int _System smbwrp_chdir(smbwrp_server *srv, cli_state * cli, char *fname)
    996918{
    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 */
    1021940int _System smbwrp_mkdir(cli_state * cli, char *fname)
    1022941{
    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 */
    1038954int _System smbwrp_rmdir(cli_state * cli, char *fname)
    1039955{
    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 */
    1055968int _System smbwrp_setea(cli_state * cli, char *fname, char * name, unsigned char * value, int size)
    1056969{
    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 */
    1071982int _System smbwrp_fsetea(cli_state * cli, smbwrp_file *file, char * name, unsigned char * value, int size)
    1072983{
    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;
    1082991}
    1083992
    1084993
    1085994#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 */
     995typedef struct _FEA
     996{
     997        unsigned char fEA;      // flags
     998        unsigned char cbName;   // name length not including NULL
     999        unsigned short cbValue; // value length
    10911000} FEA;
    10921001
    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 */
     1002typedef struct _FEALIST
     1003{
     1004        unsigned long cbList;   // total bytes of structure including full list
     1005        FEA list[1];            // variable length FEA structures
    10971006} FEALIST;
    10981007#pragma pack()
     
    11001009static int unilistea(cli_state * cli, char *fname, void * buffer, unsigned long size)
    11011010{
    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 64kb
    1125         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 path
    1157 *******************************************************/
     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 */
    11581067int _System smbwrp_listea(cli_state * cli, char *fname, void * buffer, unsigned long size)
    11591068{
    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 */
    11721079int _System smbwrp_flistea(cli_state * cli, smbwrp_file *file, void * buffer, unsigned long size)
    11731080{
    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 */
    11861091int _System smbwrp_dskattr(cli_state * cli, FSALLOCATE *pfsa)
    11871092{
    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  
    7474typedef struct smbwrp_server
    7575{
    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;
    8484} smbwrp_server;
    8585
    8686typedef struct smbwrp_file
    8787{
    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];
     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];
    101101} smbwrp_file;
    102102
    103103typedef struct smbwrp_fileinfo
    104104{
    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];
    112112} smbwrp_fileinfo;
    113113
    114114typedef struct smbwrp_fileseek
    115115{
    116         int whence;
    117         long offset;
    118         unsigned long result;
     116        int whence;
     117        long offset;
     118        unsigned long result;
    119119} smbwrp_fileseek;
    120120
     
    123123typedef struct _FSALLOCATE      /* fsalloc */
    124124{
    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;
    130130} FSALLOCATE;
    131131#endif
     
    135135typedef struct _Resource
    136136{
    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;
    143141        int cachetimeout;
    144142        int cachedepth;
    145         struct DirectoryCache *pdc;
     143        int loglevel;
     144        struct DirectoryCache *pdc;
    146145} Resource;
    147146
    148147typedef struct _Connection
    149148{
    150         Resource *pRes;
    151         cli_state* cli;
    152         smbwrp_file file;
     149        Resource *pRes;
     150        cli_state* cli;
     151        smbwrp_file file;
    153152} Connection;
    154153
     
    156155typedef struct filelist_state
    157156{
    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;
    171170} filelist_state;
    172171
  • trunk/client/src/util.c

    r957 r959  
    2626#include <stdlib.h>
    2727#include <string.h>
     28#include <stdio.h>
    2829
    2930#include "smbwrp.h"
     
    3233int maperror(int rc)
    3334{
    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        }
    95143//      debug_printf( "Unhandled return code %d\n");
    96         return rc + 40000;
     144        return rc + 40000;
    97145}
    98146
    99147char * getlastslash(char * path)
    100148{
    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;
    114159}
    115 
Note: See TracChangeset for help on using the changeset viewer.