static int dir_walk(const char *basepath) { #define RECUR_NAME "RECUR" Rdir_walk.verbose ("Creating directories %s/" RECUR_NAME "/" RECUR_NAME "/" RECUR_NAME "\n" ,basepath); for (int i=1; i<4 && Rdir_walk.getnberr()==0; i++){ char path[MAXSIZ_PATH]; strcpy (path,basepath); for (int j=0; j<i; j++) strcat (path,"/" RECUR_NAME); util_mkdir(path,0777,Rdir_walk,0); } if (Rdir_walk.getnberr()==0){ char wpath[MAXSIZ_PATH]; struct stat info1; sprintf (wpath,"%s/" RECUR_NAME "/./../" RECUR_NAME "/" RECUR_NAME "/" RECUR_NAME "/../../../" RECUR_NAME ,basepath); util_stat (wpath,&info1,Rdir_walk,0); } dir_removeall (basepath,RECUR_NAME,4,Rdir_walk); return Rdir_walk.getnberr(); }
/* * util_file_is_device_dax -- checks whether the path points to a device dax */ int util_file_is_device_dax(const char *path) { #ifdef _WIN32 return 0; #else util_stat_t st; int olderrno = errno; int ret = 0; if (path == NULL) goto out; if (util_stat(path, &st) < 0) goto out; if (!S_ISCHR(st.st_mode)) goto out; char spath[PATH_MAX]; snprintf(spath, PATH_MAX, "/sys/dev/char/%d:%d/subsystem", major(st.st_rdev), minor(st.st_rdev)); char npath[PATH_MAX]; char *rpath = realpath(spath, npath); if (rpath == NULL) goto out; ret = strcmp(DEVICE_DAX_PREFIX, rpath) == 0; out: errno = olderrno; return ret; #endif }
/* * pool_set_part_copy -- make a copy of the poolset part */ int pool_set_part_copy(struct pool_set_part *dpart, struct pool_set_part *spart, int overwrite) { LOG(3, "dpart %p spart %p", dpart, spart); int result = 0; util_stat_t stat_buf; if (util_stat(spart->path, &stat_buf)) { ERR("!util_stat"); return -1; } size_t smapped = 0; void *saddr = pmem_map_file(spart->path, 0, 0, S_IREAD, &smapped, NULL); if (!saddr) return -1; size_t dmapped = 0; int is_pmem; void *daddr; if (!access(dpart->path, F_OK)) { if (!overwrite) { errno = EEXIST; result = -1; goto out_sunmap; } daddr = pmem_map_file(dpart->path, 0, 0, S_IWRITE, &dmapped, &is_pmem); } else { if (errno == ENOENT) { errno = 0; daddr = pmem_map_file(dpart->path, dpart->filesize, PMEM_FILE_CREATE | PMEM_FILE_EXCL, stat_buf.st_mode, &dmapped, &is_pmem); } else { result = -1; goto out_sunmap; } } if (!daddr) { result = -1; goto out_sunmap; } if (is_pmem) { pmem_memcpy_persist(daddr, saddr, smapped); } else { memcpy(daddr, saddr, smapped); PERSIST_GENERIC(dpart->is_dax, daddr, smapped); } pmem_unmap(daddr, dmapped); out_sunmap: pmem_unmap(saddr, smapped); return result; }
void display_admin(DbSortedRows *sorted_rows) { char *action = query_val(QUERY_PARAM_ACTION); HTML_LOG(1,"action = %s",action); if (!allow_admin()) { printf("admin disabled"); } else if (EMPTY_STR(action) || STRCMP(action,"ask")==0 || STRCMP(action,"Cancel")==0) { int show_donate = 1; if (strstr(NVL(getenv("QUERY_STRING")),"donate") ) { // we've come from the donate page. show_donate = 0; } if (show_donate) { if (exists(donated_file())) { struct STAT64 stat; if (util_stat(donated_file(),&stat) == 0) { HTML_LOG(0,"now=%u time = %u",time(NULL),stat.st_mtime); if (time(NULL) < stat.st_mtime ) { show_donate = 0; } } } } if (show_donate) { display_main_template("admin","donate",sorted_rows); } else { display_main_template("admin","admin",sorted_rows); } } else if (util_starts_with(action,"settings")) { display_main_template("admin","settings",sorted_rows); #define CONFIRM_PREFIX "confirm_" } else if (util_starts_with(action,CONFIRM_PREFIX)) { display_main_template("admin",action+strlen(CONFIRM_PREFIX),sorted_rows); #define TEMPLATE_PREFIX "template_" } else if (util_starts_with(action,TEMPLATE_PREFIX)) { display_main_template("admin",action+strlen(TEMPLATE_PREFIX),sorted_rows); } else { display_main_template("admin","completed",sorted_rows); } }
/* * pool_set_file_open -- (internal) opens pool set file or regular file */ static struct pool_set_file * pool_set_file_open(const char *fname, struct pool_params *params, int rdonly) { LOG(3, NULL); struct pool_set_file *file = calloc(1, sizeof(*file)); if (!file) return NULL; file->fname = strdup(fname); if (!file->fname) goto err; const char *path = file->fname; if (params->type != POOL_TYPE_BTT) { int ret = util_poolset_create_set(&file->poolset, path, 0, 0); if (ret < 0) { LOG(2, "cannot open pool set -- '%s'", path); goto err_free_fname; } if (util_pool_open_nocheck(file->poolset, rdonly)) goto err_free_fname; file->size = file->poolset->poolsize; /* get modification time from the first part of first replica */ path = file->poolset->replica[0]->part[0].path; file->addr = file->poolset->replica[0]->part[0].addr; } else { int oflag = rdonly ? O_RDONLY : O_RDWR; file->fd = util_file_open(fname, NULL, 0, oflag); file->size = params->size; } util_stat_t buf; if (util_stat(path, &buf)) { ERR("%s", path); goto err_close_poolset; } file->mtime = buf.st_mtime; file->mode = buf.st_mode; return file; err_close_poolset: if (params->type != POOL_TYPE_BTT) util_poolset_close(file->poolset, 0); else close(file->fd); err_free_fname: free(file->fname); err: free(file); return NULL; }
/* Test many hlinkink chain to point to a file fpath */ static void hlink_many ( const char *fpath, // target of the link const char *lpath, // base name for hard link int fpath_exist, // fpath does exist or not UMSDOS_REGISTER ®) { if (reg.getnberr()==0){ /* #Specification: utstspc / hard links / case / link 2 link 2 link ... hlink_simple does test a link made to a link made to a link and so on. On a normal UNIX file system, this test is not really an issue. Given the fact that a hardlink on UMSDOS is a symlink to a hidden file, it make sense to test at least the two cases: hard link to an existing file with no link hard link to an existing file with more than one link. */ int i; for (i=0; i<6 && reg.getnberr()==0; i++){ char spath1[MAXSIZ_PATH]; if (i > 0){ strcpy (spath1,lpath); for (int j=0; j<i; j++) strcat (spath1,".s"); }else{ strcpy (spath1,fpath); } char spath2[MAXSIZ_PATH]; strcpy (spath2,lpath); for (int j=0; j<=i; j++) strcat (spath2,".s"); if (fpath_exist){ util_hardlink (spath1,spath2,reg,0); struct stat info; if (util_stat (spath2,&info,reg,0)!=-1 && info.st_size != 6){ reg.prterr ( "Invalid dimension for %s\n",spath2); } hlink_checkhello (spath2,reg); }else{ util_hardlink (spath1,spath2,reg,ENOENT); } } if (fpath_exist){ // Cleanup char spath[MAXSIZ_PATH]; strcpy (spath,lpath); for (i=0; i<=5; i++){ strcat (spath,".s"); util_unlink (spath,reg,0); } } } }
/* Do a rename, but try to compute the expected result. Instead of doing a big test case table, I prefer trying almost all combination and do a simple algorythm to compute the expect result from the kernel. */ static int sticky_renchk ( STICKY_PATHS &p, UMSDOS_REGISTER ®) { struct stat infodir1; struct stat infofile1; struct stat infodir2; struct stat infofile2; int ret = -1; if (util_stat(p.dir1,&infodir1,reg,0)!=-1 && util_stat(p.file1,&infofile1,reg,0)!=-1 && util_stat(p.dir2,&infodir2,reg,0)!=-1){ /* The destination file may exist or not */ int err_expected = 0; if (util_delok(infofile1,infodir1)==EPERM) err_expected = EPERM; if (stat(p.file2,&infofile2)!=-1){ if (util_delok(infofile2,infodir2)==EPERM) err_expected = EPERM; } // printf ("/expect=%d/ ", err_expected); ret = util_rename (p.file1,p.file2,reg,err_expected); } return ret; }
/* * device_dax_size -- (internal) checks the size of a given dax device */ static ssize_t device_dax_size(const char *path) { util_stat_t st; int olderrno; if (util_stat(path, &st) < 0) return -1; char spath[PATH_MAX]; snprintf(spath, PATH_MAX, "/sys/dev/char/%d:%d/size", major(st.st_rdev), minor(st.st_rdev)); int fd = open(spath, O_RDONLY); if (fd < 0) return -1; ssize_t size = -1; char sizebuf[MAX_SIZE_LENGTH + 1]; ssize_t nread; if ((nread = read(fd, sizebuf, MAX_SIZE_LENGTH)) < 0) goto out; sizebuf[nread] = 0; /* null termination */ char *endptr; olderrno = errno; errno = 0; size = strtoll(sizebuf, &endptr, 0); if (endptr == sizebuf || *endptr != '\n' || ((size == LLONG_MAX || size == LLONG_MIN) && errno == ERANGE)) { size = -1; goto out; } errno = olderrno; out: olderrno = errno; (void) close(fd); errno = olderrno; return size; }
/* * util_file_get_size -- returns size of a file */ ssize_t util_file_get_size(const char *path) { #ifndef _WIN32 if (util_file_is_device_dax(path)) { return device_dax_size(path); } #endif util_stat_t stbuf; if (util_stat(path, &stbuf) < 0) { ERR("!fstat %s", path); return -1; } return stbuf.st_size; }
/* * replica_check_local_part_dir -- check if directory for the part file * exists */ int replica_check_local_part_dir(struct pool_set *set, unsigned repn, unsigned partn) { LOG(3, "set %p, repn %u, partn %u", set, repn, partn); char *path = Strdup(PART(REP(set, repn), partn).path); const char *dir = dirname(path); util_stat_t sb; if (util_stat(dir, &sb) != 0 || !(sb.st_mode & S_IFDIR)) { ERR("a directory %s for part %u in replica %u" " does not exist or is not accessible", path, partn, repn); Free(path); return -1; } Free(path); return 0; }
/** * returns record in name file that matches the name id. * This has format * id tab name * eg * 1\tJohn Doe */ char *dbnames_fetch_static(char *key,char *file) { char *result = NULL; struct STAT64 st; if (util_stat(file,&st) == 0) { FILE *f = util_open(file,"rba"); if (f) { result = dbnames_fetch_chop_static(key,f,0,st.st_size); chomp(result); fclose(f); } } HTML_LOG(1,"dbnames_fetch_chop_static[%s]=[%s]",key,result); return result; }
/* * pool_set_part_copy -- make a copy of the poolset part */ int pool_set_part_copy(struct pool_set_part *dpart, struct pool_set_part *spart) { LOG(3, "dpart %p spart %p", dpart, spart); int result = 0; util_stat_t stat_buf; if (util_stat(spart->path, &stat_buf)) { ERR("!util_stat"); return -1; } size_t smapped = 0; void *saddr = pmem_map_file(spart->path, 0, 0, S_IREAD, &smapped, NULL); if (!saddr) return -1; size_t dmapped = 0; int is_pmem; void *daddr = pmem_map_file(dpart->path, dpart->filesize, PMEM_FILE_CREATE | PMEM_FILE_EXCL, stat_buf.st_mode, &dmapped, &is_pmem); if (!daddr) { result = -1; goto out_sunmap; } if (is_pmem) { pmem_memcpy_persist(daddr, saddr, smapped); } else { memcpy(daddr, saddr, smapped); pmem_msync(daddr, smapped); } pmem_unmap(daddr, dmapped); out_sunmap: pmem_unmap(saddr, smapped); return result; }
/* ---INFOBEGIN--- * DO NOT DELETE THIS COMMENT BLOCK!!! COMMAND rmdir remote "remove directories from the remote system" * ---INFOEND--- */ #include "client.h" #ifndef ANSI_PROTOTYPES extern char **glob(); #else /* ANSI_PROTOTYPES */ extern char **glob(char *); #endif /* ANSI_PROTOTYPES */ static int dirty; static int #ifndef ANSI_PROTOTYPES do_rmdir(name) char *name; #else /* ANSI_PROTOTYPES */ do_rmdir(char *name) #endif /* ANSI_PROTOTYPES */ { char *op; UBUF *ub; struct stat sbuf; if (!validate_operation(name, LITERAL_DIR | DIR_OWNER)) return -1; if (util_stat(name, &sbuf) < 0) { ffprintf(STDERR,"rmdir: cannot remove directory `%s': no such directory\n", name); return -1; } if (!S_ISDIR(sbuf.st_mode)) { ffprintf(STDERR,"rmdir: cannot remove directory `%s': not a directory\n", name); return -1; } op = util_abs_path(name); ub = client_interact(CC_DEL_DIR, 0L, strlen(op), op + 1, 0, NULLP); (void)free(op); if (client_intr_state > 1 || !ub) return -1; if (ub->cmd == CC_ERR) { ffprintf(STDERR,"rmdir: cannot remove directory `%s'\n", name); return -1; } dirty = 1; return 0; }
/* * pool_copy -- make a copy of the pool */ int pool_copy(struct pool_data *pool, const char *dst_path, int overwrite) { struct pool_set_file *file = pool->set_file; int dfd; if (!access(dst_path, F_OK)) { if (!overwrite) { errno = EEXIST; return -1; } dfd = util_file_open(dst_path, NULL, 0, O_RDWR); } else { if (errno == ENOENT) { errno = 0; dfd = util_file_create(dst_path, file->size, 0); } else { return -1; } } if (dfd < 0) return -1; int result = 0; util_stat_t stat_buf; if (util_stat(file->fname, &stat_buf)) { result = -1; goto out_close; } if (fchmod(dfd, stat_buf.st_mode)) { result = -1; goto out_close; } void *daddr = mmap(NULL, file->size, PROT_READ | PROT_WRITE, MAP_SHARED, dfd, 0); if (daddr == MAP_FAILED) { result = -1; goto out_close; } if (pool->params.type != POOL_TYPE_BTT) { void *saddr = pool_set_file_map(file, 0); memcpy(daddr, saddr, file->size); goto out_unmap; } void *buf = malloc(RW_BUFFERING_SIZE); if (buf == NULL) { ERR("!malloc"); result = -1; goto out_unmap; } pool_btt_lseek(pool, 0, SEEK_SET); ssize_t buf_read = 0; void *dst = daddr; while ((buf_read = pool_btt_read(pool, buf, RW_BUFFERING_SIZE))) { if (buf_read == -1) break; memcpy(dst, buf, (size_t)buf_read); dst = (void *)((ssize_t)dst + buf_read); } free(buf); out_unmap: munmap(daddr, file->size); out_close: if (dfd >= 0) close(dfd); return result; }
int ls(char *path) { int result = 0; printf("Content-Type: text/html; charset=utf-8\n\n<html><head><title>%s</title><style type=\"text/css\">" " .K { color:green; }" " .M { color:orange; }" " .G { color:red; }" " td.size { text-align:right; }" "</style></head><body>%s<br>",path,path); DIR *d = opendir(path); if (d) { Array *dirs = array_new(free); Array *files = array_new(free); struct dirent *f ; while((f = readdir(d)) != NULL) { char *p,*u; double size=0; char *unit="b"; int precision=0; char *size_str=NULL; struct STAT64 st; ovs_asprintf(&p,"%s/%s",path,f->d_name); //printf("<br>checking %s\n",p); //u = file_to_url(p); ovs_asprintf(&u,"?%s",p); util_stat(p,&st); size = st.st_size; if (f->d_type == 0) { // more nmt100 oddness - dirent type not set? if (S_ISREG(st.st_mode)) f->d_type = DT_REG; else if (S_ISDIR(st.st_mode)) f->d_type = DT_DIR; } if (size > 1024 ) { size /= 1024 ; unit="<span class=\"K\">K</span>" ; precision=1; } if (size > 1024 ) { size /= 1024 ; unit="<font class=\"M\">M</span>" ; } if (size > 1024 ) { size /= 1024 ; unit="<span class=\"G\">G</span>" ; } char *display = f->d_name; if (strcmp(f->d_name,"..") == 0) { // find parent folder name char *tmp = STRDUP(path); ovs_asprintf(&u,"?%s",dirname(tmp)); FREE(tmp); display="up↑"; ; // UP } if (strcmp(f->d_name,".") != 0) { char *tmp; switch(f->d_type) { case DT_REG: if(strstr(f->d_name,"log.gz")) { // Display inline link ovs_asprintf(&tmp,"<tr><td><a href=\"%s.txt\">%s</a> <a href=\"%s\">*</a></td><td class=\"size\"> - %.*f%s</td></tr>", u,display,u, precision,size,unit); } else { //ovs_asprintf(&tmp,"<tr><td>%.1f%s</td><td><a href=\"%s\">%s</a></td></tr>",size,unit,u,f->d_name); ovs_asprintf(&tmp,"<tr><td><a href=\"%s\">%s</a></td><td class=\"size\"> - %.*f%s</td></tr>", u,display, precision,size,unit); } array_add(files,tmp); break; case DT_DIR: ovs_asprintf(&tmp,"<a href=\"%s\">%s</a> ",u,display); array_add(dirs,tmp); break; default: ovs_asprintf(&tmp,"<tr><td><a href=\"%s\">%s</a></td><td>%d?</td></tr>",u,f->d_name,f->d_type); array_add(files,tmp); break; } } FREE(size_str); FREE(u); FREE(p); } closedir(d); char *out; array_sort(dirs,NULL); out = arraystr(dirs); if (out) { printf("%s",out); } FREE(out); printf("<hr><table border=\"0\">"); array_sort(files,NULL); out = arraystr(files); if (out) { printf("%s",out); } FREE(out); printf("</table>"); array_free(dirs); array_free(files); } else { fprintf(stderr,"Error %d opening [%s]\n",errno,path); result = errno; } printf("</body></html>"); return result; }