/* similar to readlink (cf. man readlink), except that symbolic links are followed up to MAX_LINK_LEVEL */ static int full_readlink(const char* name, char* buf, size_t bufsize) { int ret; if ((ret=my_readlink(name, buf, bufsize)) > 0) { char buf2[MAXPATHLEN]; int ret2, i = 0; do { buf[ret] = '\0'; if ((ret2 = my_readlink(buf, buf2, MAXPATHLEN)) > 0) { i++; buf2[ret2] = '\0'; strcpy(buf, buf2); ret = ret2; } else { return ret; } } while (i<MAX_LINK_LEVEL); } return -1; }
int my_rename_with_symlink(const char *from, const char *to, myf MyFlags) { #ifndef HAVE_READLINK return my_rename(from, to, MyFlags); #else char link_name[FN_REFLEN], tmp_name[FN_REFLEN]; int was_symlink= (!my_disable_symlinks && !my_readlink(link_name, from, MYF(0))); int result=0; int name_is_different; DBUG_ENTER("my_rename_with_symlink"); if (!was_symlink) DBUG_RETURN(my_rename(from, to, MyFlags)); /* Change filename that symlink pointed to */ strmov(tmp_name, to); fn_same(tmp_name,link_name,1); /* Copy dir */ name_is_different= strcmp(link_name, tmp_name); if (name_is_different && !access(tmp_name, F_OK)) { my_errno= EEXIST; if (MyFlags & MY_WME) my_error(EE_CANTCREATEFILE, MYF(0), tmp_name, EEXIST); DBUG_RETURN(1); } /* Create new symlink */ if (my_symlink(tmp_name, to, MyFlags)) DBUG_RETURN(1); /* Rename symlinked file if the base name didn't change. This can happen if you use this function where 'from' and 'to' has the same basename and different directories. */ if (name_is_different && my_rename(link_name, tmp_name, MyFlags)) { int save_errno=my_errno; my_delete(to, MyFlags); /* Remove created symlink */ my_errno=save_errno; DBUG_RETURN(1); } /* Remove original symlink */ if (my_delete(from, MyFlags)) { int save_errno=my_errno; /* Remove created link */ my_delete(to, MyFlags); /* Rename file back */ if (strcmp(link_name, tmp_name)) (void) my_rename(tmp_name, link_name, MyFlags); my_errno=save_errno; result= 1; } DBUG_RETURN(result); #endif /* HAVE_READLINK */ }
struct list * scsi_get_list(void) { DIR *dir; struct dirent *dirent; struct list *modules = NULL; dir = opendir("/sys/bus/scsi/devices"); if (!dir) return NULL; while((dirent = readdir(dir))) { char *path; char *tmp; char *name = dirent->d_name; if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue; if (name[0] < '0' || name[0] > '9') continue; path = concat("/sys/bus/scsi/devices/", name); path = my_readlink(path); tmp = sys_value(path, "type"); if (tmp) { if (strcmp(tmp, "0") == 0 || strcmp(tmp, "7") == 0) modules = list_add(modules, "sd_mod"); if (strcmp(tmp, "1") == 0) modules = list_add(modules, "st"); if (strcmp(tmp, "4") == 0 || strcmp(tmp, "5") == 0) modules = list_add(modules, "sr_mod"); } } closedir(dir); return modules; }
int my_delete_with_symlink(const char *name, myf MyFlags) { char link_name[FN_REFLEN]; int was_symlink= (!my_disable_symlinks && !my_readlink(link_name, name, MYF(0))); int result; DBUG_ENTER("my_delete_with_symlink"); if (!(result=my_delete(name, MyFlags))) { if (was_symlink) result=my_delete(link_name, MyFlags); } DBUG_RETURN(result); }
void inotify_dnsmasq_init() { struct resolvc *res; inotify_buffer = safe_malloc(INOTIFY_SZ); daemon->inotifyfd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); if (daemon->inotifyfd == -1) die(_("failed to create inotify: %s"), NULL, EC_MISC); if (option_bool(OPT_NO_RESOLV)) return; for (res = daemon->resolv_files; res; res = res->next) { char *d, *new_path, *path = safe_malloc(strlen(res->name) + 1); int links = MAXSYMLINKS; strcpy(path, res->name); /* Follow symlinks until we reach a non-symlink, or a non-existant file. */ while ((new_path = my_readlink(path))) { if (links-- == 0) die(_("too many symlinks following %s"), res->name, EC_MISC); free(path); path = new_path; } res->wd = -1; if ((d = strrchr(path, '/'))) { *d = 0; /* make path just directory */ res->wd = inotify_add_watch(daemon->inotifyfd, path, IN_CLOSE_WRITE | IN_MOVED_TO); res->file = d+1; /* pointer to filename */ *d = '/'; if (res->wd == -1 && errno == ENOENT) die(_("directory %s for resolv-file is missing, cannot poll"), res->name, EC_MISC); } if (res->wd == -1) die(_("failed to create inotify for %s: %s"), res->name, EC_MISC); } }
char * fn_format(char * to, const char *name, const char *dir, const char *extension, uint flag) { char dev[FN_REFLEN], buff[FN_REFLEN], *pos, *startpos; const char *ext; reg1 size_t length; size_t dev_length; my_bool not_used; DBUG_ENTER("fn_format"); DBUG_ASSERT(name != NULL); DBUG_ASSERT(extension != NULL); DBUG_PRINT("enter",("name: %s dir: %s extension: %s flag: %d", name,dir,extension,flag)); /* Copy and skip directory */ name+=(length=dirname_part(dev, (startpos=(char *) name), &dev_length)); if (length == 0 || (flag & MY_REPLACE_DIR)) { DBUG_ASSERT(dir != NULL); /* Use given directory */ convert_dirname(dev,dir,NullS); /* Fix to this OS */ } else if ((flag & MY_RELATIVE_PATH) && !test_if_hard_path(dev)) { DBUG_ASSERT(dir != NULL); /* Put 'dir' before the given path */ strmake(buff,dev,sizeof(buff)-1); pos=convert_dirname(dev,dir,NullS); strmake(pos,buff,sizeof(buff)-1- (int) (pos-dev)); } if (flag & MY_PACK_FILENAME) pack_dirname(dev,dev); /* Put in ./.. and ~/.. */ if (flag & MY_UNPACK_FILENAME) (void) unpack_dirname(dev, dev, ¬_used); /* Replace ~/.. with dir */ if (!(flag & MY_APPEND_EXT) && (pos= (char*) strchr(name,FN_EXTCHAR)) != NullS) { if ((flag & MY_REPLACE_EXT) == 0) /* If we should keep old ext */ { length=strlength(name); /* Use old extension */ ext = ""; } else { length= (size_t) (pos-(char*) name); /* Change extension */ ext= extension; } } else { length=strlength(name); /* No ext, use the now one */ ext=extension; } if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN ) { /* To long path, return original or NULL */ size_t tmp_length; if (flag & MY_SAFE_PATH) DBUG_RETURN(NullS); tmp_length= strlength(startpos); DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext, (uint) length)); (void) strmake(to, startpos, MY_MIN(tmp_length, FN_REFLEN-1)); } else { if (to == startpos) { bmove(buff,(uchar*) name,length); /* Save name for last copy */ name=buff; } pos=strmake(strmov(to,dev),name,length); (void) strmov(pos,ext); /* Don't convert extension */ } /* If MY_RETURN_REAL_PATH and MY_RESOLVE_SYMLINK is given, only do realpath if the file is a symbolic link */ if (flag & MY_RETURN_REAL_PATH) (void) my_realpath(to, to, MYF(flag & MY_RESOLVE_SYMLINKS ? MY_RESOLVE_LINK: 0)); else if (flag & MY_RESOLVE_SYMLINKS) { strmov(buff,to); (void) my_readlink(to, buff, MYF(0)); } DBUG_RETURN(to); } /* fn_format */