static void _gio_file_mkdir(GIOControl *gc,char *path) { if ( GFileMkDir(path)==-1 ) { _GIO_reporterror(gc,errno); } else { gc->return_code = 201; gc->done = true; (gc->receivedata)(gc); } }
static void _gio_file_renamefile(GIOControl *gc,char *path, char *topath) { if ( rename(path,topath)==-1 ) { _GIO_reporterror(gc,errno); } else { gc->return_code = 201; gc->done = true; (gc->receivedata)(gc); } }
static void _gio_file_statfile(GIOControl *gc,char *path) { GDirEntry *cur; struct stat statb; if ( stat(path,&statb)==-1 ) { _GIO_reporterror(gc,errno); } else { cur = (GDirEntry *) gcalloc(1,sizeof(GDirEntry)); cur->name = uc_copy(GFileNameTail(path)); cur->hasdir = cur->hasexe = cur->hasmode = cur->hassize = cur->hastime = true; cur->size = statb.st_size; cur->mode = statb.st_mode; cur->modtime = statb.st_mtime; cur->isdir = S_ISDIR(cur->mode); cur->isexe = !cur->isdir && (cur->mode & 0100); gc->iodata = cur; gc->direntrydata = true; gc->return_code = 200; gc->done = true; (gc->receivedata)(gc); } }
static void GIOdispatch(GIOControl *gc, enum giofuncs gf) { unichar_t *temp, *pt, *tpt; int i; gc->gf = gf; if ( _GIO_stdfuncs.useragent == NULL ) _GIO_stdfuncs.useragent = copy("*****@*****.**"); temp = _GIO_translateURL(gc->path,gf); if ( temp!=NULL ) { if ( gc->origpath==NULL ) gc->origpath = gc->path; else free(gc->path); gc->path = temp; } if ( gc->topath!=NULL ) { temp = _GIO_translateURL(gc->topath,gf); if ( temp!=NULL ) { free(gc->topath); gc->topath = temp; } if ( gf==gf_renamefile ) { if (( pt = uc_strstr(gc->path,"://"))== NULL ) pt = gc->path; else { pt=u_strchr(pt+3,'/'); if ( pt==NULL ) pt = gc->path+u_strlen(gc->path); } if (( tpt = uc_strstr(gc->topath,"://"))== NULL ) tpt = gc->topath; else { tpt=u_strchr(tpt+3,'/'); if ( tpt==NULL ) tpt = gc->topath+u_strlen(gc->topath); } if ( tpt-gc->topath!=pt-gc->path || u_strnmatch(gc->path,gc->topath,pt-gc->path)!=0 ) { _GIO_reporterror(gc,EXDEV); return; } } } pt = uc_strstr(gc->path,"://"); if ( pt!=NULL ) { for ( i=0; i<plen; ++i ) if ( u_strnmatch(protocols[i].proto,gc->path,pt-gc->path)==0 ) break; if ( i>=plen && !AddProtocol(gc->path,pt-gc->path) ) { gc->protocol_index = -2; gc->return_code = 501; gc->error = err501; uc_strcpy(gc->status,"No support for browsing: "); u_strncpy(gc->status+u_strlen(gc->status), gc->path, pt-gc->path ); gc->done = true; (gc->receiveerror)(gc); return; } gc->protocol_index = i; if ( !protocols[i].dothread ) (protocols[i].dispatcher)(gc); else { #ifndef HAVE_PTHREAD_H gc->return_code = 501; gc->error = err501; uc_strcpy(gc->status,"No support for protocol"); gc->done = true; (gc->receiveerror)(gc); return; #else static pthread_cond_t initcond = PTHREAD_COND_INITIALIZER; static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER; /* could put stuff here to queue functions if we get too many */ /* threads, or perhaps even a thread pool */ uc_strcpy(gc->status,"Queued"); gc->threaddata = (struct gio_threaddata *) malloc(sizeof(struct gio_threaddata)); gc->threaddata->mutex = initmutex; gc->threaddata->cond = initcond; if ( _GIO_stdfuncs.gdraw_sync_thread!=NULL ) (_GIO_stdfuncs.gdraw_sync_thread)(NULL,NULL,NULL); pthread_create(&gc->threaddata->thread,NULL, (ptread_startfunc_t *) (protocols[i].dispatcher), gc); #endif } } else { gc->protocol_index = -1; _GIO_localDispatch(gc); } }
static void _gio_file_dir(GIOControl *gc,char *path) { DIR *dir; struct dirent *ent; GDirEntry *head=NULL, *last=NULL, *cur; char *buffer, *ept, *temp; struct stat statb; dir = opendir(path); if ( dir==NULL ) { _GIO_reporterror(gc,errno); return; } buffer = (char *) malloc(strlen(path)+FILENAME_MAX+3); strcpy(buffer,path); ept = buffer+strlen(buffer); if ( ept[-1]!='/' ) *ept++ = '/'; while (( ent = readdir(dir))!=NULL ) { cur = (GDirEntry *) calloc(1,sizeof(GDirEntry)); cur->name = def2u_copy(ent->d_name); strcpy(ept,ent->d_name); stat(buffer,&statb); cur->hasdir = cur->hasexe = cur->hasmode = cur->hassize = cur->hastime = true; cur->size = statb.st_size; cur->mode = statb.st_mode; cur->modtime = statb.st_mtime; cur->isdir = S_ISDIR(cur->mode); cur->isexe = !cur->isdir && (cur->mode & 0100); temp = NULL; // Things go badly if we open a pipe or a device. So we don't. #ifdef __MINGW32__ //Symlinks behave differently on Windows and are transparent, so no S_ISLNK. if (S_ISREG(statb.st_mode) || S_ISDIR(statb.st_mode)) { #else if (S_ISREG(statb.st_mode) || S_ISDIR(statb.st_mode) || S_ISLNK(statb.st_mode)) { #endif // We look at the file and try to determine a MIME type. if ( (temp=GIOguessMimeType(buffer)) || (temp=GIOGetMimeType(buffer)) ) { cur->mimetype = u_copy(c_to_u(temp)); free(temp); } } if ( last==NULL ) head = last = cur; else { last->next = cur; last = cur; } } #if __CygWin /* Under cygwin we should give the user access to /cygdrive, even though */ /* a diropen("/") will not find it */ if ( strcmp(path,"/")==0 ) { cur = (GDirEntry *) calloc(1,sizeof(GDirEntry)); cur->name = def2u_copy("cygdrive"); strcpy(ept,"cygdrive"); stat(buffer,&statb); cur->hasdir = cur->hasexe = cur->hasmode = cur->hassize = cur->hastime = true; cur->size = statb.st_size; cur->mode = statb.st_mode; cur->modtime = statb.st_mtime; cur->isdir = S_ISDIR(cur->mode); cur->isexe = !cur->isdir && (cur->mode & 0100); if ( last==NULL ) head = last = cur; else { last->next = cur; last = cur; } } #endif closedir(dir); free(buffer); gc->iodata = head; gc->direntrydata = true; gc->return_code = 200; gc->done = true; (gc->receivedata)(gc); } static void _gio_file_statfile(GIOControl *gc,char *path) { GDirEntry *cur; struct stat statb; if ( stat(path,&statb)==-1 ) { _GIO_reporterror(gc,errno); } else { cur = (GDirEntry *) calloc(1,sizeof(GDirEntry)); cur->name = uc_copy(GFileNameTail(path)); cur->hasdir = cur->hasexe = cur->hasmode = cur->hassize = cur->hastime = true; cur->size = statb.st_size; cur->mode = statb.st_mode; cur->modtime = statb.st_mtime; cur->isdir = S_ISDIR(cur->mode); cur->isexe = !cur->isdir && (cur->mode & 0100); gc->iodata = cur; gc->direntrydata = true; gc->return_code = 200; gc->done = true; (gc->receivedata)(gc); } }
static void _gio_file_dir(GIOControl *gc,char *path) { DIR *dir; struct dirent *ent; GDirEntry *head=NULL, *last=NULL, *cur; char *buffer, *ept; struct stat statb; dir = opendir(path); if ( dir==NULL ) { _GIO_reporterror(gc,errno); return; } buffer = (char *) galloc(strlen(path)+FILENAME_MAX+3); strcpy(buffer,path); ept = buffer+strlen(buffer); if ( ept[-1]!='/' ) *ept++ = '/'; while (( ent = readdir(dir))!=NULL ) { cur = (GDirEntry *) gcalloc(1,sizeof(GDirEntry)); cur->name = def2u_copy(ent->d_name); strcpy(ept,ent->d_name); stat(buffer,&statb); cur->hasdir = cur->hasexe = cur->hasmode = cur->hassize = cur->hastime = true; cur->size = statb.st_size; cur->mode = statb.st_mode; cur->modtime = statb.st_mtime; cur->isdir = S_ISDIR(cur->mode); cur->isexe = !cur->isdir && (cur->mode & 0100); cur->mimetype= u_copy(c_to_u(GIOGetMimeType(buffer, false))); if ( last==NULL ) head = last = cur; else { last->next = cur; last = cur; } } #if __CygWin /* Under cygwin we should give the user access to /cygdrive, even though */ /* a diropen("/") will not find it */ if ( strcmp(path,"/")==0 ) { cur = (GDirEntry *) gcalloc(1,sizeof(GDirEntry)); cur->name = def2u_copy("cygdrive"); strcpy(ept,"cygdrive"); stat(buffer,&statb); cur->hasdir = cur->hasexe = cur->hasmode = cur->hassize = cur->hastime = true; cur->size = statb.st_size; cur->mode = statb.st_mode; cur->modtime = statb.st_mtime; cur->isdir = S_ISDIR(cur->mode); cur->isexe = !cur->isdir && (cur->mode & 0100); if ( last==NULL ) head = last = cur; else { last->next = cur; last = cur; } } #endif closedir(dir); free(buffer); gc->iodata = head; gc->direntrydata = true; gc->return_code = 200; gc->done = true; (gc->receivedata)(gc); }