+ else if (adp ) {
+ /* update the ressource fork
+ * for a folder adp is always null
+ */
+ if (ad_setid(adp, st->st_dev, st->st_ino, aint, did, vol->v_stamp)) {
+ ad_flush(adp);
+ }
+ }
+#endif
+ }
+ return aint;
+}
+
+/* -------------------------- */
+int getmetadata(struct vol *vol,
+ u_int16_t bitmap,
+ struct path *path, struct dir *dir,
+ char *buf, size_t *buflen, struct adouble *adp)
+{
+ char *data, *l_nameoff = NULL, *upath;
+ char *utf_nameoff = NULL;
+ int bit = 0;
+ u_int32_t aint;
+ cnid_t id = 0;
+ u_int16_t ashort;
+ u_char achar, fdType[4];
+ u_int32_t utf8 = 0;
+ struct stat *st;
+ struct maccess ma;
+
+#ifdef DEBUG
+ LOG(log_debug9, logtype_afpd, "begin getmetadata:");
+#endif /* DEBUG */
+
+ upath = path->u_name;
+ st = &path->st;
+
+ data = buf;
+
+ if ( ((bitmap & ( (1 << FILPBIT_FINFO)|(1 << FILPBIT_LNAME)|(1 <<FILPBIT_PDINFO) ) ) && !path->m_name)
+ || (bitmap & ( (1 << FILPBIT_LNAME) ) && utf8_encoding()) /* FIXME should be m_name utf8 filename */
+ || (bitmap & (1 << FILPBIT_FNUM))) {
+ if (!path->id)
+ id = get_id(vol, adp, st, dir->d_did, upath, strlen(upath));
+ else
+ id = path->id;
+ if (id == 0)
+ return afp_errno;
+ if (!path->m_name) {
+ path->m_name = utompath(vol, upath, id, utf8_encoding());
+ }
+ }
+ while ( bitmap != 0 ) {
+ while (( bitmap & 1 ) == 0 ) {
+ bitmap = bitmap>>1;
+ bit++;
+ }
+
+ switch ( bit ) {
+ case FILPBIT_ATTR :
+ if ( adp ) {
+ ad_getattr(adp, &ashort);
+ } else if (vol_inv_dots(vol) && *upath == '.') {
+ ashort = htons(ATTRBIT_INVISIBLE);
+ } else
+ ashort = 0;
+#if 0
+ /* FIXME do we want a visual clue if the file is read only
+ */
+ struct maccess ma;
+ accessmode( ".", &ma, dir , NULL);
+ if ((ma.ma_user & AR_UWRITE)) {
+ accessmode( upath, &ma, dir , st);
+ if (!(ma.ma_user & AR_UWRITE)) {
+ ashort |= htons(ATTRBIT_NOWRITE);
+ }
+ }
+#endif
+ memcpy(data, &ashort, sizeof( ashort ));
+ data += sizeof( ashort );
+ break;
+
+ case FILPBIT_PDID :
+ memcpy(data, &dir->d_did, sizeof( u_int32_t ));
+ data += sizeof( u_int32_t );
+ break;
+
+ case FILPBIT_CDATE :
+ if (!adp || (ad_getdate(adp, AD_DATE_CREATE, &aint) < 0))
+ aint = AD_DATE_FROM_UNIX(st->st_mtime);
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ break;
+
+ case FILPBIT_MDATE :
+ if ( adp && (ad_getdate(adp, AD_DATE_MODIFY, &aint) == 0)) {
+ if ((st->st_mtime > AD_DATE_TO_UNIX(aint))) {
+ aint = AD_DATE_FROM_UNIX(st->st_mtime);
+ }
+ } else {
+ aint = AD_DATE_FROM_UNIX(st->st_mtime);
+ }
+ memcpy(data, &aint, sizeof( int ));
+ data += sizeof( int );
+ break;
+
+ case FILPBIT_BDATE :
+ if (!adp || (ad_getdate(adp, AD_DATE_BACKUP, &aint) < 0))
+ aint = AD_DATE_START;
+ memcpy(data, &aint, sizeof( int ));
+ data += sizeof( int );
+ break;
+
+ case FILPBIT_FINFO :
+ get_finderinfo(vol, upath, adp, (char *)data);
+ data += ADEDLEN_FINDERI;
+ break;
+
+ case FILPBIT_LNAME :
+ l_nameoff = data;
+ data += sizeof( u_int16_t );
+ break;
+
+ case FILPBIT_SNAME :
+ memset(data, 0, sizeof(u_int16_t));
+ data += sizeof( u_int16_t );
+ break;
+
+ case FILPBIT_FNUM :
+ memcpy(data, &id, sizeof( id ));
+ data += sizeof( id );
+ break;
+
+ case FILPBIT_DFLEN :
+ if (st->st_size > 0xffffffff)
+ aint = 0xffffffff;
+ else
+ aint = htonl( st->st_size );
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ break;
+
+ case FILPBIT_RFLEN :
+ if ( adp ) {
+ if (adp->ad_rlen > 0xffffffff)
+ aint = 0xffffffff;
+ else
+ aint = htonl( adp->ad_rlen);
+ } else {
+ aint = 0;
+ }
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ break;
+
+ /* Current client needs ProDOS info block for this file.
+ Use simple heuristic and let the Mac "type" string tell
+ us what the PD file code should be. Everything gets a
+ subtype of 0x0000 unless the original value was hashed
+ to "pXYZ" when we created it. See IA, Ver 2.
+ <shirsch@adelphia.net> */
+ case FILPBIT_PDINFO :
+ if (afp_version >= 30) { /* UTF8 name */
+ utf8 = kTextEncodingUTF8;
+ utf_nameoff = data;
+ data += sizeof( u_int16_t );
+ aint = 0;
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ }
+ else {
+ if ( adp ) {
+ memcpy(fdType, ad_entry( adp, ADEID_FINDERI ), 4 );
+
+ if ( memcmp( fdType, "TEXT", 4 ) == 0 ) {
+ achar = '\x04';
+ ashort = 0x0000;
+ }
+ else if ( memcmp( fdType, "PSYS", 4 ) == 0 ) {
+ achar = '\xff';
+ ashort = 0x0000;
+ }
+ else if ( memcmp( fdType, "PS16", 4 ) == 0 ) {
+ achar = '\xb3';
+ ashort = 0x0000;
+ }
+ else if ( memcmp( fdType, "BINA", 4 ) == 0 ) {
+ achar = '\x00';
+ ashort = 0x0000;
+ }
+ else if ( fdType[0] == 'p' ) {
+ achar = fdType[1];
+ ashort = (fdType[2] * 256) + fdType[3];
+ }
+ else {
+ achar = '\x00';
+ ashort = 0x0000;
+ }
+ }
+ else {
+ achar = '\x00';
+ ashort = 0x0000;
+ }
+
+ *data++ = achar;
+ *data++ = 0;
+ memcpy(data, &ashort, sizeof( ashort ));
+ data += sizeof( ashort );
+ memset(data, 0, sizeof( ashort ));
+ data += sizeof( ashort );
+ }
+ break;
+ case FILPBIT_EXTDFLEN:
+ aint = htonl(st->st_size >> 32);
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ aint = htonl(st->st_size);
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ break;
+ case FILPBIT_EXTRFLEN:
+ aint = 0;
+ if (adp)
+ aint = htonl(adp->ad_rlen >> 32);
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ if (adp)
+ aint = htonl(adp->ad_rlen);
+ memcpy(data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ break;
+ case FILPBIT_UNIXPR :
+ /* accessmode may change st_mode with ACLs */
+ accessmode( upath, &ma, dir , st);
+
+ aint = htonl(st->st_uid);
+ memcpy( data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+ aint = htonl(st->st_gid);
+ memcpy( data, &aint, sizeof( aint ));
+ data += sizeof( aint );
+
+ /* FIXME: ugly hack
+ type == slnk indicates an OSX style symlink,
+ we have to add S_IFLNK to the mode, otherwise
+ 10.3 clients freak out. */
+
+ aint = st->st_mode;
+ if (adp) {
+ memcpy(fdType, ad_entry( adp, ADEID_FINDERI ), 4 );
+ if ( memcmp( fdType, "slnk", 4 ) == 0 ) {
+ aint |= S_IFLNK;
+ }