void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir) { // Set default finder info Mac_memset(finfo, 0, SIZEOF_FInfo); if (fxinfo) Mac_memset(fxinfo, 0, SIZEOF_FXInfo); WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS); WriteMacInt32(finfo + fdLocation, (uint32)-1); // Open file int fd = open(path, O_RDONLY); if (fd < 0) return; if (!is_dir) { // Read BeOS MIME type ssize_t actual = fs_read_attr(fd, "BEOS:TYPE", B_MIME_STRING_TYPE, 0, tmp_buf, 256); tmp_buf[255] = 0; if (actual > 0) { // Translate MIME type to MacOS type/creator uint8 mactype[4]; if (sscanf((char *)tmp_buf, "application/x-MacOS-%c%c%c%c", mactype, mactype+1, mactype+2, mactype+3) == 4) { // MacOS style type WriteMacInt32(finfo + fdType, (mactype[0] << 24) | (mactype[1] << 16) | (mactype[2] << 8) | mactype[3]); } else { // MIME string, look in table for (int i=0; m2t_translation[i].mime; i++) { if (!strcmp((char *)tmp_buf, m2t_translation[i].mime)) { WriteMacInt32(finfo + fdType, m2t_translation[i].type); WriteMacInt32(finfo + fdCreator, m2t_translation[i].creator); break; } } } } // Override file type with MACOS:CREATOR attribute if (fs_read_attr(fd, "MACOS:CREATOR", B_UINT32_TYPE, 0, tmp_buf, 4) == 4) WriteMacInt32(finfo + fdCreator, (tmp_buf[0] << 24) | (tmp_buf[1] << 16) | (tmp_buf[2] << 8) | tmp_buf[3]); } // Read MACOS:HFS_FLAGS attribute if (fs_read_attr(fd, "MACOS:HFS_FLAGS", B_UINT16_TYPE, 0, tmp_buf, 2) == 2) WriteMacInt16(finfo + fdFlags, (tmp_buf[0] << 8) | tmp_buf[1]); // Close file close(fd); }
status_t BAttributeDataReader::ReadData(off_t offset, void* buffer, size_t size) { ssize_t bytesRead = fs_read_attr(fFD, fAttribute, fType, offset, buffer, size); if (bytesRead < 0) return errno; return (size_t)bytesRead == size ? B_OK : B_ERROR; }
/*! \brief Reads data from an attribute into a buffer. Reads the data of the attribute given by \a name into the buffer specified by \a buffer with length specified by \a len. \a type and \a offset are currently ignored. \param attr the name of the attribute \param type the type of the attribute (currently ignored) \param offset the index from which to read the data (currently ignored) \param buffer the buffer for the data to be read \param len the number of bytes to be read \return - the number of bytes actually read - \c B_BAD_VALUE: \c NULL \a attr or \a buffer - \c B_FILE_ERROR: The object is not initialized. - \c B_ENTRY_NOT_FOUND: The node has no attribute \a attr. */ ssize_t BNode::ReadAttr(const char *attr, type_code type, off_t offset, void *buffer, size_t len) const { if (fCStatus != B_OK) return B_FILE_ERROR; if (!attr || !buffer) return B_BAD_VALUE; ssize_t result = fs_read_attr(fFd, attr, type, offset, buffer, len ); return (result == -1 ? errno : result); }
// ReadAttr status_t FileHandle::ReadAttr(const char* name, uint32 type, off_t pos, void* buffer, size_t size, size_t* _bytesRead) { if (fFD < 0) return B_BAD_VALUE; ssize_t bytesRead = fs_read_attr(fFD, name, type, pos, buffer, size); if (bytesRead < 0) return errno; *_bytesRead = bytesRead; return B_OK; }
int fill_grent_from_fd(int fd, struct group *gbuf, char *buf, size_t buflen) { size_t left; ssize_t len; left = buflen; len = fs_read_attr(fd, B_GR_GID, B_INT32_TYPE, 0LL, &gbuf->gr_gid, sizeof(gid_t)); if (len < 0) return fill_grent_default(gbuf); PRINT(("%s: got gid\n", __FUNCTION__)); gbuf->gr_passwd = ""; gbuf->gr_mem = default_gr_members; if (left < GR_MAX_NAME + 1) return ERANGE; len = fs_read_attr(fd, B_GR_NAME, B_STRING_TYPE, 0LL, buf, GR_MAX_NAME); if (len < 0) return fill_grent_default(gbuf); gbuf->gr_name = buf; buf[len] = '\0'; left -= len + 1; buf += len + 1; PRINT(("%s: got name\n", __FUNCTION__)); return 0; }
static int rfork_read(SDL_RWops *context, void *ptr, int size, int maxnum) { rfork_data *d = (rfork_data *)context->hidden.unknown.data1; int num = maxnum; if (d->current + (num*size) > d->size) num = (d->size - d->current) / size; ssize_t actual = fs_read_attr(d->fd, ATTR_NAME, B_RAW_TYPE, d->current, ptr, num * size); if (actual < 0) return actual; else { d->current += actual; return actual / size; } }
int main(void) { char path[300]; int code; thread_id tid; system_info sinfo; thread_info tinfo; int fd; int r; struct{ int lock; bigtime_t sessionSN; thread_id tid; }lockdata; signal(SIGINT,SIG_IGN); // protection anti-cons get_system_info(&sinfo); for(;;){ code=receive_data(&tid,&path,sizeof path); path[sizeof path-1]=0; fd=open(path,B_READ_WRITE); if(fd<0){ send_data(tid,errno,NULL,0); continue; } r=fs_read_attr(fd,AFL_SERVER_NAME,ATTRTYPE, 0,&lockdata,sizeof lockdata); switch(code){ case AFLMSG_LOCK: if(r==sizeof lockdata && lockdata.lock && lockdata.sessionSN==sinfo.boot_time && !(get_thread_info(lockdata.tid,&tinfo))){ // le fichier est déjà vérouillé ! close(fd); send_data(tid,AFLMSG_ISLOCKED,&lockdata.tid,sizeof lockdata.tid); break; } lockdata.lock=1; lockdata.sessionSN=sinfo.boot_time; lockdata.tid=tid; r=fs_write_attr(fd,AFL_SERVER_NAME,ATTRTYPE, 0,&lockdata,sizeof lockdata); close(fd); if(r<0) send_data(tid,errno,0,NULL); else send_data(tid,B_OK,0,NULL); break; case AFLMSG_UNLOCK: if(r!=sizeof lockdata || !lockdata.lock || lockdata.sessionSN!=sinfo.boot_time || lockdata.tid!=tid){ // le fichier n'est pas vérouillé par ce thread ! close(fd); send_data(tid,B_PERMISSION_DENIED,0,NULL); break; } r=fs_remove_attr(fd,AFL_SERVER_NAME); close(fd); if(r<0) send_data(tid,errno,0,NULL); else send_data(tid,B_OK,0,NULL); break; default: close(fd); send_data(tid,B_BAD_VALUE,0,NULL); } } return 0; }
static status_t catAttr(const char *attribute, const char *fileName, bool keepRaw = false) { int fd = open(fileName, O_RDONLY); if (fd < 0) return errno; attr_info info; if (fs_stat_attr(fd, attribute, &info) < 0) return errno; // limit size of the attribute, only the first 64k will make it on screen off_t size = info.size; bool cut = false; if (size > 64 * 1024) { size = 64 * 1024; cut = true; } char* buffer = (char*)malloc(size); if (!buffer) { fprintf(stderr, "Could not allocate read buffer!\n"); return B_NO_MEMORY; } ssize_t bytesRead = fs_read_attr(fd, attribute, info.type, 0, buffer, size); if (bytesRead < 0) { free(buffer); return errno; } if (bytesRead != size) { fprintf(stderr, "Could only read %ld bytes from attribute!\n", bytesRead); free(buffer); return B_ERROR; } if (keepRaw) { off_t pos = 0; ssize_t written = 0; while (pos < info.size) { // write what we have read so far written = write(STDOUT_FILENO, buffer, bytesRead); // check for write error if (written < bytesRead) { if (written >= 0) { fprintf(stderr, "Could only write %ld bytes to stream!\n", written); written = B_ERROR; } else { fprintf(stderr, "Failed to write to stream: %s\n", strerror(written)); } break; } // read next chunk of data at pos pos += bytesRead; bytesRead = fs_read_attr(fd, attribute, info.type, pos, buffer, size); // check for read error if (bytesRead < size && pos + bytesRead < info.size) { if (bytesRead >= 0) { fprintf(stderr, "Could only read %ld bytes from " "attribute!\n", bytesRead); } else { fprintf(stderr, "Failed to read from attribute: %s\n", strerror(bytesRead)); } written = B_ERROR; break; } } free(buffer); if (written > 0) written = B_OK; return written; } switch (info.type) { case B_INT8_TYPE: printf("%s : int8 : %d\n", fileName, *((int8 *)buffer)); break; case B_UINT8_TYPE: printf("%s : uint8 : %u\n", fileName, *((uint8 *)buffer)); break; case B_INT16_TYPE: printf("%s : int16 : %d\n", fileName, *((int16 *)buffer)); break; case B_UINT16_TYPE: printf("%s : uint16 : %u\n", fileName, *((uint16 *)buffer)); break; case B_INT32_TYPE: printf("%s : int32 : %ld\n", fileName, *((int32 *)buffer)); break; case B_UINT32_TYPE: printf("%s : uint32 : %lu\n", fileName, *((uint32 *)buffer)); break; case B_INT64_TYPE: printf("%s : int64 : %Ld\n", fileName, *((int64 *)buffer)); break; case B_UINT64_TYPE: printf("%s : uint64 : %Lu\n", fileName, *((uint64 *)buffer)); break; case B_FLOAT_TYPE: printf("%s : float : %f\n", fileName, *((float *)buffer)); break; case B_DOUBLE_TYPE: printf("%s : double : %f\n", fileName, *((double *)buffer)); break; case B_BOOL_TYPE: printf("%s : bool : %d\n", fileName, *((unsigned char *)buffer)); break; case B_STRING_TYPE: printf("%s : string : %s\n", fileName, buffer); break; case B_MIME_STRING_TYPE: case 'MSIG': case 'MSDC': case 'MPTH': printf("%s : %s : %s\n", fileName, type_to_string(info.type), buffer); break; case B_MESSAGE_TYPE: { BMessage message; if (!cut && message.Unflatten(buffer) == B_OK) { printf("%s : message :\n", fileName); message.PrintToStream(); break; } // supposed to fall through } default: // The rest of the attributes types are displayed as raw data printf("%s : %s : \n", fileName, type_to_string(info.type)); dumpRawData(buffer, size); break; } free(buffer); return B_OK; }
int fill_pwent_from_fd(int fd, struct passwd *pwbuf, char *buf, size_t buflen) { ssize_t left; ssize_t len; PRINT(("%s()\n", __FUNCTION__)); left = buflen; if (left <= 0) return ERANGE; len = fs_read_attr(fd, B_PW_GID, B_INT32_TYPE, 0LL, &pwbuf->pw_gid, sizeof(gid_t)); if (len < 0) return fill_pwent_default(pwbuf); PRINT(("%s: got gid\n", __FUNCTION__)); len = fs_read_attr(fd, B_PW_UID, B_INT32_TYPE, 0LL, &pwbuf->pw_uid, sizeof(uid_t)); if (len < 0) return fill_pwent_default(pwbuf); PRINT(("%s: got uid\n", __FUNCTION__)); if (left < PW_MAX_NAME + 1) return ERANGE; len = fs_read_attr(fd, B_PW_NAME, B_STRING_TYPE, 0LL, buf, PW_MAX_NAME); if (len < 0) return fill_pwent_default(pwbuf); pwbuf->pw_name = buf; buf[len] = '\0'; left -= len + 1; buf += len + 1; PRINT(("%s: got name\n", __FUNCTION__)); if (left < PW_MAX_DIR + 1) return ERANGE; len = fs_read_attr(fd, B_PW_DIR, B_STRING_TYPE, 0LL, buf, PW_MAX_DIR); if (len < 0) return fill_pwent_default(pwbuf); pwbuf->pw_dir = buf; buf[len] = '\0'; left -= len + 1; buf += len + 1; PRINT(("%s: got dir\n", __FUNCTION__)); if (left < PW_MAX_SHELL + 1) return ERANGE; len = fs_read_attr(fd, B_PW_SHELL, B_STRING_TYPE, 0LL, buf, PW_MAX_SHELL); if (len < 0) return fill_pwent_default(pwbuf); pwbuf->pw_shell = buf; buf[len] = '\0'; left -= len + 1; buf += len + 1; PRINT(("%s: got shell\n", __FUNCTION__)); if (left < PW_MAX_GECOS + 1) return ERANGE; len = fs_read_attr(fd, B_PW_GECOS, B_STRING_TYPE, 0LL, buf, PW_MAX_GECOS); if (len < 0) return fill_pwent_default(pwbuf); pwbuf->pw_gecos = buf; buf[len] = '\0'; left -= len + 1; buf += len + 1; PRINT(("%s: got gecos\n", __FUNCTION__)); if (left < PW_MAX_PASSWD + 1) return ERANGE; len = fs_read_attr(fd, B_PW_PASSWD, B_STRING_TYPE, 0LL, buf, PW_MAX_PASSWD); if (len < 0) { buf[0] = '*'; /* no pass set */ len = 1; } pwbuf->pw_passwd = buf; buf[len] = '\0'; left -= len + 1; buf += len + 1; PRINT(("%s: got passwd\n", __FUNCTION__)); return 0; }