+
+
+/*
+ * precreate a folder
+ * this is only intended for folders in the volume root
+ * It will *not* work if the folder name contains extended characters
+ */
+static int create_special_folder (const struct vol *vol, const struct _special_folder *folder)
+{
+ char *p,*q,*r;
+ struct adouble ad;
+ u_int16_t attr;
+ struct stat st;
+ int ret;
+
+
+ p = (char *) malloc ( strlen(vol->v_path)+strlen(folder->name)+2);
+ if ( p == NULL) {
+ LOG(log_error, logtype_afpd,"malloc failed");
+ exit (EXITERR_SYS);
+ }
+
+ q=strdup(folder->name);
+ if ( q == NULL) {
+ LOG(log_error, logtype_afpd,"malloc failed");
+ exit (EXITERR_SYS);
+ }
+
+ strcpy(p, vol->v_path);
+ strcat(p, "/");
+
+ r=q;
+ while (*r) {
+ if ((vol->v_casefold & AFPVOL_MTOUUPPER))
+ *r=toupper(*r);
+ else if ((vol->v_casefold & AFPVOL_MTOULOWER))
+ *r=tolower(*r);
+ r++;
+ }
+ strcat(p, q);
+
+ if ( (ret = stat( p, &st )) < 0 ) {
+ if (folder->precreate) {
+ if (ad_mkdir(p, folder->mode)) {
+ LOG(log_debug, logtype_afpd,"Creating '%s' failed in %s: %s", p, vol->v_path, strerror(errno));
+ free(p);
+ free(q);
+ return -1;
+ }
+ ret = 0;
+ }
+ }
+
+ if ( !ret && folder->hide) {
+ /* Hide it */
+ ad_init(&ad, vol->v_adouble, vol->v_ad_options);
+ if (ad_open( p, vol_noadouble(vol) | ADFLAGS_HF|ADFLAGS_DIR,
+ O_RDWR|O_CREAT, 0666, &ad) < 0) {
+ free (p);
+ free(q);
+ return (-1);
+ }
+ if ((ad_get_HF_flags( &ad ) & O_CREAT) ) {
+ if (ad_getentryoff(&ad, ADEID_NAME)) {
+ ad_setentrylen( &ad, ADEID_NAME, strlen(folder->name));
+ memcpy(ad_entry( &ad, ADEID_NAME ), folder->name,
+ ad_getentrylen( &ad, ADEID_NAME ));
+ }
+ }
+
+ ad_getattr(&ad, &attr);
+ attr |= htons( ntohs( attr ) | ATTRBIT_INVISIBLE );
+ ad_setattr(&ad, attr);
+
+ /* do the same with the finder info */
+ if (ad_entry(&ad, ADEID_FINDERI)) {
+ memcpy(&attr, ad_entry(&ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, sizeof(attr));
+ attr |= htons(FINDERINFO_INVISIBLE);
+ memcpy(ad_entry(&ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF,&attr, sizeof(attr));
+ }
+
+ ad_flush( &ad );
+ ad_close( &ad, ADFLAGS_HF );
+ }
+ free(p);
+ free(q);
+ return 0;
+}
+
+static void handle_special_folders (const struct vol * vol)
+{
+ const _special_folder *p = &special_folders[0];
+
+ if ((vol->v_flags & AFPVOL_RO))
+ return;
+
+ for (; p->name != NULL; p++) {
+ create_special_folder (vol, p);
+ }
+}
+