~ubuntu-branches/ubuntu/maverick/krb5/maverick

« back to all changes in this revision

Viewing changes to src/util/support/plugins.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman
  • Date: 2009-05-07 16:16:34 UTC
  • mfrom: (13.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20090507161634-xqyk0s9na0le4flj
Tags: 1.7dfsg~beta1-4
When  decrypting the TGS response fails with the subkey, try with the
session key to work around Heimdal bug, Closes: #527353 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * util/support/plugins.c
3
3
 *
4
 
 * Copyright 2006 by the Massachusetts Institute of Technology.
 
4
 * Copyright 2006, 2008 by the Massachusetts Institute of Technology.
5
5
 * All Rights Reserved.
6
6
 *
7
7
 * Export of this software from the United States of America may
31
31
#if USE_DLOPEN
32
32
#include <dlfcn.h>
33
33
#endif
34
 
#if USE_CFBUNDLE
35
 
#include <CoreFoundation/CoreFoundation.h>
36
 
#endif
37
34
#include <stdio.h>
38
35
#include <sys/types.h>
39
36
#ifdef HAVE_SYS_STAT_H
49
46
#include <unistd.h>
50
47
#endif
51
48
 
 
49
#include "k5-platform.h"
 
50
 
 
51
#if USE_DLOPEN && USE_CFBUNDLE
 
52
#include <CoreFoundation/CoreFoundation.h>
 
53
 
 
54
/* Currently CoreFoundation only exists on the Mac so we just use
 
55
 * pthreads directly to avoid creating empty function calls on other
 
56
 * platforms.  If a thread initializer ever gets created in the common
 
57
 * plugin code, move this there */
 
58
static pthread_mutex_t krb5int_bundle_mutex = PTHREAD_MUTEX_INITIALIZER;
 
59
#endif
 
60
 
52
61
#include <stdarg.h>
53
62
static void Tprintf (const char *fmt, ...)
54
63
{
64
73
#if USE_DLOPEN
65
74
    void *dlhandle;
66
75
#endif
67
 
#if USE_CFBUNDLE
68
 
    CFBundleRef bundle;
 
76
#ifdef _WIN32
 
77
    HMODULE hinstPlugin;
69
78
#endif
70
 
#if !defined (USE_DLOPEN) && !defined (USE_CFBUNDLE)
 
79
#if !defined (USE_DLOPEN) && !defined (_WIN32)
71
80
    char dummy;
72
81
#endif
73
82
};
74
83
 
 
84
#ifdef _WIN32
 
85
struct dirent {
 
86
    long d_ino;                 /* inode (always 1 in WIN32) */
 
87
    off_t d_off;                /* offset to this dirent */
 
88
    unsigned short d_reclen;    /* length of d_name */
 
89
    char d_name[_MAX_FNAME+1];  /* filename (null terminated) */
 
90
};
 
91
 
 
92
typedef struct {
 
93
    long handle;                /* _findfirst/_findnext handle */
 
94
    short offset;               /* offset into directory */
 
95
    short finished;             /* 1 if there are not more files */
 
96
    struct _finddata_t fileinfo;/* from _findfirst/_findnext */
 
97
    char *dir;                  /* the dir we are reading */
 
98
    struct dirent dent;         /* the dirent to return */
 
99
} DIR;
 
100
 
 
101
DIR * opendir(const char *dir)
 
102
{
 
103
    DIR *dp;
 
104
    char *filespec;
 
105
    long handle;
 
106
    int index;
 
107
 
 
108
    filespec = malloc(strlen(dir) + 2 + 1);
 
109
    strcpy(filespec, dir);
 
110
    index = strlen(filespec) - 1;
 
111
    if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
 
112
        filespec[index] = '\0';
 
113
    strcat(filespec, "/*");
 
114
 
 
115
    dp = (DIR *)malloc(sizeof(DIR));
 
116
    dp->offset = 0;
 
117
    dp->finished = 0;
 
118
    dp->dir = strdup(dir);
 
119
 
 
120
    if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
 
121
        if (errno == ENOENT)
 
122
            dp->finished = 1;
 
123
        else {
 
124
            free(filespec);
 
125
            free(dp->dir);
 
126
            free(dp);
 
127
            return NULL;
 
128
        }
 
129
    }
 
130
 
 
131
    dp->handle = handle;
 
132
    free(filespec);
 
133
 
 
134
    return dp;
 
135
}
 
136
 
 
137
struct dirent * readdir(DIR *dp)
 
138
{
 
139
    if (!dp || dp->finished) return NULL;
 
140
 
 
141
    if (dp->offset != 0) {
 
142
        if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
 
143
            dp->finished = 1;
 
144
            return NULL;
 
145
        }
 
146
    }
 
147
    dp->offset++;
 
148
 
 
149
    strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
 
150
    dp->dent.d_ino = 1;
 
151
    dp->dent.d_reclen = (unsigned short)strlen(dp->dent.d_name);
 
152
    dp->dent.d_off = dp->offset;
 
153
 
 
154
    return &(dp->dent);
 
155
}
 
156
 
 
157
int closedir(DIR *dp)
 
158
{
 
159
    if (!dp) return 0;
 
160
    _findclose(dp->handle);
 
161
    if (dp->dir) free(dp->dir);
 
162
    if (dp) free(dp);
 
163
 
 
164
    return 0;
 
165
}
 
166
#endif
 
167
 
75
168
long KRB5_CALLCONV
76
169
krb5int_open_plugin (const char *filepath, struct plugin_file_handle **h, struct errinfo *ep)
77
170
{
89
182
 
90
183
    if (!err) {
91
184
        htmp = calloc (1, sizeof (*htmp)); /* calloc initializes ptrs to NULL */
92
 
        if (htmp == NULL) { err = errno; }
 
185
        if (htmp == NULL) { err = ENOMEM; }
93
186
    }
94
187
 
95
188
#if USE_DLOPEN
96
 
    if (!err && (statbuf.st_mode & S_IFMT) == S_IFREG) {
 
189
    if (!err && ((statbuf.st_mode & S_IFMT) == S_IFREG
 
190
#if USE_CFBUNDLE
 
191
                 || (statbuf.st_mode & S_IFMT) == S_IFDIR
 
192
#endif /* USE_CFBUNDLE */
 
193
        )) {
97
194
        void *handle = NULL;
 
195
        
 
196
#if USE_CFBUNDLE
 
197
        char executablepath[MAXPATHLEN];
 
198
        
 
199
        if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
 
200
            int lock_err = 0;
 
201
            CFStringRef pluginString = NULL;
 
202
            CFURLRef pluginURL = NULL;
 
203
            CFBundleRef pluginBundle = NULL;
 
204
            CFURLRef executableURL = NULL;
 
205
 
 
206
            /* Lock around CoreFoundation calls since objects are refcounted
 
207
             * and the refcounts are not thread-safe.  Using pthreads directly
 
208
             * because this code is Mac-specific */
 
209
            lock_err = pthread_mutex_lock(&krb5int_bundle_mutex);
 
210
            if (lock_err) { err = lock_err; }
 
211
            
 
212
            if (!err) {
 
213
                pluginString = CFStringCreateWithCString (kCFAllocatorDefault, 
 
214
                                                          filepath, 
 
215
                                                          kCFStringEncodingASCII);
 
216
                if (pluginString == NULL) { err = ENOMEM; }
 
217
            }
 
218
            
 
219
            if (!err) {
 
220
                pluginURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, 
 
221
                                                           pluginString, 
 
222
                                                           kCFURLPOSIXPathStyle, 
 
223
                                                           true);
 
224
                if (pluginURL == NULL) { err = ENOMEM; }
 
225
            }
 
226
            
 
227
            if (!err) {
 
228
                pluginBundle = CFBundleCreate (kCFAllocatorDefault, pluginURL);
 
229
                if (pluginBundle == NULL) { err = ENOENT; } /* XXX need better error */
 
230
            }
 
231
            
 
232
            if (!err) {
 
233
                executableURL = CFBundleCopyExecutableURL (pluginBundle);
 
234
                if (executableURL == NULL) { err = ENOMEM; }
 
235
            }
 
236
            
 
237
            if (!err) {
 
238
                if (!CFURLGetFileSystemRepresentation (executableURL,
 
239
                                                       true, /* absolute */
 
240
                                                       (UInt8 *)executablepath, 
 
241
                                                       sizeof (executablepath))) {
 
242
                    err = ENOMEM;
 
243
                }
 
244
            }
 
245
            
 
246
            if (!err) {
 
247
                /* override the path the caller passed in */
 
248
                filepath = executablepath;
 
249
            }
 
250
            
 
251
            if (executableURL    != NULL) { CFRelease (executableURL); }
 
252
            if (pluginBundle     != NULL) { CFRelease (pluginBundle); }
 
253
            if (pluginURL        != NULL) { CFRelease (pluginURL); }
 
254
            if (pluginString     != NULL) { CFRelease (pluginString); }
 
255
            
 
256
            /* unlock after CFRelease calls since they modify refcounts */
 
257
            if (!lock_err) { pthread_mutex_unlock (&krb5int_bundle_mutex); }
 
258
        }
 
259
#endif /* USE_CFBUNDLE */
 
260
 
98
261
#ifdef RTLD_GROUP
99
262
#define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL | RTLD_GROUP)
100
263
#else
101
264
#define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL)
102
265
#endif
103
 
 
104
266
        if (!err) {
105
267
            handle = dlopen(filepath, PLUGIN_DLOPEN_FLAGS);
106
268
            if (handle == NULL) {
119
281
 
120
282
        if (handle != NULL) { dlclose (handle); }
121
283
    }
122
 
#endif
123
 
 
124
 
#if USE_CFBUNDLE
125
 
    if (!err && (statbuf.st_mode & S_IFMT) == S_IFDIR) {
126
 
        CFStringRef pluginPath = NULL;
127
 
        CFURLRef pluginURL = NULL;
128
 
        CFBundleRef pluginBundle = NULL;
129
 
 
130
 
        if (!err) {
131
 
            pluginPath = CFStringCreateWithCString (kCFAllocatorDefault, filepath, 
132
 
                                                    kCFStringEncodingASCII);
133
 
            if (pluginPath == NULL) { err = ENOMEM; }
134
 
        }
135
 
        
136
 
        if (!err) {
137
 
            pluginURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, pluginPath, 
138
 
                                                       kCFURLPOSIXPathStyle, true);
139
 
            if (pluginURL == NULL) { err = ENOMEM; }
140
 
        }
141
 
        
142
 
        if (!err) {
143
 
            pluginBundle = CFBundleCreate (kCFAllocatorDefault, pluginURL);
144
 
            if (pluginBundle == NULL) { err = ENOENT; } /* XXX need better error */
145
 
        }
146
 
        
147
 
        if (!err) {
148
 
            if (!CFBundleIsExecutableLoaded (pluginBundle)) {
149
 
                int loaded = CFBundleLoadExecutable (pluginBundle);
150
 
                if (!loaded) { err = ENOENT; }  /* XXX need better error */
151
 
            }
152
 
        }
153
 
        
 
284
#endif /* USE_DLOPEN */
 
285
        
 
286
#ifdef _WIN32
 
287
    if (!err && (statbuf.st_mode & S_IFMT) == S_IFREG) {
 
288
        HMODULE handle = NULL;
 
289
 
 
290
        handle = LoadLibrary(filepath);
 
291
        if (handle == NULL) {
 
292
            Tprintf ("Unable to load dll: %s\n", filepath);
 
293
            err = ENOENT; /* XXX */
 
294
            krb5int_set_error (ep, err, "%s", "unable to load dll");
 
295
        }
 
296
 
154
297
        if (!err) {
155
298
            got_plugin = 1;
156
 
            htmp->bundle = pluginBundle;
157
 
            pluginBundle = NULL;  /* htmp->bundle takes ownership */
 
299
            htmp->hinstPlugin = handle;
 
300
            handle = NULL;
158
301
        }
159
302
 
160
 
        if (pluginBundle != NULL) { CFRelease (pluginBundle); }
161
 
        if (pluginURL    != NULL) { CFRelease (pluginURL); }
162
 
        if (pluginPath   != NULL) { CFRelease (pluginPath); }
 
303
        if (handle != NULL) 
 
304
            FreeLibrary(handle); 
163
305
    }
164
306
#endif
165
 
        
 
307
 
166
308
    if (!err && !got_plugin) {
167
309
        err = ENOENT;  /* no plugin or no way to load plugins */
168
310
    }
199
341
    }
200
342
#endif
201
343
    
202
 
#if USE_CFBUNDLE
203
 
    if (!err && !sym && (h->bundle != NULL)) {
204
 
        CFStringRef cfsymname = NULL;
205
 
        
206
 
        if (!err) {
207
 
            cfsymname = CFStringCreateWithCString (kCFAllocatorDefault, csymname, 
208
 
                                                   kCFStringEncodingASCII);
209
 
            if (cfsymname == NULL) { err = ENOMEM; }
210
 
        }
211
 
        
212
 
        if (!err) {
213
 
            if (isfunc) {
214
 
                sym = CFBundleGetFunctionPointerForName (h->bundle, cfsymname);
215
 
            } else {
216
 
                sym = CFBundleGetDataPointerForName (h->bundle, cfsymname);
217
 
            }
218
 
            if (sym == NULL) { err = ENOENT; }  /* XXX */       
219
 
        }
220
 
        
221
 
        if (cfsymname != NULL) { CFRelease (cfsymname); }
 
344
#ifdef _WIN32
 
345
    LPVOID lpMsgBuf;
 
346
    DWORD dw;
 
347
 
 
348
    if (!err && !sym && (h->hinstPlugin != NULL)) {
 
349
        sym = GetProcAddress(h->hinstPlugin, csymname);
 
350
        if (sym == NULL) {
 
351
            const char *e = "unable to get dll symbol"; /* XXX copy and save away */
 
352
            Tprintf ("GetProcAddress(%s): %s\n", csymname, GetLastError());
 
353
            err = ENOENT; /* XXX */
 
354
            krb5int_set_error(ep, err, "%s", e);
 
355
 
 
356
            dw = GetLastError();
 
357
            if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
 
358
                              FORMAT_MESSAGE_FROM_SYSTEM,
 
359
                              NULL,
 
360
                              dw,
 
361
                              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
 
362
                              (LPTSTR) &lpMsgBuf,
 
363
                              0, NULL )) {
 
364
 
 
365
                 fprintf (stderr, "unable to get dll symbol, %s\n", (LPCTSTR)lpMsgBuf);
 
366
                 LocalFree(lpMsgBuf);
 
367
             }
 
368
        }
222
369
    }
223
370
#endif
224
 
    
 
371
 
225
372
    if (!err && (sym == NULL)) {
226
373
        err = ENOENT;  /* unimplemented */
227
374
    }
259
406
#if USE_DLOPEN
260
407
    if (h->dlhandle != NULL) { dlclose(h->dlhandle); }
261
408
#endif
262
 
#if USE_CFBUNDLE
263
 
    /* Do not call CFBundleUnloadExecutable because it's not ref counted. 
264
 
     * CFRelease will unload the bundle if the internal refcount goes to zero. */
265
 
    if (h->bundle != NULL) { CFRelease (h->bundle); }
 
409
#ifdef _WIN32
 
410
    if (h->hinstPlugin != NULL) { FreeLibrary(h->hinstPlugin); }
266
411
#endif
267
412
    free (h);
268
413
}
272
417
#include <dirent.h>
273
418
#define NAMELEN(D) strlen((D)->d_name)
274
419
#else
 
420
#ifndef _WIN32
275
421
#define dirent direct
276
422
#define NAMELEN(D) ((D)->d->namlen)
 
423
#else
 
424
#define NAMELEN(D) strlen((D)->d_name)
 
425
#endif
277
426
#if HAVE_SYS_NDIR_H
278
427
# include <sys/ndir.h>
279
428
#elif HAVE_SYS_DIR_H
298
447
    long err = 0;
299
448
 
300
449
    *harray = calloc (1, sizeof (**harray)); /* calloc initializes to NULL */
301
 
    if (*harray == NULL) { err = errno; }
 
450
    if (*harray == NULL) { err = ENOMEM; }
302
451
 
303
452
    return err;
304
453
}
305
454
 
306
455
static long
307
 
krb5int_plugin_file_handle_array_add (struct plugin_file_handle ***harray, int *count, 
 
456
krb5int_plugin_file_handle_array_add (struct plugin_file_handle ***harray, size_t *count, 
308
457
                                      struct plugin_file_handle *p)
309
458
{
310
459
    long err = 0;
311
460
    struct plugin_file_handle **newharray = NULL;
312
 
    int newcount = *count + 1;
 
461
    size_t newcount = *count + 1;
313
462
    
314
463
    newharray = realloc (*harray, ((newcount + 1) * sizeof (**harray))); /* +1 for NULL */
315
464
    if (newharray == NULL) { 
316
 
        err = errno; 
 
465
        err = ENOMEM;
317
466
    } else {
318
467
        newharray[newcount - 1] = p;
319
468
        newharray[newcount] = NULL;
337
486
}
338
487
 
339
488
#if TARGET_OS_MAC
340
 
#define FILEEXTS { "", ".bundle", ".so", NULL }
 
489
#define FILEEXTS { "", ".bundle", ".dylib", ".so", NULL }
341
490
#elif defined(_WIN32)
342
491
#define FILEEXTS  { "", ".dll", NULL }
343
492
#else
364
513
    long err = 0;
365
514
    static const char *const fileexts[] = FILEEXTS;
366
515
    char **tempnames = NULL;
367
 
    int i;
 
516
    size_t bases_count = 0;
 
517
    size_t exts_count = 0;
 
518
    size_t i;
368
519
 
 
520
    if (!filebases) { err = EINVAL; }
 
521
    if (!filenames) { err = EINVAL; }
 
522
   
369
523
    if (!err) {
370
 
        size_t count = 0;
371
 
        for (i = 0; filebases[i] != NULL; i++, count++);
372
 
        for (i = 0; fileexts[i] != NULL; i++, count++);
373
 
        tempnames = calloc (count, sizeof (char *));
374
 
        if (tempnames == NULL) { err = errno; }
 
524
        for (i = 0; filebases[i]; i++) { bases_count++; }
 
525
        for (i = 0; fileexts[i]; i++) { exts_count++; }
 
526
        tempnames = calloc ((bases_count * exts_count)+1, sizeof (char *));
 
527
        if (!tempnames) { err = ENOMEM; }
375
528
    }
376
529
 
377
530
    if (!err) {
378
 
        int j;
379
 
        for (i = 0; !err && (filebases[i] != NULL); i++) {
380
 
            size_t baselen = strlen (filebases[i]);
381
 
            for (j = 0; !err && (fileexts[j] != NULL); j++) {
382
 
                size_t len = baselen + strlen (fileexts[j]) + 2; /* '.' + NULL */
383
 
                tempnames[i+j] = malloc (len * sizeof (char));
384
 
                if (tempnames[i+j] == NULL) { 
385
 
                    err = errno; 
386
 
                } else {
387
 
                    sprintf (tempnames[i+j], "%s%s", filebases[i], fileexts[j]);
388
 
                }
 
531
        size_t j;
 
532
        for (i = 0; !err && filebases[i]; i++) {
 
533
            for (j = 0; !err && fileexts[j]; j++) {
 
534
                if (asprintf(&tempnames[(i*exts_count)+j], "%s%s", 
 
535
                             filebases[i], fileexts[j]) < 0) {
 
536
                    tempnames[(i*exts_count)+j] = NULL;
 
537
                    err = ENOMEM;
 
538
                }
389
539
            }
390
540
        }
 
541
        tempnames[bases_count * exts_count] = NULL; /* NUL-terminate */
391
542
    }
392
543
    
393
544
    if (!err) {
395
546
        tempnames = NULL;
396
547
    }
397
548
    
398
 
    if (tempnames != NULL) { krb5int_free_plugin_filenames (tempnames); }
 
549
    if (tempnames) { krb5int_free_plugin_filenames (tempnames); }
399
550
    
400
551
    return err;
401
552
}
413
564
{
414
565
    long err = 0;
415
566
    struct plugin_file_handle **h = NULL;
416
 
    int count = 0;
 
567
    size_t count = 0;
417
568
    char **filenames = NULL;
418
569
    int i;
419
570
 
426
577
    }
427
578
    
428
579
    for (i = 0; !err && dirnames[i] != NULL; i++) {
429
 
        size_t dirnamelen = strlen (dirnames[i]) + 1; /* '/' */
430
580
        if (filenames != NULL) {
431
581
            /* load plugins with names from filenames from each directory */
432
582
            int j;
436
586
                char *filepath = NULL;
437
587
                
438
588
                if (!err) {
439
 
                    filepath = malloc (dirnamelen + strlen (filenames[j]) + 1); /* NULL */
440
 
                    if (filepath == NULL) { 
441
 
                        err = errno; 
442
 
                    } else {
443
 
                        sprintf (filepath, "%s/%s", dirnames[i], filenames[j]);
 
589
                    if (asprintf(&filepath, "%s/%s", dirnames[i], filenames[j]) < 0) {
 
590
                        filepath = NULL;
 
591
                        err = ENOMEM;
444
592
                    }
445
593
                }
446
594
                
454
602
            }
455
603
        } else {
456
604
            /* load all plugins in each directory */
457
 
#ifndef _WIN32
458
605
            DIR *dir = opendir (dirnames[i]);
459
606
            
460
607
            while (dir != NULL && !err) {
472
619
                
473
620
                if (!err) {
474
621
                    int len = NAMELEN (d);
475
 
                    filepath = malloc (dirnamelen + len + 1); /* NULL */
476
 
                    if (filepath == NULL) { 
477
 
                        err = errno; 
478
 
                    } else {
479
 
                        sprintf (filepath, "%s/%*s", dirnames[i], len, d->d_name);
 
622
                    if (asprintf(&filepath, "%s/%*s", dirnames[i], len, d->d_name) < 0) {
 
623
                        filepath = NULL;
 
624
                        err = ENOMEM;
480
625
                    }
481
626
                }
482
627
                
492
637
            }
493
638
            
494
639
            if (dir != NULL) { closedir (dir); }
495
 
#else
496
 
            /* Until a Windows implementation of this code is implemented */
497
 
            err = ENOENT;
498
 
#endif /* _WIN32 */
499
640
        }
500
641
    }
501
642
        
542
683
{
543
684
    long err = 0;
544
685
    void **p = NULL;
545
 
    int count = 0;
 
686
    size_t count = 0;
546
687
 
547
688
    /* XXX Do we need to add a leading "_" to the symbol name on any
548
689
       modern platforms?  */
551
692
 
552
693
    if (!err) {
553
694
        p = calloc (1, sizeof (*p)); /* calloc initializes to NULL */
554
 
        if (p == NULL) { err = errno; }
 
695
        if (p == NULL) { err = ENOMEM; }
555
696
    }
556
697
    
557
698
    if (!err && (dirhandle != NULL) && (dirhandle->files != NULL)) {
566
707
                count++;
567
708
                newp = realloc (p, ((count + 1) * sizeof (*p))); /* +1 for NULL */
568
709
                if (newp == NULL) { 
569
 
                    err = errno; 
 
710
                    err = ENOMEM; 
570
711
                } else {
571
712
                    p = newp;
572
713
                    p[count - 1] = sym;
601
742
{
602
743
    long err = 0;
603
744
    void (**p)() = NULL;
604
 
    int count = 0;
 
745
    size_t count = 0;
605
746
    
606
747
    /* XXX Do we need to add a leading "_" to the symbol name on any
607
748
        modern platforms?  */
610
751
    
611
752
    if (!err) {
612
753
        p = calloc (1, sizeof (*p)); /* calloc initializes to NULL */
613
 
        if (p == NULL) { err = errno; }
 
754
        if (p == NULL) { err = ENOMEM; }
614
755
    }
615
756
    
616
757
    if (!err && (dirhandle != NULL) && (dirhandle->files != NULL)) {
625
766
                count++;
626
767
                newp = realloc (p, ((count + 1) * sizeof (*p))); /* +1 for NULL */
627
768
                if (newp == NULL) { 
628
 
                    err = errno; 
 
769
                    err = ENOMEM;
629
770
                } else {
630
771
                    p = newp;
631
772
                    p[count - 1] = sym;