/*
* Given a directory, subscribe to Node Monitor
* messages on it and all it's descendents.
* For all directories, use B_WATCH_DIRECTORY.
* For all file, use B_WATCH_STAT.
* It also watches the directory itself
* with B_WATCH_DIRECOTRY.
*/
void
App::recursive_watch(BDirectory *dir)
{
  status_t err;

  BEntry entry;
  err = dir->GetNextEntry(&entry);

  //for each file in the current directory
  while(err == B_OK)
  {
    //put this file in global list
    this->track_file(&entry);
    BFile file = BFile(&entry,B_READ_ONLY);
    if(file.IsDirectory())
    {
      watch_entry(&entry,B_WATCH_DIRECTORY);
      BDirectory *ndir = new BDirectory(&entry);
      this->recursive_watch(ndir);
      delete ndir;
    }
    else
    {
      watch_entry(&entry,B_WATCH_STAT);
    }

    err = dir->GetNextEntry(&entry);
  }
}
/*
* Given a local directory, do the equivalent of `rm -rf`
* on it, but using the actual filesystem API.
* You can't just use dir->Remove() because that
* gives an error if the directory is not empty.
*/
void
rm_rf(BDirectory *dir)
{
  status_t err;
  BEntry entry;
  err = dir->GetNextEntry(&entry);
  while(err==B_OK)
  {
    BFile file = BFile(&entry, B_READ_ONLY);
    if(file.IsDirectory())
    {
      BDirectory ndir = BDirectory(&entry);
      rm_rf(&ndir);
    }

    err = entry.Remove();
    if(err != B_OK)
    {
      BPath path;
      entry.GetPath(&path);
      printf("Remove Error: %s on %s\n",strerror(err),path.Path());
      //what to do if I can't remove something?
    }

    err = dir->GetNextEntry(&entry);
  }
  err = dir->GetEntry(&entry);
  err = entry.Remove();
  if(err != B_OK)
    printf("Folder Removal Error: %s\n", strerror(err));
}
Ejemplo n.º 3
0
status_t
CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir)
{
    if (ref == NULL)
        return B_BAD_VALUE;

    BNode typeNode;

    BFile file;
    status_t status = file.SetTo(ref, B_READ_ONLY);
    if (status < B_OK)
        return status;

    bool isDir = file.IsDirectory();
    if (_entryIsDir != NULL)
        *_entryIsDir = isDir;

    if (isDir)
        return B_OK;

    BAppFileInfo appInfo(&file);
    status = appInfo.InitCheck();
    if (status < B_OK)
        return status;

    // Read the app sig (which consequently keeps us from updating
    // non-applications, since we get an error if the file has no
    // app sig)
    BString signature;
    status = file.ReadAttrString("BEOS:APP_SIG", &signature);
    if (status < B_OK)
        return B_BAD_TYPE;

    // Init our various objects

    BMimeType mime;
    status = mime.SetTo(signature.String());
    if (status < B_OK)
        return status;

    InstallNotificationDeferrer _(fDatabase, signature.String());

    if (!mime.IsInstalled())
        mime.Install();

    BString path = "/";
    path.Append(signature);
    path.ToLower();
    // Signatures and MIME types are case insensitive, but we want to
    // preserve the case wherever possible
    path.Prepend(get_database_directory().c_str());

    status = typeNode.SetTo(path.String());
    if (status < B_OK)
        return status;

    // Preferred App
    attr_info info;
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kPreferredAppAttr, &info) != B_OK))
        status = mime.SetPreferredApp(signature.String());

    // Short Description (name of the application)
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kShortDescriptionAttr, &info) != B_OK))
        status = mime.SetShortDescription(ref->name);

    // App Hint
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kAppHintAttr, &info) != B_OK))
        status = mime.SetAppHint(ref);

    // Vector Icon
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kIconAttr, &info) != B_OK)) {
        uint8* data = NULL;
        size_t size = 0;
        if (appInfo.GetIcon(&data, &size) == B_OK) {
            status = mime.SetIcon(data, size);
            free(data);
        }
    }
    // Mini Icon
    BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kMiniIconAttr, &info) != B_OK)) {
        if (appInfo.GetIcon(&miniIcon, B_MINI_ICON) == B_OK)
            status = mime.SetIcon(&miniIcon, B_MINI_ICON);
    }
    // Large Icon
    BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kLargeIconAttr, &info) != B_OK)) {
        if (appInfo.GetIcon(&largeIcon, B_LARGE_ICON) == B_OK)
            status = mime.SetIcon(&largeIcon, B_LARGE_ICON);
    }

    // Supported Types
    bool setSupportedTypes = false;
    BMessage supportedTypes;
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kSupportedTypesAttr, &info) != B_OK)) {
        if (appInfo.GetSupportedTypes(&supportedTypes) == B_OK)
            setSupportedTypes = true;
    }

    // defer notifications for supported types
    const char* type;
    for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
        fDatabase->DeferInstallNotification(type);

    // set supported types
    if (setSupportedTypes)
        status = mime.SetSupportedTypes(&supportedTypes);

    // Icons for supported types
    for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) {
        // vector icon
        uint8* data = NULL;
        size_t size = 0;
        if (status == B_OK && appInfo.GetIconForType(type, &data, &size) == B_OK) {
            status = mime.SetIconForType(type, data, size);
            free(data);
        }
        // mini icon
        if (status == B_OK && appInfo.GetIconForType(type, &miniIcon, B_MINI_ICON) == B_OK)
            status = mime.SetIconForType(type, &miniIcon, B_MINI_ICON);
        // large icon
        if (status == B_OK && appInfo.GetIconForType(type, &largeIcon, B_LARGE_ICON) == B_OK)
            status = mime.SetIconForType(type, &largeIcon, B_LARGE_ICON);
    }

    // undefer notifications for supported types
    for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
        fDatabase->UndeferInstallNotification(type);

    return status;
}