static void sv_rewind(struct irs_sv *sv) { struct service_private *service = (struct service_private *)sv->private_data; if (service->file) { if (fseek(service->file, 0L, SEEK_SET) == 0) return; fclose(service->file); service->file = NULL; } char path[PATH_MAX]; if (find_directory(B_COMMON_DATA_DIRECTORY, -1, false, path, sizeof(path)) == B_OK) { strlcat(path, "/network/services", sizeof(path)); if ((service->file = fopen(path, "r")) != NULL) { if (fcntl(fileno(service->file), F_SETFD, FD_CLOEXEC) == 0) return; fclose(service->file); service->file = NULL; } } // opening the standard file has file has failed, use the attribute // find our library image image_info info; if (find_own_image(&info) != B_OK) return; // open the library int libraryFD = open(info.name, O_RDONLY); if (libraryFD < 0) return; // open the attribute int attrFD = fs_fopen_attr(libraryFD, "services", B_STRING_TYPE, O_RDONLY); close(libraryFD); if (attrFD < 0) return; // attach it to a FILE service->file = fdopen(attrFD, "r"); if (service->file == NULL) { close(attrFD); return; } if (fcntl(fileno(service->file), F_SETFD, FD_CLOEXEC) == 0) return; fclose(service->file); service->file = NULL; }
void AboutView::_AddCopyrightsFromAttribute() { #ifdef __HAIKU__ // open the app executable file char appPath[B_PATH_NAME_LENGTH]; int appFD; if (BPrivate::get_app_path(appPath) != B_OK || (appFD = open(appPath, O_RDONLY)) < 0) { return; } // open the attribute int attrFD = fs_fopen_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY); close(appFD); if (attrFD < 0) return; // attach it to a FILE FILE* attrFile = fdopen(attrFD, "r"); if (attrFile == NULL) { close(attrFD); return; } CObjectDeleter<FILE, int> _(attrFile, fclose); // read and parse the copyrights BMessage package; BString fieldName; BString fieldValue; char lineBuffer[LINE_MAX]; while (char* line = fgets(lineBuffer, sizeof(lineBuffer), attrFile)) { // chop off line break size_t lineLen = strlen(line); if (lineLen > 0 && line[lineLen - 1] == '\n') line[--lineLen] = '\0'; // flush previous field, if a new field begins, otherwise append if (lineLen == 0 || !isspace(line[0])) { // new field -- flush the previous one if (fieldName.Length() > 0) { fieldValue = trim_string(fieldValue.String(), fieldValue.Length()); package.AddString(fieldName.String(), fieldValue); fieldName = ""; } } else if (fieldName.Length() > 0) { // append to current field fieldValue += line; continue; } else { // bogus line -- ignore continue; } if (lineLen == 0) continue; // parse new field char* colon = strchr(line, ':'); if (colon == NULL) { // bogus line -- ignore continue; } fieldName.SetTo(line, colon - line); fieldName = trim_string(line, colon - line); if (fieldName.Length() == 0) { // invalid field name continue; } fieldValue = colon + 1; if (fieldName == "Package") { // flush the current package _AddPackageCredit(PackageCredit(package)); package.MakeEmpty(); } } // flush current package _AddPackageCredit(PackageCredit(package)); #endif }