PageRenderTime 123ms CodeModel.GetById 10ms app.highlight 99ms RepoModel.GetById 1ms app.codeStats 1ms

/filesystems/procfs/procfs.cc

http://macfuse.googlecode.com/
C++ | 4975 lines | 4101 code | 796 blank | 78 comment | 606 complexity | 8905523075cf982ed57d446bcdf473d7 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * procfs as a MacFUSE file system for Mac OS X
   3 *
   4 * Copyright Amit Singh. All Rights Reserved.
   5 * http://osxbook.com
   6 *
   7 * http://code.google.com/p/macfuse/
   8 *
   9 * Source License: GNU GENERAL PUBLIC LICENSE (GPL)
  10 */
  11
  12#define MACFUSE_PROCFS_VERSION "2.0"
  13#define FUSE_USE_VERSION 26
  14
  15#include <dirent.h>
  16#include <errno.h>
  17#include <fcntl.h>
  18#include <getopt.h>
  19#include <pthread.h>
  20#include <stdio.h>
  21#include <string.h>
  22#include <sys/sysctl.h>
  23
  24#include <grp.h>
  25#include <pwd.h>
  26
  27#include <mach/mach.h>
  28#include <mach/mach_vm.h>
  29#include <mach/vm_region.h>
  30#include <mach/vm_statistics.h>
  31
  32#include <Carbon/Carbon.h>
  33#include <CoreFoundation/CoreFoundation.h>
  34#include <IOKit/IOKitLib.h>
  35
  36#include <cassert>
  37#include <vector>
  38#include <pcrecpp.h>
  39
  40#include <fuse.h>
  41
  42#include "procfs_displays.h"
  43#include "procfs_proc_info.h"
  44#include "procfs_windows.h"
  45#include "sequencegrab/procfs_sequencegrab.h"
  46
  47#if MACFUSE_PROCFS_ENABLE_TPM
  48#include "procfs_tpm.h"
  49#endif /* MACFUSE_PROCFS_ENABLE_TPM */
  50
  51static int procfs_ui = 0;
  52#define PROCFS_DEFAULT_FILE_SIZE 65536
  53
  54static int total_file_patterns = 0;
  55static int total_directory_patterns = 0;
  56static int total_link_patterns = 0;
  57
  58static processor_port_array_t processor_list;
  59static mach_port_t  p_default_set = 0;
  60static mach_port_t  p_default_set_control = 0;
  61static host_priv_t  host_priv;
  62static natural_t    processor_count = 0;
  63static io_connect_t lightsensor_port = 0;
  64static io_connect_t motionsensor_port = 0;
  65static unsigned int sms_gIndex = 0;
  66static IOItemCount  sms_gStructureInputSize = 0;
  67static IOByteCount  sms_gStructureOutputSize = 0;
  68
  69/* camera */
  70static pthread_mutex_t  camera_lock;
  71static int              camera_busy = 0;
  72static CFMutableDataRef camera_tiff = (CFMutableDataRef)0;
  73
  74/* display */
  75static pthread_mutex_t  display_lock;
  76static int              display_busy = 0;
  77static CFMutableDataRef display_png = (CFMutableDataRef)0;
  78
  79static pcrecpp::RE *valid_process_pattern = new pcrecpp::RE("/(\\d+)");
  80
  81typedef struct {
  82    char x;
  83    char y;
  84    char z;
  85    short v;
  86#define FILLER_SIZE 60
  87    char scratch[FILLER_SIZE];
  88} MotionSensorData_t;
  89
  90static kern_return_t
  91sms_getOrientation_hardware_apple(MotionSensorData_t *odata)
  92{
  93    kern_return_t      kr;
  94    IOItemCount        isize = sms_gStructureInputSize;
  95    IOByteCount        osize = sms_gStructureOutputSize;
  96    MotionSensorData_t idata;
  97
  98    kr = IOConnectMethodStructureIStructureO(motionsensor_port,
  99                                             sms_gIndex,
 100                                             isize,
 101                                             &osize,
 102                                             &idata,
 103                                             odata);
 104    return kr;
 105}
 106
 107static int init_task_list(task_array_t           *task_list,
 108                          mach_msg_type_number_t *task_count)
 109{
 110    return processor_set_tasks(p_default_set_control, task_list, task_count);
 111}
 112
 113static void fini_task_list(task_array_t           task_list,
 114                           mach_msg_type_number_t task_count)
 115{
 116    unsigned int i;
 117    for (i = 0; i < task_count; i++) {
 118        mach_port_deallocate(mach_task_self(), task_list[i]);
 119    }
 120    vm_deallocate(mach_task_self(), (vm_address_t)task_list,
 121                  task_count * sizeof(task_t));
 122}
 123
 124static int init_thread_list(task_t                  the_task,
 125                            thread_array_t         *thread_list,
 126                            mach_msg_type_number_t *thread_count)
 127{
 128    return task_threads(the_task, thread_list, thread_count);
 129}
 130
 131static void fini_thread_list(thread_array_t         thread_list,
 132                             mach_msg_type_number_t thread_count)
 133{
 134    unsigned int i;
 135    for (i = 0; i < thread_count; i++) {
 136        mach_port_deallocate(mach_task_self(), thread_list[i]);
 137    }
 138    vm_deallocate(mach_task_self(), (vm_address_t)thread_list,
 139                  thread_count * sizeof(thread_act_t));
 140}
 141
 142static int init_port_list(task_t                  the_task,
 143                          mach_port_name_array_t *name_list,
 144                          mach_msg_type_number_t *name_count,
 145                          mach_port_type_array_t *type_list,
 146                          mach_msg_type_number_t *type_count)
 147{
 148    return mach_port_names(the_task,
 149                           name_list, name_count, type_list, type_count);
 150}
 151
 152static void fini_port_list(mach_port_name_array_t name_list,
 153                           mach_msg_type_number_t name_count,
 154                           mach_port_type_array_t type_list,
 155                           mach_msg_type_number_t type_count)
 156{
 157    vm_deallocate(mach_task_self(), (vm_address_t)name_list,
 158                  name_count * sizeof(mach_port_name_t));
 159    vm_deallocate(mach_task_self(), (vm_address_t)type_list,
 160                  type_count * sizeof(mach_port_type_t));
 161}
 162                           
 163
 164#define DECL_PORT_LIST() \
 165    mach_port_name_array_t name_list;  \
 166    mach_msg_type_number_t name_count; \
 167    mach_port_type_array_t type_list;  \
 168    mach_msg_type_number_t type_count;
 169#define INIT_PORT_LIST(the_task) \
 170    if (init_port_list(the_task, &name_list, &name_count, &type_list, &type_count) != 0) { \
 171        return -EIO; \
 172    }
 173#define FINI_PORT_LIST() \
 174    fini_port_list(name_list, name_count, type_list, type_count)
 175
 176#define DECL_TASK_LIST() \
 177    task_array_t           task_list; \
 178    mach_msg_type_number_t task_count;
 179#define INIT_TASK_LIST() \
 180    if (init_task_list(&task_list, &task_count) != 0) { return -EIO; }
 181#define FINI_TASK_LIST() \
 182    fini_task_list(task_list, task_count)
 183
 184#define DECL_THREAD_LIST() \
 185    thread_array_t         thread_list; \
 186    mach_msg_type_number_t thread_count;
 187#define INIT_THREAD_LIST(the_task) \
 188    if (init_thread_list(the_task, &thread_list, &thread_count) != 0) { \
 189        return -EIO; \
 190    }
 191#define FINI_THREAD_LIST() \
 192    fini_thread_list(thread_list, thread_count)
 193
 194struct procfs_dispatcher_entry;
 195typedef struct procfs_dispatcher_entry * procfs_dispatcher_entry_t;
 196
 197typedef int (*procfs_open_handler_t)(procfs_dispatcher_entry_t  e,
 198                                     const char                *argv[],
 199                                     const char                *path,
 200                                     struct fuse_file_info     *fi);
 201
 202typedef int (*procfs_release_handler_t)(procfs_dispatcher_entry_t  e,
 203                                        const char                *argv[],
 204                                        const char                *path,
 205                                        struct fuse_file_info     *fi);
 206typedef int (*procfs_opendir_handler_t)(procfs_dispatcher_entry_t  e,
 207                                        const char                *argv[],
 208                                        const char                *path,
 209                                        struct fuse_file_info     *fi);
 210
 211typedef int (*procfs_releasedir_handler_t)(procfs_dispatcher_entry_t  e,
 212                                           const char                *argv[],
 213                                           const char                *path,
 214                                           struct fuse_file_info     *fi);
 215
 216typedef int (*procfs_getattr_handler_t)(procfs_dispatcher_entry_t  e,
 217                                        const char                *argv[],
 218                                        struct stat               *stbuf);
 219
 220typedef int (*procfs_read_handler_t)(procfs_dispatcher_entry_t  e,
 221                                     const char                *argv[],
 222                                     char                      *buf,
 223                                     size_t                     size,
 224                                     off_t                      offset,
 225                                     struct fuse_file_info     *fi);
 226
 227typedef int (*procfs_readdir_handler_t)(procfs_dispatcher_entry_t  e,
 228                                        const char                *argv[],
 229                                        void                      *buf,
 230                                        fuse_fill_dir_t            filler,
 231                                        off_t                      offset,
 232                                        struct fuse_file_info     *fi);
 233
 234typedef int (*procfs_readlink_handler_t)(procfs_dispatcher_entry_t  e,
 235                                         const char                *argv[],
 236                                         char                      *buf,
 237                                         size_t                    size);
 238
 239typedef struct procfs_dispatcher_entry {
 240    int                         flag;
 241    char                       *pattern;
 242    pcrecpp::RE                *compiled_pattern;
 243    int                         argc;
 244    procfs_open_handler_t       open;
 245    procfs_release_handler_t    release;
 246    procfs_opendir_handler_t    opendir;
 247    procfs_releasedir_handler_t releasedir;
 248    procfs_getattr_handler_t    getattr;
 249    procfs_read_handler_t       read;
 250    procfs_readdir_handler_t    readdir;
 251    procfs_readlink_handler_t   readlink;
 252    const char                 *content_files[32];
 253    const char                 *content_directories[32];
 254};
 255
 256/* flags */
 257#define PROCFS_FLAG_ISDOTFILE 0x00000001
 258
 259#define PROCFS_MAX_ARGS       3
 260
 261#define OPEN_HANDLER(handler) \
 262int \
 263procfs_open_##handler(procfs_dispatcher_entry_t  e,      \
 264                      const char                *argv[], \
 265                      const char                *path,   \
 266                      struct fuse_file_info     *fi)     \
 267
 268#define RELEASE_HANDLER(handler) \
 269int \
 270procfs_release_##handler(procfs_dispatcher_entry_t  e,      \
 271                         const char                 *argv[], \
 272                         const char                 *path,   \
 273                         struct fuse_file_info      *fi)     \
 274
 275#define OPENDIR_HANDLER(handler) \
 276int \
 277procfs_opendir_##handler(procfs_dispatcher_entry_t  e,      \
 278                         const char                *argv[], \
 279                         const char                *path,   \
 280                         struct fuse_file_info     *fi)     \
 281
 282#define RELEASEDIR_HANDLER(handler) \
 283int \
 284procfs_releasedir_##handler(procfs_dispatcher_entry_t  e,      \
 285                            const char                 *argv[], \
 286                            const char                 *path,   \
 287                            struct fuse_file_info      *fi)     \
 288
 289#define GETATTR_HANDLER(handler) \
 290int \
 291procfs_getattr_##handler(procfs_dispatcher_entry_t  e,      \
 292                         const char                *argv[], \
 293                         struct stat               *stbuf)  \
 294
 295#define READ_HANDLER(handler) \
 296int \
 297procfs_read_##handler(procfs_dispatcher_entry_t  e,      \
 298                      const char                *argv[], \
 299                      char                      *buf,    \
 300                      size_t                     size,   \
 301                      off_t                      offset, \
 302                      struct fuse_file_info     *fi)     \
 303
 304#define READDIR_HANDLER(handler) \
 305int \
 306procfs_readdir_##handler(procfs_dispatcher_entry_t  e,      \
 307                         const char                *argv[], \
 308                         void                      *buf,    \
 309                         fuse_fill_dir_t            filler, \
 310                         off_t                      offset, \
 311                         struct fuse_file_info     *fi)     \
 312
 313#define READLINK_HANDLER(handler) \
 314int \
 315procfs_readlink_##handler(procfs_dispatcher_entry_t  e,      \
 316                          const char                *argv[], \
 317                          char                      *buf,    \
 318                          size_t                     size)   \
 319
 320#define PROTO_OPEN_HANDLER(handler)       OPEN_HANDLER(handler)
 321#define PROTO_RELEASE_HANDLER(handler)    RELEASE_HANDLER(handler)
 322#define PROTO_OPENDIR_HANDLER(handler)    OPENDIR_HANDLER(handler)
 323#define PROTO_RELEASEDIR_HANDLER(handler) RELEASEDIR_HANDLER(handler)
 324#define PROTO_READ_HANDLER(handler)       READ_HANDLER(handler)
 325#define PROTO_READDIR_HANDLER(handler)    READDIR_HANDLER(handler)
 326#define PROTO_READLINK_HANDLER(handler)   READLINK_HANDLER(handler)
 327#define PROTO_GETATTR_HANDLER(handler)    GETATTR_HANDLER(handler)
 328
 329#define DECL_FILE(pattern, argc, openp, releasep, getattrp, readp) \
 330    {                                        \
 331        0,                                   \
 332        pattern,                             \
 333        new pcrecpp::RE(pattern),            \
 334        argc,                                \
 335        procfs_open_##openp,                 \
 336        procfs_release_##releasep,           \
 337        procfs_opendir_enotdir,              \
 338        procfs_releasedir_enotdir,           \
 339        procfs_getattr_##getattrp,           \
 340        procfs_read_##readp,                 \
 341        procfs_readdir_enotdir,              \
 342        procfs_readlink_einval,              \
 343        { NULL },                            \
 344        { NULL }                             \
 345    },
 346
 347#define DECL_FILE_WITHFLAGS(flag, pattern, argc, openp, releasep, getattrp, readp) \
 348    {                                        \
 349        flag,                                \
 350        pattern,                             \
 351        new pcrecpp::RE(pattern),            \
 352        argc,                                \
 353        procfs_open_##openp,                 \
 354        procfs_release_##releasep,           \
 355        procfs_opendir_enotdir,              \
 356        procfs_releasedir_enotdir,           \
 357        procfs_getattr_##getattrp,           \
 358        procfs_read_##readp,                 \
 359        procfs_readdir_enotdir,              \
 360        procfs_readlink_einval,              \
 361        { NULL },                            \
 362        { NULL }                             \
 363    },
 364
 365#define DECL_DIRECTORY(pattern, argc, opendirp, releasedirp, getattrp, readdirp, contents, ...) \
 366    {                                        \
 367        0,                                   \
 368        pattern,                             \
 369        new pcrecpp::RE(pattern),            \
 370        argc,                                \
 371        procfs_open_eisdir,                  \
 372        procfs_release_eisdir,               \
 373        procfs_opendir_##opendirp,           \
 374        procfs_releasedir_##releasedirp,     \
 375        procfs_getattr_##getattrp,           \
 376        procfs_read_eisdir,                  \
 377        procfs_readdir_##readdirp,           \
 378        procfs_readlink_einval,              \
 379        contents,                            \
 380        __VA_ARGS__                          \
 381    },
 382
 383#define DECL_DIRECTORY_COMPACT(pattern, contents, ...) \
 384    {                                        \
 385        0,                                   \
 386        pattern,                             \
 387        new pcrecpp::RE(pattern),            \
 388        0,                                   \
 389        procfs_open_eisdir,                  \
 390        procfs_release_eisdir,               \
 391        procfs_opendir_default_directory,    \
 392        procfs_releasedir_default_directory, \
 393        procfs_getattr_default_directory,    \
 394        procfs_read_eisdir,                  \
 395        procfs_readdir_default,              \
 396        procfs_readlink_einval,              \
 397        contents,                            \
 398        ##__VA_ARGS__                        \
 399    },
 400
 401#define DECL_LINK(pattern, argc, openp, releasep, getattrp, readlinkp) \
 402    {                                        \
 403        0,                                   \
 404        pattern,                             \
 405        new pcrecpp::RE(pattern),            \
 406        argc,                                \
 407        procfs_open_##openp,                 \
 408        procfs_release_##releasep,           \
 409        procfs_opendir_enotdir,              \
 410        procfs_releasedir_enotdir,           \
 411        procfs_getattr_##getattrp,           \
 412        procfs_read_einval,                  \
 413        procfs_readdir_enotdir,              \
 414        procfs_readlink_##readlinkp,         \
 415        { NULL },                            \
 416        { NULL }                             \
 417    },
 418
 419#define DECL_LINK_COMPACT(pattern, argc, readlinkp) \
 420    {                                        \
 421        0,                                   \
 422        pattern,                             \
 423        new pcrecpp::RE(pattern),            \
 424        argc,                                \
 425        procfs_open_default_file,            \
 426        procfs_release_default_file,         \
 427        procfs_opendir_enotdir,              \
 428        procfs_releasedir_enotdir,           \
 429        procfs_getattr_default_link,         \
 430        procfs_read_einval,                  \
 431        procfs_readdir_enotdir,              \
 432        procfs_readlink_##readlinkp,         \
 433        { NULL },                            \
 434        { NULL }                             \
 435    },
 436
 437PROTO_OPEN_HANDLER(default_file);
 438PROTO_OPEN_HANDLER(eisdir);
 439PROTO_OPEN_HANDLER(proc__windows__identify);
 440PROTO_OPEN_HANDLER(proc__windows__screenshots__window);
 441PROTO_OPEN_HANDLER(system__hardware__camera__screenshot);
 442PROTO_OPEN_HANDLER(system__hardware__displays__display__screenshot);
 443
 444PROTO_RELEASE_HANDLER(default_file);
 445PROTO_RELEASE_HANDLER(eisdir);
 446PROTO_RELEASE_HANDLER(proc__windows__identify);
 447PROTO_RELEASE_HANDLER(proc__windows__screenshots__window);
 448PROTO_RELEASE_HANDLER(system__hardware__camera__screenshot);
 449PROTO_RELEASE_HANDLER(system__hardware__displays__display__screenshot);
 450
 451PROTO_OPENDIR_HANDLER(default_directory);
 452PROTO_OPENDIR_HANDLER(enotdir);
 453
 454PROTO_RELEASEDIR_HANDLER(default_directory);
 455PROTO_RELEASEDIR_HANDLER(enotdir);
 456
 457PROTO_GETATTR_HANDLER(default_file);
 458PROTO_GETATTR_HANDLER(default_file_finder_info);
 459PROTO_GETATTR_HANDLER(default_directory);
 460PROTO_GETATTR_HANDLER(default_link);
 461PROTO_GETATTR_HANDLER(byname__name);
 462PROTO_GETATTR_HANDLER(system__hardware__camera__screenshot);
 463PROTO_GETATTR_HANDLER(system__hardware__displays__display);
 464PROTO_GETATTR_HANDLER(system__hardware__displays__display__screenshot);
 465#if MACFUSE_PROCFS_ENABLE_TPM
 466PROTO_GETATTR_HANDLER(system__hardware__tpm__keyslots__slot);
 467PROTO_GETATTR_HANDLER(system__hardware__tpm__pcrs__pcr);
 468#endif /* MACFUSE_PROCFS_ENABLE_TPM */
 469PROTO_GETATTR_HANDLER(proc__task__ports__port);
 470PROTO_GETATTR_HANDLER(proc__task__threads__thread);
 471PROTO_GETATTR_HANDLER(proc__windows__screenshots__window);
 472
 473PROTO_READ_HANDLER(einval);
 474PROTO_READ_HANDLER(eisdir);
 475PROTO_READ_HANDLER(zero);
 476PROTO_READ_HANDLER(default_file_finder_info);
 477PROTO_READ_HANDLER(proc__carbon);
 478#if __i386__
 479PROTO_READ_HANDLER(proc__fds);
 480#endif /* __i386__ */
 481PROTO_READ_HANDLER(proc__generic);
 482PROTO_READ_HANDLER(proc__task__absolutetime_info);
 483PROTO_READ_HANDLER(proc__task__basic_info);
 484PROTO_READ_HANDLER(proc__task__events_info);
 485PROTO_READ_HANDLER(proc__task__thread_times_info);
 486PROTO_READ_HANDLER(proc__task__mach_name);
 487PROTO_READ_HANDLER(proc__task__ports__port);
 488PROTO_READ_HANDLER(proc__task__role);
 489PROTO_READ_HANDLER(proc__task__threads__thread__basic_info);
 490PROTO_READ_HANDLER(proc__task__threads__thread__states__debug);
 491PROTO_READ_HANDLER(proc__task__threads__thread__states__exception);
 492PROTO_READ_HANDLER(proc__task__threads__thread__states__float);
 493PROTO_READ_HANDLER(proc__task__threads__thread__states__thread);
 494PROTO_READ_HANDLER(proc__task__tokens);
 495PROTO_READ_HANDLER(proc__task__vmmap);
 496PROTO_READ_HANDLER(proc__task__vmmap_r);
 497PROTO_READ_HANDLER(proc__windows__generic);
 498PROTO_READ_HANDLER(proc__windows__screenshots__window);
 499PROTO_READ_HANDLER(proc__xcred);
 500PROTO_READ_HANDLER(system__firmware__variables);
 501PROTO_READ_HANDLER(system__hardware__camera__screenshot);
 502PROTO_READ_HANDLER(system__hardware__cpus__cpu__data);
 503PROTO_READ_HANDLER(system__hardware__displays__display__info);
 504PROTO_READ_HANDLER(system__hardware__displays__display__screenshot);
 505#if MACFUSE_PROCFS_ENABLE_TPM
 506PROTO_READ_HANDLER(system__hardware__tpm__hwmodel);
 507PROTO_READ_HANDLER(system__hardware__tpm__hwvendor);
 508PROTO_READ_HANDLER(system__hardware__tpm__hwversion);
 509PROTO_READ_HANDLER(system__hardware__tpm__keyslots__slot);
 510PROTO_READ_HANDLER(system__hardware__tpm__pcrs__pcr);
 511#endif /* MACFUSE_PROCFS_ENABLE_TPM */
 512PROTO_READ_HANDLER(system__hardware__xsensor);
 513
 514PROTO_READDIR_HANDLER(default);
 515PROTO_READDIR_HANDLER(enotdir);
 516PROTO_READDIR_HANDLER(byname);
 517PROTO_READDIR_HANDLER(proc__task__ports);
 518PROTO_READDIR_HANDLER(proc__task__threads);
 519PROTO_READDIR_HANDLER(proc__windows__screenshots);
 520PROTO_READDIR_HANDLER(root);
 521PROTO_READDIR_HANDLER(system__hardware__cpus);
 522PROTO_READDIR_HANDLER(system__hardware__cpus__cpu);
 523PROTO_READDIR_HANDLER(system__hardware__displays);
 524PROTO_READDIR_HANDLER(system__hardware__displays__display);
 525#if MACFUSE_PROCFS_ENABLE_TPM
 526PROTO_READDIR_HANDLER(system__hardware__tpm__keyslots);
 527PROTO_READDIR_HANDLER(system__hardware__tpm__pcrs);
 528#endif /* MACFUSE_PROCFS_ENABLE_TPM */
 529
 530PROTO_READLINK_HANDLER(einval);
 531PROTO_READLINK_HANDLER(byname__name);
 532
 533static struct procfs_dispatcher_entry
 534procfs_link_table[] = {
 535
 536    DECL_LINK(
 537        "/byname/(.+)",
 538        1,
 539        default_file,
 540        default_file,
 541        byname__name,
 542        byname__name
 543    )
 544};
 545
 546static struct procfs_dispatcher_entry
 547procfs_file_table[] = {
 548
 549    DECL_FILE_WITHFLAGS(
 550        PROCFS_FLAG_ISDOTFILE,
 551        "/system/.*\\._.*|/\\d+/.*\\._.*",
 552        0,
 553        default_file,
 554        default_file,
 555        default_file_finder_info,
 556        default_file_finder_info
 557    )
 558
 559    DECL_FILE(
 560        "/system/firmware/variables",
 561        0,
 562        default_file,
 563        default_file,
 564        default_file,
 565        system__firmware__variables
 566    )
 567
 568    DECL_FILE(
 569        "/system/hardware/(lightsensor|motionsensor|mouse)/data",
 570        1,
 571        default_file,
 572        default_file,
 573        default_file,
 574        system__hardware__xsensor
 575    )
 576
 577    DECL_FILE(
 578        "/system/hardware/camera/screenshot.tiff",
 579        0,
 580        system__hardware__camera__screenshot,
 581        system__hardware__camera__screenshot,
 582        system__hardware__camera__screenshot,
 583        system__hardware__camera__screenshot
 584    )
 585
 586    DECL_FILE(
 587        "/system/hardware/cpus/(\\d+)/data",
 588        1,
 589        default_file,
 590        default_file,
 591        default_file,
 592        system__hardware__cpus__cpu__data
 593    )
 594
 595    DECL_FILE(
 596        "/system/hardware/displays/(\\d+)/info",
 597        1,
 598        default_file,
 599        default_file,
 600        default_file,
 601        system__hardware__displays__display__info
 602    )
 603
 604    DECL_FILE(
 605        "/system/hardware/displays/(\\d+)/screenshot.png",
 606        1,
 607        system__hardware__displays__display__screenshot,
 608        system__hardware__displays__display__screenshot,
 609        system__hardware__displays__display__screenshot,
 610        system__hardware__displays__display__screenshot
 611    )
 612
 613#if MACFUSE_PROCFS_ENABLE_TPM
 614    DECL_FILE(
 615        "/system/hardware/tpm/hwmodel",
 616        0,
 617        default_file,
 618        default_file,
 619        default_file,
 620        system__hardware__tpm__hwmodel
 621    )
 622
 623    DECL_FILE(
 624        "/system/hardware/tpm/hwvendor",
 625        0,
 626        default_file,
 627        default_file,
 628        default_file,
 629        system__hardware__tpm__hwvendor
 630    )
 631
 632    DECL_FILE(
 633        "/system/hardware/tpm/hwversion",
 634        0,
 635        default_file,
 636        default_file,
 637        default_file,
 638        system__hardware__tpm__hwversion
 639    )
 640
 641    DECL_FILE(
 642        "/system/hardware/tpm/keyslots/key(\\d+)",
 643        1,
 644        default_file,
 645        default_file,
 646        system__hardware__tpm__keyslots__slot,
 647        system__hardware__tpm__keyslots__slot
 648    )
 649
 650    DECL_FILE(
 651        "/system/hardware/tpm/pcrs/pcr(\\d+)",
 652        1,
 653        default_file,
 654        default_file,
 655        system__hardware__tpm__pcrs__pcr,
 656        system__hardware__tpm__pcrs__pcr
 657    )
 658#endif /* MACFUSE_PROCFS_ENABLE_TPM */
 659
 660    DECL_FILE(
 661        "/(\\d+)/carbon/(name|psn)",
 662        2,
 663        default_file,
 664        default_file,
 665        default_file,
 666        proc__carbon
 667    )
 668
 669#if __i386__
 670    DECL_FILE(
 671        "/(\\d+)/fds",
 672        1,
 673        default_file,
 674        default_file,
 675        default_file,
 676        proc__fds
 677    )
 678#endif /* __i386__ */
 679
 680    DECL_FILE(
 681        "/(\\d+)/(cmdline|jobc|paddr|pgid|ppid|tdev|tpgid|wchan)",
 682        2,
 683        default_file,
 684        default_file,
 685        default_file,
 686        proc__generic
 687    )
 688
 689    DECL_FILE(
 690        "/(\\d+)/task/absolutetime_info/(threads_system|threads_user|total_system|total_user)",
 691        2,
 692        default_file,
 693        default_file,
 694        default_file,
 695        proc__task__absolutetime_info
 696    )
 697
 698    DECL_FILE(
 699        "/(\\d+)/task/basic_info/(policy|resident_size|suspend_count|system_time|user_time|virtual_size)",
 700        2,
 701        default_file,
 702        default_file,
 703        default_file,
 704        proc__task__basic_info
 705    )
 706
 707    DECL_FILE(
 708        "/(\\d+)/task/events_info/(cow_faults|csw|faults|messages_received|messages_sent|pageins|syscalls_mach|syscalls_unix)",
 709        2,
 710        default_file,
 711        default_file,
 712        default_file,
 713        proc__task__events_info
 714    )
 715
 716    DECL_FILE(
 717        "/(\\d+)/task/thread_times_info/(system_time|user_time)",
 718        2,
 719        default_file,
 720        default_file,
 721        default_file,
 722        proc__task__thread_times_info
 723    )
 724
 725    DECL_FILE(
 726        "/(\\d+)/task/mach_name",
 727        1,
 728        default_file,
 729        default_file,
 730        default_file,
 731        proc__task__mach_name
 732    )
 733
 734    DECL_FILE(
 735        "/(\\d+)/task/ports/([a-f\\d]+)/(msgcount|qlimit|seqno|sorights|task_rights)",
 736        3,
 737        default_file,
 738        default_file,
 739        default_file,
 740        proc__task__ports__port
 741    )
 742
 743    DECL_FILE(
 744        "/(\\d+)/task/role",
 745        1,
 746        default_file,
 747        default_file,
 748        default_file,
 749        proc__task__role
 750    )
 751
 752    DECL_FILE(
 753        "/(\\d+)/task/threads/([a-f\\d]+)/basic_info/(cpu_usage|flags|policy|run_state|sleep_time|suspend_count|system_time|user_time)",
 754        3,
 755        default_file,
 756        default_file,
 757        default_file,
 758        proc__task__threads__thread__basic_info
 759    )
 760
 761    DECL_FILE(
 762        "/(\\d+)/task/threads/([a-f\\d]+)/states/debug/(dr[0-7])",
 763        3,
 764        default_file,
 765        default_file,
 766        default_file,
 767        proc__task__threads__thread__states__debug
 768    )
 769
 770    DECL_FILE(
 771        "/(\\d+)/task/threads/([a-f\\d]+)/states/exception/(err|faultvaddr|trapno)",
 772        3,
 773        default_file,
 774        default_file,
 775        default_file,
 776        proc__task__threads__thread__states__exception
 777    )
 778
 779    DECL_FILE(
 780        "/(\\d+)/task/threads/([a-f\\d]+)/states/float/(fpu_fcw|fpu_fsw|fpu_ftw|fpu_fop|fpu_ip|fpu_cs|fpu_dp|fpu_ds|fpu_mxcsr|fpu_mxcsrmask)",
 781        3,
 782        default_file,
 783        default_file,
 784        default_file,
 785        proc__task__threads__thread__states__float
 786    )
 787
 788    DECL_FILE(
 789        "/(\\d+)/task/threads/([a-f\\d]+)/states/thread/(e[a-d]x|edi|esi|ebp|esp|ss|eflags|eip|[cdefg]s)",
 790        3,
 791        default_file,
 792        default_file,
 793        default_file,
 794        proc__task__threads__thread__states__thread
 795    )
 796
 797    DECL_FILE(
 798        "/(\\d+)/task/tokens/(audit|security)",
 799        2,
 800        default_file,
 801        default_file,
 802        default_file,
 803        proc__task__tokens
 804    )
 805
 806    DECL_FILE(
 807        "/(\\d+)/task/vmmap",
 808        1,
 809        default_file,
 810        default_file,
 811        default_file,
 812        proc__task__vmmap
 813    )
 814
 815    DECL_FILE(
 816        "/(\\d+)/task/vmmap_r",
 817        1,
 818        default_file,
 819        default_file,
 820        default_file,
 821        proc__task__vmmap_r
 822    )
 823
 824    DECL_FILE(
 825        "/(\\d+)/windows/(all|onscreen)",
 826        2,
 827        default_file,
 828        default_file,
 829        default_file,
 830        proc__windows__generic
 831    )
 832
 833    DECL_FILE(
 834        "/(\\d+)/windows/identify",
 835        1,
 836        proc__windows__identify,
 837        proc__windows__identify,
 838        default_file,
 839        zero
 840    )
 841
 842    DECL_FILE(
 843        "/(\\d+)/windows/screenshots/([a-f\\d]+).png",
 844        2,
 845        proc__windows__screenshots__window, 
 846        proc__windows__screenshots__window, 
 847        proc__windows__screenshots__window,
 848        proc__windows__screenshots__window
 849    )
 850
 851    DECL_FILE(
 852        "/(\\d+)/(ucred|pcred)/(groups|rgid|ruid|svgid|svuid|uid)",
 853        3,
 854        default_file,
 855        default_file,
 856        default_file,
 857        proc__xcred
 858    )
 859};
 860
 861static struct procfs_dispatcher_entry
 862procfs_directory_table[] = {
 863    DECL_DIRECTORY(
 864        "/",
 865        0,
 866        default_directory,
 867        default_directory,
 868        default_directory,
 869        root,
 870        { NULL },
 871        { "byname", "system", NULL }
 872    )
 873
 874    DECL_DIRECTORY(
 875        "/byname",
 876        0,
 877        default_directory,
 878        default_directory,
 879        default_directory,
 880        byname,
 881        { NULL },
 882        { NULL }
 883    )
 884
 885    DECL_DIRECTORY_COMPACT(
 886        "/system",
 887        { NULL },
 888        { "firmware", "hardware", NULL },
 889    )
 890
 891    DECL_DIRECTORY_COMPACT(
 892        "/system/firmware",
 893        { "variables", NULL },
 894        { NULL }
 895    )
 896
 897    DECL_DIRECTORY_COMPACT(
 898        "/system/hardware",
 899        { NULL },
 900#if MACFUSE_PROCFS_ENABLE_TPM
 901        {
 902            "camera", "cpus", "displays", "lightsensor", "motionsensor",
 903             "mouse", "tpm", NULL
 904        }
 905#else
 906        {
 907            "camera", "cpus", "displays", "lightsensor", "motionsensor",
 908            "mouse", NULL
 909        }
 910#endif /* MACFUSE_PROCFS_ENABLE_TPM */
 911    )
 912
 913    DECL_DIRECTORY_COMPACT(
 914        "/system/hardware/camera",
 915        { "screenshot.tiff", NULL },
 916        { NULL },
 917    )
 918
 919    DECL_DIRECTORY(
 920        "/system/hardware/cpus",
 921        0,
 922        default_directory,
 923        default_directory,
 924        default_directory,
 925        system__hardware__cpus,
 926        { NULL },
 927        { NULL },
 928    )
 929
 930    DECL_DIRECTORY(
 931        "/system/hardware/cpus/(\\d+)",
 932        1,
 933        default_directory,
 934        default_directory,
 935        default_directory,
 936        system__hardware__cpus__cpu,
 937        { "data", NULL },
 938        { NULL },
 939    )
 940
 941    DECL_DIRECTORY(
 942        "/system/hardware/displays",
 943        0,
 944        default_directory,
 945        default_directory,
 946        default_directory,
 947        system__hardware__displays,
 948        { NULL },
 949        { NULL },
 950    )
 951
 952    DECL_DIRECTORY(
 953        "/system/hardware/displays/(\\d+)",
 954        1,
 955        default_directory,
 956        default_directory,
 957        system__hardware__displays__display,
 958        system__hardware__displays__display,
 959        { "info", "screenshot.png", NULL },
 960        { NULL },
 961    )
 962
 963    DECL_DIRECTORY_COMPACT(
 964        "/system/hardware/lightsensor",
 965        { "data", NULL },
 966        { NULL },
 967    )
 968
 969    DECL_DIRECTORY_COMPACT(
 970        "/system/hardware/motionsensor",
 971        { "data", NULL },
 972        { NULL },
 973    )
 974
 975    DECL_DIRECTORY_COMPACT(
 976        "/system/hardware/mouse",
 977        { "data", NULL },
 978        { NULL },
 979    )
 980
 981#if MACFUSE_PROCFS_ENABLE_TPM
 982    DECL_DIRECTORY_COMPACT(
 983        "/system/hardware/tpm",
 984        { "hwmodel", "hwvendor", "hwversion", NULL },
 985        { "keyslots", "pcrs" }
 986    )
 987
 988    DECL_DIRECTORY(
 989        "/system/hardware/tpm/keyslots",
 990        0,
 991        default_directory,
 992        default_directory,
 993        default_directory,
 994        system__hardware__tpm__keyslots,
 995        { NULL },
 996        { NULL },
 997    )
 998
 999    DECL_DIRECTORY(
1000        "/system/hardware/tpm/pcrs",
1001        0,
1002        default_directory,
1003        default_directory,
1004        default_directory,
1005        system__hardware__tpm__pcrs,
1006        { NULL },
1007        { NULL },
1008    )
1009#endif /* MACFUSE_PROCFS_ENABLE_TPM */
1010
1011    DECL_DIRECTORY_COMPACT(
1012        "/\\d+",
1013        {
1014            "cmdline",
1015#if __i386__
1016            "fds",
1017#endif /* __i386__ */
1018            "jobc", "paddr", "pgid", "ppid", "tdev", "tpgid",
1019            "wchan", "windows", NULL
1020        },
1021        { "carbon", "pcred", "task", "ucred", NULL }
1022    )
1023
1024    DECL_DIRECTORY_COMPACT(
1025        "/\\d+/carbon",
1026        { "name", "psn", NULL },
1027        { NULL }
1028    )
1029
1030    DECL_DIRECTORY_COMPACT(
1031        "/\\d+/pcred",
1032        { "rgid", "ruid", "svgid", "svgid", NULL },
1033        { NULL }
1034    )
1035
1036    DECL_DIRECTORY_COMPACT(
1037        "/\\d+/task",
1038        { "mach_name", "role", "vmmap", "vmmap_r", NULL },
1039        {
1040            "absolutetime_info", "basic_info", "events_info", "ports",
1041            "thread_times_info", "threads", "tokens", NULL
1042        }
1043    )
1044
1045    DECL_DIRECTORY_COMPACT(
1046        "/\\d+/task/absolutetime_info",
1047        {
1048            "threads_system", "threads_user", "total_system",
1049            "total_user", NULL
1050        },
1051        { NULL }
1052    )
1053
1054    DECL_DIRECTORY_COMPACT(
1055        "/\\d+/task/basic_info",
1056        {
1057            "policy", "resident_size", "suspend_count", "system_time",
1058            "user_time", "virtual_size", NULL
1059        },
1060        { NULL }
1061    )
1062
1063    DECL_DIRECTORY_COMPACT(
1064        "/\\d+/task/events_info",
1065        {
1066            "cow_faults", "csw", "faults", "messages_received",
1067            "messages_sent", "pageins", "syscalls_mach", "syscalls_unix", NULL
1068        },
1069        { NULL }
1070    )
1071
1072    DECL_DIRECTORY(
1073        "/(\\d+)/task/ports",
1074        1,
1075        default_directory,
1076        default_directory,
1077        default_directory,
1078        proc__task__ports,
1079        { NULL },
1080        { NULL }
1081    )
1082
1083    DECL_DIRECTORY(
1084        "/(\\d+)/task/ports/([a-f\\d]+)",
1085        2,
1086        default_directory,
1087        default_directory,
1088        proc__task__ports__port,
1089        default,
1090        { "msgcount", "qlimit", "seqno", "sorights", "task_rights", NULL },
1091        { NULL }
1092    )
1093
1094    DECL_DIRECTORY_COMPACT(
1095        "/\\d+/task/thread_times_info",
1096        { "system_time", "user_time", NULL },
1097        { NULL }
1098    )
1099
1100    DECL_DIRECTORY(
1101        "/(\\d+)/task/threads",
1102        1,
1103        default_directory,
1104        default_directory,
1105        default_directory,
1106        proc__task__threads,
1107        { NULL },
1108        { NULL }
1109    )
1110
1111    DECL_DIRECTORY(
1112        "/(\\d+)/task/threads/([a-f\\d])+",
1113        2,
1114        default_directory,
1115        default_directory,
1116        proc__task__threads__thread,
1117        default,
1118        { NULL },
1119        { "basic_info", "states", NULL }
1120    )
1121
1122    DECL_DIRECTORY_COMPACT(
1123        "/\\d+/task/threads/[a-f\\d]+/basic_info",
1124        {
1125            "cpu_usage", "flags", "policy", "run_state", "sleep_time",
1126            "suspend_count", "system_time", "user_time", NULL
1127        },
1128        { NULL }
1129    )
1130
1131    DECL_DIRECTORY_COMPACT(
1132        "/\\d+/task/threads/[a-f\\d]+/states",
1133        { "debug", "exception", "float", "thread", NULL },
1134        { NULL }
1135    )
1136
1137    DECL_DIRECTORY_COMPACT(
1138        "/\\d+/task/threads/[a-f\\d]+/states/debug",
1139        { "dr0", "dr1", "dr2", "dr3", "dr4", "dr5", "dr6", "dr7", NULL },
1140        { NULL }
1141    )
1142
1143    DECL_DIRECTORY_COMPACT(
1144        "/\\d+/task/threads/[a-f\\d]+/states/exception",
1145        { "err", "faultvaddr", "trapno", NULL },
1146        { NULL }
1147    )
1148
1149    DECL_DIRECTORY_COMPACT(
1150        "/\\d+/task/threads/[a-f\\d]+/states/float",
1151        {
1152            "fpu_cs", "fpu_dp", "fpu_ds", "fpu_fcw", "fpu_fop", "fpu_fsw",
1153            "fpu_ftw", "fpu_ip", "fpu_mxcsr", "fpu_mxcsrmask", NULL
1154        },
1155        { NULL }
1156    )
1157
1158    DECL_DIRECTORY_COMPACT(
1159        "/\\d+/task/threads/[a-f\\d]+/states/thread",
1160        {
1161            "eax", "ebx", "ecx", "edx", "edi", "esi", "ebp", "esp", "ss",
1162            "eflags", "eip", "cs", "ds", "es", "fs", "gs", NULL
1163        },
1164        { NULL }
1165    )
1166
1167    DECL_DIRECTORY_COMPACT(
1168        "/\\d+/task/tokens",
1169        { "audit", "security", NULL },
1170        { NULL }
1171    )
1172
1173    DECL_DIRECTORY_COMPACT(
1174        "/\\d+/ucred",
1175        { "groups", "uid", NULL },
1176        { NULL }
1177    )
1178
1179    DECL_DIRECTORY_COMPACT(
1180        "/\\d+/windows",
1181        { "all", "onscreen", "identify", NULL },
1182        { "screenshots", NULL }
1183    )
1184
1185    DECL_DIRECTORY(
1186        "/(\\d+)/windows/screenshots",
1187        1,
1188        default_directory,
1189        default_directory,
1190        default_directory,
1191        proc__windows__screenshots,
1192        { NULL },
1193        { NULL },
1194    )
1195
1196};
1197
1198// BEGIN: OPEN/OPENDIR
1199
1200//
1201// int
1202// procfs_open/opendir_<handler>(procfs_dispatcher_entry_t  e,
1203//                               const char                *argv[],
1204//                               const char                *path,
1205//                               struct fuse_file_info     *fi)
1206
1207OPEN_HANDLER(default_file)
1208{
1209    return 0;
1210}
1211
1212OPEN_HANDLER(eisdir)
1213{
1214    return -EISDIR;
1215}
1216
1217OPEN_HANDLER(proc__windows__identify)
1218{
1219    if (fi->fh != 0) { /* XXX: need locking */
1220        return 0;
1221    } else {
1222        fi->fh = 1;
1223    }
1224    char *whandler = NULL;
1225    if ((whandler = getenv("MACFUSE_PROCFS_WHANDLER")) == NULL) {
1226        goto bail;
1227    }
1228    int npid = vfork();
1229    if (npid == 0) {
1230        execl(whandler, whandler, argv[0], NULL);
1231        return 0;
1232    }
1233
1234bail:
1235    return 0;
1236}
1237
1238OPEN_HANDLER(proc__windows__screenshots__window)
1239{
1240    if (fi->fh != 0) { /* XXX: need locking */
1241        return 0;
1242    }
1243
1244    pid_t pid = strtol(argv[0], NULL, 10);
1245    CGWindowID target = strtol(argv[1], NULL, 16);
1246    ProcessSerialNumber psn;
1247
1248    OSStatus status = GetProcessForPID(pid, &psn);
1249    if (status != noErr) {
1250        return -ENOENT;
1251    }
1252
1253    CGSConnectionID conn;
1254    CGError err = CGSGetConnectionIDForPSN(0, &psn, &conn);
1255    if (err != kCGErrorSuccess) {
1256        return -ENOENT;
1257    }
1258
1259#define MAX_WINDOWS 256
1260    CGSWindowID windowIDs[MAX_WINDOWS];
1261    int windowCount = 0;
1262    int i = 0;
1263
1264    err = CGSGetWindowList(_CGSDefaultConnection(), conn, MAX_WINDOWS,
1265                           windowIDs, &windowCount);
1266
1267    for (i = 0; i < windowCount; i++) {
1268        if (windowIDs[i] == target) {
1269            goto doread;
1270        }
1271    }
1272
1273    return -ENOENT;
1274
1275doread:
1276
1277    CFMutableDataRef window_png = (CFMutableDataRef)0;
1278    int ret = PROCFS_GetPNGForWindowAtIndex(target, &window_png);
1279
1280    if (ret == -1) {
1281        return -EIO;
1282    }
1283
1284    struct ProcfsWindowData *pwd =
1285        (struct ProcfsWindowData *)malloc(sizeof(struct ProcfsWindowData));
1286    if (!pwd) {
1287        CFRelease(window_png);
1288        return -ENOMEM;
1289    }
1290
1291    pwd->window_png = window_png;
1292    pwd->max_len = PROCFS_GetPNGSizeForWindowAtIndex(target);
1293    pwd->len = (size_t)CFDataGetLength(window_png);
1294
1295    fi->fh = (uint64_t)pwd;
1296
1297    return 0;
1298}
1299
1300OPEN_HANDLER(system__hardware__camera__screenshot)
1301{
1302    pthread_mutex_lock(&camera_lock);
1303    if (camera_busy) {
1304        pthread_mutex_unlock(&camera_lock);
1305        return -EBUSY;
1306    } else {
1307        camera_busy = 1;
1308        pthread_mutex_unlock(&camera_lock);
1309    }
1310
1311    int ret = PROCFS_GetTIFFFromCamera(&camera_tiff);
1312
1313    return ret;
1314}
1315
1316OPEN_HANDLER(system__hardware__displays__display__screenshot)
1317{
1318    pthread_mutex_lock(&display_lock);
1319    if (display_busy) {
1320        pthread_mutex_unlock(&display_lock);
1321        return -EBUSY;
1322    } else {
1323        display_busy = 1;
1324        pthread_mutex_unlock(&display_lock);
1325    }
1326
1327    unsigned long index = strtol(argv[0], NULL, 10);
1328    CGDisplayCount display_count = PROCFS_GetDisplayCount();
1329
1330    if (index >= display_count) {
1331        return -ENOENT;
1332    }
1333
1334    if (display_png) {
1335        CFRelease(display_png);
1336        display_png = (CFMutableDataRef)0;
1337    }
1338
1339    int ret = PROCFS_GetPNGForDisplayAtIndex(index, &display_png);
1340    if (ret) {
1341        if (display_png) {
1342            CFRelease(display_png);
1343            display_png = (CFMutableDataRef)0;
1344        }
1345        return -EIO;
1346    }
1347
1348    return 0;
1349}
1350
1351OPENDIR_HANDLER(default_directory)
1352{
1353    return 0;
1354}
1355
1356OPENDIR_HANDLER(enotdir)
1357{
1358    return -ENOTDIR;
1359}
1360
1361// END: OPEN/OPENDIR
1362
1363
1364// BEGIN: RELEASE/RELEASEDIR
1365
1366//
1367// int
1368// procfs_release/releasedir_<handler>(procfs_dispatcher_entry_t  e,
1369//                                     const char                *argv[],
1370//                                     const char                *path,
1371//                                     struct fuse_file_info     *fi)
1372
1373RELEASE_HANDLER(default_file)
1374{
1375    return 0;
1376}
1377
1378RELEASE_HANDLER(eisdir)
1379{
1380    return -EISDIR;
1381}
1382
1383RELEASE_HANDLER(proc__windows__identify)
1384{
1385    fi->fh = 0;
1386
1387    return 0;
1388}
1389
1390RELEASE_HANDLER(proc__windows__screenshots__window)
1391{ 
1392    if (fi->fh) {
1393        struct ProcfsWindowData *pwd = (struct ProcfsWindowData *)(fi->fh);
1394        CFRelease((CFMutableDataRef)(pwd->window_png));
1395        free((void *)pwd);
1396        fi->fh = 0;
1397    }
1398
1399    return 0;
1400}
1401
1402RELEASE_HANDLER(system__hardware__camera__screenshot)
1403{
1404    pthread_mutex_lock(&camera_lock);
1405    camera_busy = 0;
1406    pthread_mutex_unlock(&camera_lock);
1407
1408    return 0;
1409}
1410
1411RELEASE_HANDLER(system__hardware__displays__display__screenshot)
1412{
1413    pthread_mutex_lock(&display_lock);
1414    display_busy = 0;
1415    if (display_png) {
1416        CFRelease(display_png);
1417        display_png = (CFMutableDataRef)0;
1418    }
1419    pthread_mutex_unlock(&display_lock);
1420
1421    return 0;
1422}
1423
1424RELEASEDIR_HANDLER(default_directory)
1425{
1426    return 0;
1427}
1428
1429RELEASEDIR_HANDLER(enotdir)
1430{
1431    return -ENOTDIR;
1432}
1433
1434// END: RELEASE/RELEASEDIR
1435
1436
1437// BEGIN: GETATTR
1438
1439//
1440//  int
1441//  procfs_getattr_<handler>(procfs_dispatcher_entry_t  e,
1442//                           const char                *argv[],
1443//                           struct stat               *stbuf)
1444                          
1445
1446GETATTR_HANDLER(default_file)
1447{                         
1448    time_t current_time = time(NULL);
1449    stbuf->st_mode = S_IFREG | 0444;             
1450    stbuf->st_nlink = 1;  
1451    stbuf->st_size = 0;
1452    if (procfs_ui) {
1453        stbuf->st_size = PROCFS_DEFAULT_FILE_SIZE;
1454    }
1455    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1456
1457    return 0;
1458}   
1459
1460GETATTR_HANDLER(default_file_finder_info)
1461{
1462    if (!procfs_ui) {
1463        return -ENOENT;
1464    }
1465
1466    time_t current_time = time(NULL);
1467    stbuf->st_mode = S_IFREG | 0444;             
1468    stbuf->st_nlink = 1;  
1469    stbuf->st_size = 82;
1470    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1471
1472    return 0;
1473}
1474    
1475GETATTR_HANDLER(default_directory)
1476{
1477    time_t current_time = time(NULL);
1478
1479    stbuf->st_mode = S_IFDIR | 0555;
1480    stbuf->st_nlink = 1;
1481    stbuf->st_size = 0;
1482    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1483    
1484    return 0;
1485}
1486
1487GETATTR_HANDLER(default_link)
1488{
1489    stbuf->st_mode = S_IFLNK | 0755;
1490    stbuf->st_nlink = 1;
1491    stbuf->st_size = 0;
1492    
1493    return 0;
1494}
1495
1496GETATTR_HANDLER(byname__name)
1497{
1498    const char *target_Pname = argv[0];
1499    struct stat the_stat;
1500    char the_name[MAXNAMLEN + 1];  
1501    Boolean strstatus = false;
1502
1503    ProcessSerialNumber psn;
1504    OSErr osErr = noErr;
1505    OSStatus status;
1506    CFStringRef Pname;
1507    pid_t Pid;
1508
1509    psn.highLongOfPSN = kNoProcess;
1510    psn.lowLongOfPSN  = kNoProcess;
1511
1512    while ((osErr = GetNextProcess(&psn)) != procNotFound) {
1513        status = GetProcessPID(&psn, &Pid);
1514        if (status != noErr) {
1515            continue;
1516        }
1517        Pname = (CFStringRef)0;
1518        status = CopyProcessName(&psn, &Pname);
1519        if (status != noErr) {
1520            if (Pname) {
1521                CFRelease(Pname);
1522                Pname = (CFStringRef)0;
1523            }
1524            continue;
1525        }
1526
1527        strstatus = CFStringGetCString(Pname, the_name, MAXNAMLEN,
1528                                       kCFStringEncodingASCII);
1529        if (strstatus != true) {
1530            Pid = 0;
1531        } else if (strcmp(target_Pname, the_name) != 0) {
1532            Pid = 0;
1533        }
1534
1535        CFRelease(Pname);
1536        Pname = (CFStringRef)0;
1537
1538        if (Pid) {
1539            break;
1540        }
1541    }
1542
1543    if (!Pid) {
1544        return -ENOENT;
1545    }
1546
1547    time_t current_time = time(NULL);
1548    stbuf->st_mode = S_IFLNK | 0755;
1549    stbuf->st_nlink = 1;
1550    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1551    int len = snprintf(the_name, MAXNAMLEN, "../%u", Pid);
1552    the_stat.st_size = len;
1553
1554    return 0;
1555}
1556
1557GETATTR_HANDLER(system__hardware__displays__display)
1558{
1559    unsigned long index = strtol(argv[0], NULL, 10);
1560    CGDisplayCount display_count = PROCFS_GetDisplayCount();
1561
1562    if (index >= display_count) {
1563        return -ENOENT;
1564    }
1565
1566    time_t current_time = time(NULL);
1567
1568    stbuf->st_mode = S_IFDIR | 0555;
1569    stbuf->st_nlink = 1;
1570    stbuf->st_size = 0;
1571    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1572    
1573    return 0;
1574}
1575
1576GETATTR_HANDLER(system__hardware__camera__screenshot)
1577{
1578    time_t current_time = time(NULL);
1579
1580    stbuf->st_mode = S_IFREG | 0444;
1581    stbuf->st_nlink = 1;
1582    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1583    stbuf->st_size = PROCFS_GetTIFFSizeFromCamera();
1584
1585    return 0;
1586}
1587
1588GETATTR_HANDLER(system__hardware__displays__display__screenshot)
1589{
1590    unsigned long index = strtol(argv[0], NULL, 10);
1591
1592    time_t current_time = time(NULL);
1593
1594    stbuf->st_mode = S_IFREG | 0444;
1595    stbuf->st_nlink = 1;
1596    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1597    stbuf->st_size = PROCFS_GetPNGSizeForDisplayAtIndex(index);
1598
1599    return 0;
1600}
1601
1602#if MACFUSE_PROCFS_ENABLE_TPM
1603GETATTR_HANDLER(system__hardware__tpm__keyslots__slot)
1604{
1605    uint32_t keys[256];
1606    unsigned long slotno = strtol(argv[0], NULL, 10);
1607
1608    uint16_t slots_used = 0;
1609    uint32_t slots_free = 0;
1610    uint32_t slots_total = 0;
1611
1612    if (TPM_GetCapability_Slots(&slots_free)) {
1613        return -ENOENT;
1614    }
1615
1616    if (TPM_GetCapability_Key_Handle(&slots_used, keys)) {
1617        return -ENOENT;
1618    }
1619
1620    slots_total = slots_used + slots_free;
1621
1622    if (slotno >= slots_total) {
1623        return -ENOENT;
1624    }
1625
1626    time_t current_time = time(NULL);
1627    stbuf->st_nlink = 1;
1628    stbuf->st_size = 9;
1629    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1630
1631    if (slotno >= slots_used) {
1632        stbuf->st_mode = S_IFREG | 0000;
1633    } else {
1634        stbuf->st_mode = S_IFREG | 0444;
1635    }
1636
1637    return 0;
1638}
1639
1640GETATTR_HANDLER(system__hardware__tpm__pcrs__pcr)
1641{
1642    time_t current_time = time(NULL);
1643    stbuf->st_mode = S_IFREG | 0444;
1644    stbuf->st_nlink = 1;
1645    stbuf->st_size = 60;
1646    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1647
1648    return 0;
1649}  
1650#endif /* MACFUSE_PROCFS_ENABLE_TPM */
1651
1652GETATTR_HANDLER(proc__task__ports__port)
1653{
1654    kern_return_t kr;
1655    task_t the_task = MACH_PORT_NULL;
1656    pid_t pid = strtol(argv[0], NULL, 10);
1657
1658    kr = task_for_pid(mach_task_self(), pid, &the_task);
1659    if (kr != KERN_SUCCESS) {
1660        return -ENOENT;
1661    }
1662
1663    DECL_PORT_LIST();
1664    INIT_PORT_LIST(the_task);
1665
1666    int found = 0;
1667    unsigned int i;
1668    unsigned int the_port_name = strtoul(argv[1], NULL, 16);
1669
1670    for (i = 0; i < name_count; i++) {
1671        if (the_port_name == name_list[i]) {
1672            found = 1;
1673            break;
1674        }
1675    }
1676
1677    FINI_PORT_LIST();
1678
1679    if (the_task != MACH_PORT_NULL) {
1680        mach_port_deallocate(mach_task_self(), the_task);
1681    }
1682
1683    if (!found) {
1684        return -ENOENT;
1685    }
1686
1687    time_t current_time = time(NULL);
1688
1689    stbuf->st_mode = S_IFDIR | 0555;
1690    stbuf->st_nlink = 1;
1691    stbuf->st_size = 0;
1692    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1693    
1694    return 0;
1695}
1696
1697GETATTR_HANDLER(proc__task__threads__thread)
1698{
1699    kern_return_t kr;
1700    task_t the_task = MACH_PORT_NULL;
1701    pid_t pid = strtol(argv[0], NULL, 10);
1702
1703    kr = task_for_pid(mach_task_self(), pid, &the_task);
1704    if (kr != KERN_SUCCESS) {
1705        return -ENOENT;
1706    }
1707
1708    DECL_THREAD_LIST();
1709    INIT_THREAD_LIST(the_task);
1710    FINI_THREAD_LIST();
1711
1712    if (the_task != MACH_PORT_NULL) {
1713        mach_port_deallocate(mach_task_self(), the_task);
1714    }
1715
1716    unsigned int the_thread_name = strtoul(argv[1], NULL, 16);
1717    if (the_thread_name >= thread_count) {
1718        return -ENOENT;
1719    }
1720
1721    time_t current_time = time(NULL);
1722
1723    stbuf->st_mode = S_IFDIR | 0555;
1724    stbuf->st_nlink = 1;
1725    stbuf->st_size = 0;
1726    stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1727    
1728    return 0;
1729}
1730
1731GETATTR_HANDLER(proc__windows__screenshots__window)
1732{
1733    pid_t pid = strtol(argv[0], NULL, 10);
1734    CGWindowID target = strtol(argv[1], NULL, 16);
1735    ProcessSerialNumber psn;
1736
1737    OSStatus status = GetProcessForPID(pid, &psn);
1738    if (status != noErr) {
1739        return 0; /* technically not an error in this case */
1740    }
1741
1742    CGSConnectionID conn;
1743    CGError err = CGSGetConnectionIDForPSN(0, &psn, &conn);
1744    if (err != kCGErrorSuccess) {
1745        return 0; /* just be nice */
1746    }
1747
1748#define MAX_WINDOWS 256
1749    CGSWindowID windowIDs[MAX_WINDOWS];
1750    int windowCount = 0;
1751    int i = 0;
1752
1753    err = CGSGetWindowList(_CGSDefaultConnection(), conn, MAX_WINDOWS,
1754                           windowIDs, &windowCount);
1755
1756    for (i = 0; i < windowCount; i++) {
1757        if (windowIDs[i] == target) {
1758            time_t current_time = time(NULL);
1759
1760            stbuf->st_mode = S_IFREG | 0444;
1761            stbuf->st_nlink = 1;
1762            stbuf->st_atime = stbuf->st_ctime = stbuf->st_mtime = current_time;
1763            stbuf->st_size = PROCFS_GetPNGSizeForWindowAtIndex(windowIDs[i]);
1764            return 0;
1765        }
1766    }
1767
1768    return -ENOENT;
1769}
1770
1771// END: GETATTR
1772
1773
1774#include <stdio.h>
1775#include <stdlib.h>
1776#include <string.h>
1777#include <libgen.h>
1778#include <sys/sysctl.h>
1779
1780int
1781procinfo(pid_t pid, struct kinfo_proc *kp)
1782{
1783    int mib[4];
1784    size_t bufsize = 0, orig_bufsize = 0;
1785    struct kinfo_proc *kprocbuf;
1786    int retry_count = 0;
1787    int local_error;
1788
1789    mib[0] = CTL_KERN;
1790    mib[1] = KERN_PROC;
1791    mib[2] = KERN_PROC_PID;
1792    mib[3] = pid;
1793
1794    kprocbuf = kp;
1795    orig_bufsize = bufsize = sizeof(struct kinfo_proc);
1796    for (retry_count = 0; ; retry_count++) {
1797        local_error = 0;
1798        bufsize = orig_bufsize;
1799        if ((local_error = sysctl(mib, 4, kp, &bufsize, NULL, 0)) < 0) {
1800            if (retry_count < 1000) {
1801                sleep(1);
1802                continue;
1803            }
1804            return local_error;
1805        } else if (local_error == 0) {
1806            br

Large files files are truncated, but you can click here to view the full file