~n-muench/ubuntu/maverick/open-vm-tools/open-vm-tools.fix-632101

« back to all changes in this revision

Viewing changes to lib/dnd/dndLinux.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-10-18 12:28:19 UTC
  • mfrom: (1.1.7 upstream) (2.4.9 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091018122819-00vqew6m0ztpqcqp
Tags: 2009.10.15-201664-1
MergingĀ upstreamĀ versionĀ 2009.10.15-201664.

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
#include "escape.h"
41
41
#include "su.h"
42
42
#if defined(linux) || defined(sun) || defined(__FreeBSD__)
43
 
#include "vmblock.h"
 
43
#include "vmblock_user.h"
44
44
#include "mntinfo.h"
45
45
#endif
46
46
 
159
159
    * XXX Note that this assumes we only support dropping files, based on the
160
160
    * definition of the macro that is used.
161
161
    */
 
162
 
162
163
   nameStart = &uriList[*index];
163
164
 
164
165
   if (strncmp(nameStart,
170
171
                      sizeof DND_URI_LIST_PRE_KDE - 1) == 0) {
171
172
      nameStart += sizeof DND_URI_LIST_PRE_KDE - 1;
172
173
   } else {
173
 
      Warning("DnDUriListGetFile: the URI list did not begin with %s or %s\n",
 
174
      Warning("%s: the URI list did not begin with %s or %s\n", __func__,
174
175
              DND_URI_LIST_PRE, DND_URI_LIST_PRE_KDE);
 
176
 
175
177
      return NULL;
176
178
    }
177
179
 
192
194
 
193
195
   *index = curr - uriList;
194
196
   *length = nameEnd - nameStart + 1;
 
197
 
195
198
   return (char *)nameStart;
196
199
}
197
200
 
244
247
    * Retrieve an allocated, unescaped name.  This undoes the ' ' -> "%20"
245
248
    * escaping as required by RFC 1630 for entries in a uri-list.
246
249
    */
 
250
 
247
251
   unescapedName = Escape_Undo('%', file, fileLength, &unescapedLength);
248
252
   if (!unescapedName) {
249
253
      Warning("%s: error unescaping filename\n", __func__);
 
254
 
250
255
      return NULL;
251
256
   }
252
257
 
254
259
   if (length) {
255
260
      *length = unescapedLength;
256
261
   }
 
262
 
257
263
   return unescapedName;
258
264
}
259
265
 
261
267
/* We need to make this suck less. */
262
268
#if defined(linux) || defined(sun) || defined(__FreeBSD__)
263
269
 
264
 
#if defined(linux)
265
 
 
266
 
static INLINE int
267
 
VMBLOCK_CONTROL(int fd, int op, const char *path)
268
 
{
269
 
   return write(fd, path, op);
270
 
}
271
 
 
272
 
#elif defined(__FreeBSD__)
273
 
 
274
 
static INLINE int
275
 
VMBLOCK_CONTROL(int fd, int cmd, const char *path)
276
 
{
277
 
   char tpath[MAXPATHLEN];
278
 
 
279
 
   if (path != NULL) {
280
 
      /*
281
 
       * FreeBSD's ioctl data parameters must be of fixed size.  Guarantee a safe
282
 
       * buffer of size MAXPATHLEN by copying the user's string to one of our own.
283
 
       */
284
 
      strlcpy(tpath, path, MAXPATHLEN);
285
 
   }
286
 
 
287
 
   return ioctl(fd, cmd, tpath);
288
 
}
289
 
 
290
 
#elif defined(sun)
291
 
 
292
 
static INLINE int
293
 
VMBLOCK_CONTROL(int fd, int cmd, const char *path)
294
 
{
295
 
   return ioctl(fd, cmd, path);
296
 
}
297
 
 
298
 
#endif
299
 
 
300
 
 
301
270
/*
302
271
 *----------------------------------------------------------------------------
303
272
 *
324
293
   if (VMBLOCK_CONTROL(blockFd, VMBLOCK_ADD_FILEBLOCK, blockPath) != 0) {
325
294
      LOG(1, ("%s: Cannot add block on %s (%s)\n",
326
295
              __func__, blockPath, strerror(errno)));
 
296
 
327
297
      return FALSE;
328
298
   }
329
299
 
355
325
      if (VMBLOCK_CONTROL(blockFd, VMBLOCK_DEL_FILEBLOCK, blockedPath) != 0) {
356
326
         Log("%s: Cannot delete block on %s (%s)\n",
357
327
             __func__, blockedPath, strerror(errno));
 
328
 
358
329
         return FALSE;
359
330
      }
360
331
   } else {
361
332
      LOG(4, ("%s: Could not remove block on %s: "
362
333
              "fd to vmblock no longer exists.\n", __func__, blockedPath));
363
334
   }
 
335
 
364
336
   return TRUE;
365
337
}
366
338
 
391
363
 
392
364
 
393
365
/*
394
 
 * DnD_VmblockFuseControl --
395
 
 *
396
 
 *    Controlling function for FUSE-based blocker implementation.
397
 
 *    Passes requests to block and unblock file access to fuse module.
398
 
 *
399
 
 * Results:
400
 
 *    0 on success, -1 on failure.
401
 
 *
402
 
 * Notes:
403
 
 *    None.
404
 
 *
405
 
 */
406
 
 
407
 
static ssize_t
408
 
DnD_VmblockFuseControl(int fd,            // IN
409
 
                       char op,           // IN
410
 
                       const char *path)  // IN
411
 
{
412
 
   /*
413
 
    * buffer needs room for an operation character and a string with max length
414
 
    * PATH_MAX - 1.
415
 
    */
416
 
 
417
 
   char buffer[PATH_MAX];
418
 
   size_t pathLength;
419
 
 
420
 
   pathLength = strlen(path);
421
 
   if (pathLength >= PATH_MAX) {
422
 
      errno = ENAMETOOLONG;
423
 
      return -1;
424
 
   }
425
 
 
426
 
   buffer[0] = op;
427
 
   memcpy(buffer + 1, path, pathLength);
428
 
 
429
 
   /*
430
 
    * The lseek is only to prevent the file pointer from overflowing;
431
 
    * vmblock-fuse ignores the file pointer / offset. Overflowing the file
432
 
    * pointer causes write to fail:
433
 
    * http://article.gmane.org/gmane.comp.file-systems.fuse.devel/6648
434
 
    * There's also a race condition here where many threads all calling
435
 
    * VMBLOCK_CONTROL at the same time could have all their seeks executed one
436
 
    * after the other, followed by all the writes. Again, it's not a problem
437
 
    * unless the file pointer overflows which is very unlikely with 32 bit
438
 
    * offsets and practically impossible with 64 bit offsets.
439
 
    */
440
 
 
441
 
   if (lseek(fd, 0, SEEK_SET) < 0) {
442
 
      return -1;
443
 
   }
444
 
 
445
 
   if (write(fd, buffer, pathLength + 1) < 0) {
446
 
      return -1;
447
 
   }
448
 
 
449
 
   return 0;
450
 
}
451
 
 
452
 
 
453
 
/*
454
366
 *----------------------------------------------------------------------------
455
367
 *
456
368
 * DnD_AddBlockFuse --
473
385
{
474
386
   ASSERT(blockFd >= 0);
475
387
 
476
 
   if (DnD_VmblockFuseControl(blockFd, VMBLOCK_FUSE_ADD_FILEBLOCK,
477
 
                              blockPath) != 0) {
 
388
   if (VMBLOCK_CONTROL_FUSE(blockFd, VMBLOCK_FUSE_ADD_FILEBLOCK,
 
389
                            blockPath) != 0) {
478
390
      LOG(1, ("%s: Cannot add block on %s (%s)\n",
479
391
              __func__, blockPath, strerror(errno)));
 
392
 
480
393
      return FALSE;
481
394
   }
482
395
 
505
418
                    const char *blockedPath)        // IN
506
419
{
507
420
   if (blockFd >= 0) {
508
 
      if (DnD_VmblockFuseControl(blockFd, VMBLOCK_FUSE_DEL_FILEBLOCK,
509
 
                                 blockedPath) != 0) {
 
421
      if (VMBLOCK_CONTROL_FUSE(blockFd, VMBLOCK_FUSE_DEL_FILEBLOCK,
 
422
                               blockedPath) != 0) {
510
423
         Log("%s: Cannot delete block on %s (%s)\n",
511
424
             __func__, blockedPath, strerror(errno));
 
425
 
512
426
         return FALSE;
513
427
      }
514
428
   } else {
547
461
   if (size < 0) {
548
462
      LOG(4, ("%s: read failed, error %s.\n",
549
463
              __func__, strerror(errno)));
 
464
 
550
465
      return FALSE;
551
466
   }
552
467
 
553
468
   if (size != sizeof(VMBLOCK_FUSE_READ_RESPONSE)) {
554
469
      LOG(4, ("%s: Response too short (%"FMTSZ"d vs. %"FMTSZ"u).\n",
555
470
              __func__, size, sizeof(VMBLOCK_FUSE_READ_RESPONSE)));
 
471
 
556
472
      return FALSE;
557
473
   }
558
474
 
560
476
              sizeof(VMBLOCK_FUSE_READ_RESPONSE))) {
561
477
      LOG(4, ("%s: Invalid response %.*s",
562
478
              __func__, (int)sizeof(VMBLOCK_FUSE_READ_RESPONSE) - 1, buf));
 
479
 
563
480
      return FALSE;
564
481
   }
565
482
 
600
517
   fp = OPEN_MNTFILE("r");
601
518
   if (fp == NULL) {
602
519
      LOG(1, ("%s: could not open mount file\n", __func__));
 
520
 
603
521
      return -1;
604
522
   }
605
523
 
608
526
       * In the future we can publish the mount point in VMDB so that the UI
609
527
       * can use it rather than enforcing the VMBLOCK_MOUNT_POINT check here.
610
528
       */
 
529
 
611
530
      if (strcmp(MNTINFO_FSTYPE(mnt), vmbFsName) == 0 &&
612
531
          strcmp(MNTINFO_MNTPT(mnt), vmbMntPoint) == 0) {
613
532
         found = TRUE;
766
685
      blkCtrl->RemoveBlock = DnD_RemoveBlockLegacy;
767
686
   } else {
768
687
      Log("%s: Can't determine block type.\n", __func__);
 
688
 
769
689
      return FALSE;
770
690
   }
771
691