void add_fd_and_signal(int fd) { add_fd(fd); signal_main_thread(); if (!firsttime) { firsttime=1; signal_main_thread(); } }
void * just_end_it_now(void * ignore) { if (ending) return; ending=1; if (libafpclient->forced_ending_hook) libafpclient->forced_ending_hook(); exit_program=2; signal_main_thread(); }
void rm_fd_and_signal(int fd) { rm_fd(fd); signal_main_thread(); }
static int process_mount(struct fuse_client * c) { struct afp_server_mount_request * req; struct afp_server * s=NULL; struct afp_volume * volume; struct afp_connection_request conn_req; int ret; struct stat lstat; if ((c->incoming_size-1) < sizeof(struct afp_server_mount_request)) goto error; req=(void *) c->incoming_string+1; /* Todo should check the existance and perms of the mount point */ if ((ret=access(req->mountpoint,X_OK))!=0) { log_for_client((void *)c,AFPFSD,LOG_DEBUG, "Incorrect permissions on mountpoint %s: %s\n", req->mountpoint, strerror(errno)); goto error; } if (stat(FUSE_DEVICE,&lstat)) { printf("Could not find %s\n",FUSE_DEVICE); goto error; } if (access(FUSE_DEVICE,R_OK | W_OK )!=0) { log_for_client((void *)c, AFPFSD,LOG_NOTICE, "Incorrect permissions on %s, mode of device" " is %o, uid/gid is %d/%d. But your effective " "uid/gid is %d/%d\n", FUSE_DEVICE,lstat.st_mode, lstat.st_uid, lstat.st_gid, geteuid(),getegid()); goto error; } log_for_client((void *)c,AFPFSD,LOG_NOTICE, "Mounting %s from %s on %s\n", (char *) req->url.servername, (char *) req->url.volumename,req->mountpoint); if ((afp_default_connection_request(&conn_req,&req->url))==-1) { log_for_client((void *)c,AFPFSD,LOG_ERR, "Unknown UAM"); return -1; } conn_req.uam_mask=req->uam_mask; if ((s=afp_server_full_connect(c,&conn_req))==NULL) { signal_main_thread(); goto error; } if ((volume=mount_volume(c,s,req->url.volumename, req->url.volpassword))==NULL) { goto error; } volume->extra_flags|=req->volume_options; volume->mapping=req->map; afp_detect_mapping(volume); snprintf(volume->mountpoint,255,req->mountpoint); /* Create the new thread and block until we get an answer back */ { pthread_mutex_t mutex; struct timespec ts; struct timeval tv; int ret; struct start_fuse_thread_arg arg; memset(&arg,0,sizeof(arg)); arg.client = c; arg.volume = volume; arg.wait = 1; arg.changeuid=req->changeuid; gettimeofday(&tv,NULL); ts.tv_sec=tv.tv_sec; ts.tv_sec+=5; ts.tv_nsec=tv.tv_usec*1000; pthread_mutex_init(&mutex,NULL); pthread_cond_init(&volume->startup_condition_cond,NULL); /* Kickoff a thread to see how quickly it exits. If * it exits quickly, we have an error and it failed. */ pthread_create(&volume->thread,NULL,start_fuse_thread,&arg); if (arg.wait) ret = pthread_cond_timedwait( &volume->startup_condition_cond,&mutex,&ts); report_fuse_errors(c); switch (arg.fuse_result) { case 0: if (volume->mounted==AFP_VOLUME_UNMOUNTED) { /* Try and discover why */ switch(arg.fuse_errno) { case ENOENT: log_for_client((void *)c,AFPFSD,LOG_ERR, "Permission denied, maybe a problem with the fuse device or mountpoint?\n"); break; default: log_for_client((void *)c,AFPFSD,LOG_ERR, "Mounting of volume %s of server %s failed.\n", volume->volume_name_printable, volume->server->server_name_printable); } goto error; } else { log_for_client((void *)c,AFPFSD,LOG_NOTICE, "Mounting of volume %s of server %s succeeded.\n", volume->volume_name_printable, volume->server->server_name_printable); return 0; } break; case ETIMEDOUT: log_for_client((void *)c,AFPFSD,LOG_NOTICE, "Still trying.\n"); return 0; break; default: volume->mounted=AFP_VOLUME_UNMOUNTED; log_for_client((void *)c,AFPFSD,LOG_NOTICE, "Unknown error %d, %d.\n", arg.fuse_result,arg.fuse_errno); goto error; } } return AFP_SERVER_RESULT_OKAY; error: if ((s) && (!something_is_mounted(s))) { afp_server_remove(s); } signal_main_thread(); return AFP_SERVER_RESULT_ERROR; }
int fuse_mount(struct daemon_client * c, volumeid_t * volumeid) { struct afp_server_mount_request * req; struct afp_server * s=NULL; struct afp_volume * volume; struct afp_connection_request conn_req; int ret; struct stat lstat; char * r; int response_result = AFP_SERVER_RESULT_OKAY; memset(&volumeid,0,sizeof(volumeid_t)); req=(void *) c->complete_packet; if ((ret=access(req->mountpoint,X_OK))!=0) { log_for_client((void *)c,AFPFSD,LOG_DEBUG, "Incorrect permissions on mountpoint %s: %s\n", req->mountpoint, strerror(errno)); response_result=AFP_SERVER_RESULT_MOUNTPOINT_PERM; goto error; } if (stat(FUSE_DEVICE,&lstat)) { printf("Could not find %s\n",FUSE_DEVICE); response_result=AFP_SERVER_RESULT_MOUNTPOINT_NOEXIST; goto error; } if (access(FUSE_DEVICE,R_OK | W_OK )!=0) { log_for_client((void *)c, AFPFSD,LOG_NOTICE, "Incorrect permissions on %s, mode of device" " is %o, uid/gid is %d/%d. But your effective " "uid/gid is %d/%d\n", FUSE_DEVICE,lstat.st_mode, lstat.st_uid, lstat.st_gid, geteuid(),getegid()); response_result=AFP_SERVER_RESULT_MOUNTPOINT_PERM; goto error; } log_for_client((void *)c,AFPFSD,LOG_NOTICE, "Mounting %s from %s on %s\n", (char *) req->url.servername, (char *) req->url.volumename,req->mountpoint); if ((s=find_server_by_url(&req->url))==NULL) { log_for_client((void *) c,AFPFSD,LOG_ERR, "%s is an unknown server\n",req->url.servername); response_result=AFP_SERVER_RESULT_NOSERVER; goto error; } /* response_result could be set in command_sub_attach_volume as: * AFP_SERVER_RESULT_OKAY: * AFP_SERVER_RESULT_NOVOLUME: * AFP_SERVER_RESULT_ALREADY_MOUNTED: * AFP_SERVER_RESULT_VOLPASS_NEEDED: * AFP_SERVER_RESULT_ERROR_UNKNOWN: */ if ((volume=command_sub_attach_volume(c,s,req->url.volumename, req->url.volpassword,&response_result))==NULL) { goto error; } volume->extra_flags|=req->volume_options; volume->mapping=req->map; afp_detect_mapping(volume); snprintf(volume->mountpoint,255,req->mountpoint); /* Create the new thread and block until we get an answer back */ if (fuse_mount_thread(c,volume,req->changeuid)<0) goto error; response_result=AFP_SERVER_RESULT_OKAY; goto done; error: #if 0 if ((s) && (!something_is_mounted(s))) { afp_server_remove(s); } #endif done: signal_main_thread(); return response_result; }