static int verifyarg(char *dev, int flag) { struct stat st; int fd; int ret = 0; if (dev == NULL) { warn(gettext("specify device(s)\n")); ret = 1; goto err_exit; } if (dev[0] != '/') { warn(gettext("device name must begin with a '/'\n")); ret = 1; goto err_exit; } if ((pathcmp(dev, SYSMSG) == 0) || (pathcmp(dev, WSCONS) == 0) || (pathcmp(dev, CONSOLE) == 0)) { /* they match */ warn(gettext("invalid device %s\n"), dev); ret = 1; goto err_exit; } if (stat(dev, &st) || ! S_ISCHR(st.st_mode)) { warn(gettext("invalid device %s\n"), dev); ret = 1; goto err_exit; } /* Delete operation doesn't require this checking */ if ((fd = safeopen(dev)) < 0) { if (flag) { warn(gettext("invalid device %s\n"), dev); ret = 1; } goto err_exit; } if (!modem_support(fd)) { warn(gettext("invalid device %s\n"), dev); (void) close(fd); ret = 1; goto err_exit; } /* Only verify carrier if it's an add operation */ if (flag) { if (!has_carrier(fd)) { warn(gettext("failure, no carrier on %s\n"), dev); ret = 1; goto err_exit; } } err_exit: return (ret); }
int pathContainsPart(WCHAR *pathstart, WCHAR *pathend, WCHAR *item, WCHAR *stop) { WCHAR *p = pathend, *q=NULL; do { while (p > pathstart && *p != L'\\') --p; if (p<=pathstart) { if (q) *q=L'\\'; break; } if (pathcmp(p+1,item)==0) { if (q) *q=L'\\'; return 1; } if (pathcmp(p+1,stop)==0) { if (q) *q=L'\\'; return 0; } if (q!=NULL) *q=L'\\'; q=p; *p-- = L'\0'; } while (1); return 0; }
/* * Fork a child of sulogin for each of the auxiliary consoles. */ static void doit(char *ptr, char *cttyname) { pid_t pid; if (pathcmp(ptr, DEFAULT_CONSOLE) != 0 && pathcmp(ptr, cttyname) != 0) { if ((pid = fork()) == (pid_t)0) { setupsigs(); main_loop(ptr, B_FALSE); } else if (pid == -1) exit(EXIT_FAILURE); pidlist[nchild++] = pid; } }
int iobuf_pathcmp(struct iobuf *a, struct iobuf *b) { int r; if((r=pathcmp(a->buf, b->buf))) return r; if(a->cmd==CMD_METADATA || a->cmd==CMD_ENC_METADATA) { if(b->cmd==CMD_METADATA || b->cmd==CMD_ENC_METADATA) return 0; else return 1; } else if(a->cmd==CMD_VSS || a->cmd==CMD_ENC_VSS) { if(b->cmd==CMD_VSS || b->cmd==CMD_ENC_VSS) return 0; else return -1; } else if(a->cmd==CMD_VSS_T || a->cmd==CMD_ENC_VSS_T) { if(b->cmd==CMD_VSS_T || b->cmd==CMD_ENC_VSS_T) return 0; else return 1; } else { if(b->cmd==CMD_METADATA || b->cmd==CMD_ENC_METADATA) return -1; else if(b->cmd==CMD_VSS || b->cmd==CMD_ENC_VSS) return 1; else if(b->cmd==CMD_VSS_T || b->cmd==CMD_ENC_VSS_T) return -1; else return 0; } }
/* * copy appls to new file, deleting any matching (old) appl entries */ static int copyapplfile(int sfd, int dfd, char *mpath, u_short mplen) { int cc; char *p; u_int16_t len; u_char appltag[ 4 ]; char buf[ MAXPATHLEN ]; while (( cc = read( sfd, buf, sizeof(appltag) + sizeof( u_short ))) > 0 ) { p = buf + sizeof(appltag); memcpy( &len, p, sizeof(len)); len = ntohs( len ); p += sizeof( len ); if (( cc = read( sa.sdt_fd, p, len )) < len ) { break; } if ( pathcmp( mpath, mplen, p, len ) != 0 ) { p += len; if ( write( dfd, buf, p - buf ) != p - buf ) { cc = -1; break; } } } return( cc ); }
/* This adds a directory to the path list */ void add_to_pathlist(char *s) { PathList *cur, *prev, *plp; /* Check duplicated path in the pathlist. */ plp = prev = NULL; for(cur = pathlist; cur; prev = cur, cur = cur->next) if(pathcmp(s, cur->path, 0) == 0) { plp = cur; break; } if(plp) /* found */ { if(prev == NULL) /* first */ pathlist = pathlist->next; else prev->next = plp->next; } else { /* Allocate new path */ plp = safe_malloc(sizeof(PathList)); plp->path = safe_strdup(s); } plp->next = pathlist; pathlist = plp; }
static #endif int forward_past_entry(struct manio *manio, struct iobuf *target, enum protocol protocol, man_off_t **pos) { struct sbuf *sb=NULL; if(!(sb=sbuf_alloc(protocol))) goto error; man_off_t_free(pos); if(!(*pos=manio_tell(manio))) { logp("Could not manio_tell first pos in %s(): %s\n", __func__, strerror(errno)); goto error; } while(1) { sbuf_free_content(sb); switch(manio_read(manio, sb)) { case 0: break; case 1: logp("End of file in %s()\n", __func__); goto error; default: logp("Error in %s()\n", __func__); // Treat error in unchanged manio as not OK. goto error; } if(target->cmd==sb->path.cmd && !pathcmp(target->buf, sb->path.buf)) { man_off_t_free(pos); if(!(*pos=manio_tell(manio))) { logp("Could not get pos in %s(): %s\n", __func__, strerror(errno)); goto error; } sbuf_free(&sb); return 0; } } error: sbuf_free(&sb); man_off_t_free(pos); return -1; }
static void addtolist(char *dev) { int lckfd, fd; FILE *fp, *nfp; char newfile[MAXPATHLEN]; char buf[MAXPATHLEN]; int len; boolean_t found = B_FALSE; /* update file of devices configured to get console msgs. */ lckfd = getlock(); /* Open new file */ (void) snprintf(newfile, sizeof (newfile), "%s%d", CONSCONFIG, (int)getpid()); if (((fd = creat(newfile, 0644)) < 0) || ((nfp = fdopen(fd, "w")) == NULL)) { (void) close(lckfd); (void) unlink(CONSADMLOCK); die(gettext("could not create new %s file"), CONSCONFIG); } /* Add header to new file */ (void) fprintf(nfp, "%s", conshdr); /* Check that the file doesn't already exist */ if ((fp = fopen(CONSCONFIG, "r")) != NULL) { while (fgets(buf, MAXPATHLEN, fp) != NULL) { if (buf[0] == COMMENT || buf[0] == NEWLINE || buf[0] == SPACE || buf[0] == TAB) continue; len = strlen(buf); buf[len - 1] = NULL; /* Clear carriage return */ if (pathcmp(dev, buf) == 0) { /* they match so use name passed in. */ (void) fprintf(nfp, "%s\n", dev); found = B_TRUE; } else (void) fprintf(nfp, "%s\n", buf); } } /* User specified persistent settings */ if (found == B_FALSE) (void) fprintf(nfp, "%s\n", dev); (void) fclose(fp); (void) fclose(nfp); (void) rename(newfile, CONSCONFIG); (void) close(lckfd); (void) unlink(CONSADMLOCK); }
ACCESS_MASK isRestricted(RESTRICT_PARAM *list, PWCHAR key) { RESTRICT_PARAM *p = list; int cmp; if (!p || !key) return 0; while (p->obj != NULL) { cmp = pathcmp(p->obj, key); if (cmp==0 || cmp==1) { return p->mask; } ++p; } return 0; }
int main(void) { tap_plan(8); is(sign(pathcmp("/foo", "/foo")), 0); is(sign(pathcmp("/foo", "/foo/")), 0); is(sign(pathcmp("/foo//", "//foo/")), 0); is(sign(pathcmp("//foo//bar//", "/foo/bar")), 0); is(sign(pathcmp("/foo", "foo/")), -1); is(sign(pathcmp("/foo", "/fo/o")), 1); is(sign(pathcmp("/foo", "/bar")), 1); is(sign(pathcmp("/bar", "/foo")), -1); return tap_finish(); }
int filter_content(tommy_list* contentlist, const char* path) { tommy_node* i; for (i = tommy_list_head(contentlist); i != 0; i = i->next) { struct snapraid_content* content = i->data; char tmp[PATH_MAX]; if (pathcmp(content->content, path) == 0) return -1; /* exclude also the ".tmp" copy used to save it */ pathprint(tmp, sizeof(tmp), "%s.tmp", content->content); if (pathcmp(tmp, path) == 0) return -1; /* exclude also the ".lock" file */ pathprint(tmp, sizeof(tmp), "%s.lock", content->content); if (pathcmp(tmp, path) == 0) return -1; } return 0; }
static int do_strlist_add(struct strlist **strlist, const char *path, long flag, int sorted, int uniq) { struct strlist *s=NULL; struct strlist *slast=NULL; struct strlist *slnew=NULL; if(!(slnew=strlist_alloc(path, flag))) return -1; // Insert into a sorted position in the list, or if the sorted flag // was zero, add to the end of the list. // FIX THIS: Unsorted means that it goes through the whole list to // find the last entry. Can this be made better? for(s=*strlist; s; s=s->next) { if(uniq && !pathcmp(path, s->path)) { strlist_free(slnew); return 0; } if(sorted && pathcmp(path, s->path)<0) break; slast=s; } if(slast) { slnew->next=slast->next; slast->next=slnew; } else { *strlist=slnew; slnew->next=s; } return 0; }
const char* tree_find( const char *s ) // return full path by dirname { VString str; int z = 0; int sl = strlen( s ); for ( z = 0; z < dir_tree.count(); z++ ) { str = dir_tree[z]; if ( str_len( str ) < sl ) continue; str_sright( str, sl ); if (pathcmp( (const char*)str, s ) == 0) { return dir_tree[z]; } } return NULL; }
/* * Test if the specified file is new enough to include in the archive. */ static int new_enough(struct bsdtar *bsdtar, const char *path, const struct stat *st) { struct archive_dir_entry *p; /* * If this file/dir is excluded by a time comparison, skip it. */ if (bsdtar->newer_ctime_filter) { if (st->st_ctime < bsdtar->newer_ctime_sec) return (0); /* Too old, skip it. */ if (st->st_ctime == bsdtar->newer_ctime_sec && ARCHIVE_STAT_CTIME_NANOS(st) <= bsdtar->newer_ctime_nsec) return (0); /* Too old, skip it. */ } if (bsdtar->newer_mtime_filter) { if (st->st_mtime < bsdtar->newer_mtime_sec) return (0); /* Too old, skip it. */ if (st->st_mtime == bsdtar->newer_mtime_sec && ARCHIVE_STAT_MTIME_NANOS(st) <= bsdtar->newer_mtime_nsec) return (0); /* Too old, skip it. */ } /* * In -u mode, we only write an entry if it's newer than * what was already in the archive. */ if (bsdtar->archive_dir != NULL && bsdtar->archive_dir->head != NULL) { for (p = bsdtar->archive_dir->head; p != NULL; p = p->next) { if (pathcmp(path, p->name)==0) return (p->mtime_sec < st->st_mtime || (p->mtime_sec == st->st_mtime && p->mtime_nsec < ARCHIVE_STAT_MTIME_NANOS(st))); } } /* If the file wasn't rejected, include it. */ return (1); }
int tree_find( const char *s, VArray *va ) { VString str; int z = 0; int sl = strlen( s ); for ( z = 0; z < dir_tree.count(); z++ ) { str = dir_tree[z]; if ( str_len( str ) < sl ) continue; str_sright( str, sl ); if (pathcmp( str, s ) == 0) { str = dir_tree[z]; str_tr( str, "\\", "/" ); va->push( str ); } } return va->count(); }
static int statusrec_cmp(struct statusrec *a, struct statusrec *b) { size_t lena, lenb; if (a->sr_type == SR_DIRUP || b->sr_type == SR_DIRUP) { lena = strlen(a->sr_file); lenb = strlen(b->sr_file); if (a->sr_type == SR_DIRUP && ((lena < lenb && b->sr_file[lena] == '/') || lena == lenb) && strncmp(a->sr_file, b->sr_file, lena) == 0) return (1); if (b->sr_type == SR_DIRUP && ((lenb < lena && a->sr_file[lenb] == '/') || lenb == lena) && strncmp(a->sr_file, b->sr_file, lenb) == 0) return (-1); } return (pathcmp(a->sr_file, b->sr_file)); }
static int w32g_add_playlist1(char *filename, int uniq, int refine) { PlayListEntry *entry; char *title; struct midi_file_info *info; if(uniq) { int i; for(i = 0; i < playlist.nfiles; i++) if(pathcmp(filename, playlist.list[i].filename, 0) == 0) return 0; } title = get_midi_title(filename); info = get_midi_file_info(filename, 1); if(refine && info->format < 0) return 0; if(playlist.allocated == 0) { playlist.allocated = 32; playlist.list = (PlayListEntry *)safe_malloc(playlist.allocated * sizeof(PlayListEntry)); } else if(playlist.nfiles == playlist.allocated) { playlist.allocated *= 2; playlist.list = (PlayListEntry *)safe_realloc(playlist.list, playlist.allocated * sizeof(PlayListEntry)); } entry = &playlist.list[playlist.nfiles]; entry->filename = safe_strdup(filename); entry->title = title; entry->info = info; playlist.nfiles++; w32g_shuffle_playlist_reset(1); return 1; }
result_t path_base::basename(exlib::string path, exlib::string ext, exlib::string &retVal) { char ch; const char* c_str = path.c_str(); const char *p1 = c_str; int32_t extlen = (int32_t)ext.length(); while (*c_str) { ch = *c_str++; if (isPathSlash(ch)) p1 = c_str; } if (extlen && ((int32_t) (c_str - p1) >= extlen) && !pathcmp(ext.c_str(), c_str - extlen, extlen)) c_str -= extlen; retVal.assign(p1, (int32_t) (c_str - p1)); return 0; }
int find_color_scheme(const char *name) { char colors_dir[PATH_MAX]; DIR *dir; struct dirent *d; if(name[0] == '\0') return 0; snprintf(colors_dir, sizeof(colors_dir), "%s/colors", cfg.config_dir); dir = opendir(colors_dir); if(dir == NULL) return 0; while((d = readdir(dir)) != NULL) { #ifndef _WIN32 if(d->d_type != DT_REG && d->d_type != DT_LNK) continue; #endif if(d->d_name[0] == '.') continue; if(pathcmp(d->d_name, name) == 0) { closedir(dir); return 1; } } closedir(dir); return 0; }
static int pathcmp_qsort(const char **p1, const char **p2) { return pathcmp(*(const char **)p1, *(const char **)p2, 1); }
fsize_t __tree_rebuild_process( const char* path ) { if ( vfu_break_op() ) return -1; DIR* dir; dirent* de; struct stat st; fsize_t size = 0; char new_name[MAX_PATH]; dir = opendir( path ); if ( !dir ) return 0; while( (de = readdir(dir)) ) { if ( strcmp( de->d_name, "." ) == 0 || strcmp( de->d_name, ".." ) == 0 ) continue; sprintf(new_name, "%s%s", path, de->d_name); lstat(new_name, &st); int is_link = int(S_ISLNK(st.st_mode)); if (is_link) continue; #ifdef _TARGET_GO32_ dosstat(dir, &st); #else stat(new_name, &st); #endif int is_dir = S_ISDIR(st.st_mode); if ( is_dir ) { /* directory */ strcat( new_name, "/" ); int z; int trim = 0; for ( z = 0; z < trim_tree.count(); z++ ) { VString trim_temp = trim_tree[z]; str_fix_path( trim_temp ); if ( pathcmp(trim_temp, new_name) == 0 ) { /* trim_tree item found */ trim = 1; break; } } if (trim) continue; /* cut this branch */ int pos = dir_tree.count(); fsize_t dir_size = __tree_rebuild_process( new_name ); if ( dir_size < 0 ) { /* canceled */ closedir(dir); return -1; } dir_tree.ins( pos, new_name ); size_cache_set( new_name, dir_size ); size += dir_size; } else { /* file */ size += file_st_size( &st ); } } closedir(dir); /* show some progress :) */ say2( str_dot_reduce( path, con_max_x()-1 ) ); return size; }
int strlist_sort(struct strlist **a, struct strlist **b) { return pathcmp((*a)->path, (*b)->path); }
int mkpath(char **rpath, const char *limit) { int ret=-1; char *cp=NULL; struct stat buf; #ifdef HAVE_WIN32 int windows_stupidity=0; #endif if((cp=strrchr(*rpath, '/'))) { *cp='\0'; #ifdef HAVE_WIN32 if(strlen(*rpath)==2 && (*rpath)[1]==':') { (*rpath)[1]='\0'; windows_stupidity++; } #endif if(!**rpath) { // We are down to the root, which is OK. } else if(lstat(*rpath, &buf)) { // does not exist - recurse further down, then come // back and try to mkdir it. if(mkpath(rpath, limit)) goto end; // Require that the user has set up the required paths // on the server correctly. I have seen problems with // part of the path being a temporary symlink that // gets replaced by burp with a proper directory. // Allow it to create the actual directory specified, // though. // That is, if limit is: // /var/spool/burp // and /var/spool exists, the directory will be // created. // If only /var exists, the directory will not be // created. // Caller can give limit=NULL to create the whole // path with no limit, as in a restore. if(limit && pathcmp(*rpath, limit)<0) { logp("will not mkdir %s\n", *rpath); goto end; } if(mkdir(*rpath, 0777)) { logp("could not mkdir %s: %s\n", *rpath, strerror(errno)); goto end; } } else if(S_ISDIR(buf.st_mode)) { // Is a directory - can put the slash back and return. } else if(S_ISLNK(buf.st_mode)) { // to help with the 'current' symlink } else { // something funny going on logp("warning: wanted '%s' to be a directory\n", *rpath); } } ret=0; end: #ifdef HAVE_WIN32 if(windows_stupidity) (*rpath)[1]=':'; #endif if(cp) *cp='/'; return ret; }
/* ARGSUSED */ int main(int argc, char **argv) { struct spwd *shpw; int passreq = B_TRUE; int flags; int fd; char *infop, *ptr, *p; pid_t pid; int bufsize; struct stat st; char cttyname[100]; char namedlist[500]; char scratchlist[500]; dev_t cttyd; if (geteuid() != 0) { (void) fprintf(stderr, "%s: must be root\n", argv[0]); return (EXIT_FAILURE); } /* Do the magic to determine the children */ if ((fd = open(SYSMSG, 0)) < 0) return (EXIT_FAILURE); /* * If the console supports the CIOCTTYCONSOLE ioctl, then fetch * its console device list. If not, then we use the default * console name. */ if (ioctl(fd, CIOCTTYCONSOLE, &cttyd) == 0) { if ((bufsize = ioctl(fd, CIOCGETCONSOLE, NULL)) < 0) return (EXIT_FAILURE); if (bufsize > 0) { if ((infop = calloc(bufsize, sizeof (char))) == NULL) return (EXIT_FAILURE); if (ioctl(fd, CIOCGETCONSOLE, infop) < 0) return (EXIT_FAILURE); (void) snprintf(namedlist, sizeof (namedlist), "%s %s", DEFAULT_CONSOLE, infop); } else (void) snprintf(namedlist, sizeof (namedlist), "%s", DEFAULT_CONSOLE); } else { (void) snprintf(namedlist, sizeof (namedlist), "%s", DEFAULT_CONSOLE); cttyd = NODEV; } /* * The attempt to turn the controlling terminals dev_t into a string * may not be successful, thus leaving the variable cttyname as a * NULL. This occurs if during boot we find * the root partition (or some other partition) * requires manual fsck, thus resulting in sulogin * getting invoked. The ioctl for CIOCTTYCONSOLE * called above returned NODEV for cttyd * in these cases. NODEV gets returned when the vnode pointer * in our session structure is NULL. In these cases it * must be assumed that the default console is used. * * See uts/common/os/session.c:cttydev(). */ (void) strcpy(cttyname, DEFAULT_CONSOLE); (void) strcpy(scratchlist, namedlist); ptr = scratchlist; while (ptr != NULL) { p = strchr(ptr, ' '); if (p == NULL) { if (stat(ptr, &st)) return (EXIT_FAILURE); if (st.st_rdev == cttyd) (void) strcpy(cttyname, ptr); break; } *p++ = '\0'; if (stat(ptr, &st)) return (EXIT_FAILURE); if (st.st_rdev == cttyd) { (void) strcpy(cttyname, ptr); break; } ptr = p; } /* * Use the same value of SLEEPTIME that login(1) uses. This * is obtained by reading the file /etc/default/login using * the def*() functions. */ if (defopen(DEFAULT_LOGIN) == 0) { /* ignore case */ flags = defcntl(DC_GETFLAGS, 0); TURNOFF(flags, DC_CASE); (void) defcntl(DC_SETFLAGS, flags); if ((ptr = defread("SLEEPTIME=")) != NULL) sleeptime = atoi(ptr); if (sleeptime < 0 || sleeptime > SLEEPTIME_MAX) sleeptime = SLEEPTIME; (void) defopen(NULL); /* closes DEFAULT_LOGIN */ } /* * Use our own value of PASSREQ, separate from the one login(1) uses. * This is obtained by reading the file /etc/default/sulogin using * the def*() functions. */ if (defopen(DEFAULT_SULOGIN) == 0) { if ((ptr = defread("PASSREQ=")) != NULL) if (strcmp("NO", ptr) == 0) passreq = B_FALSE; (void) defopen(NULL); /* closes DEFAULT_SULOGIN */ } if (passreq == B_FALSE) single(shell, NULL); /* * if no 'root' entry in /etc/shadow, give maint. mode single * user shell prompt */ setspent(); if ((shpw = getspnam("root")) == NULL) { (void) fprintf(stderr, "\n*** Unable to retrieve `root' entry " "in shadow password file ***\n\n"); single(shell, NULL); } endspent(); /* * if no 'root' entry in /etc/passwd, give maint. mode single * user shell prompt */ setpwent(); if (getpwnam("root") == NULL) { (void) fprintf(stderr, "\n*** Unable to retrieve `root' entry " "in password file ***\n\n"); single(shell, NULL); } endpwent(); /* process with controlling tty treated special */ if ((pid = fork()) != (pid_t)0) { if (pid == -1) return (EXIT_FAILURE); else { setupsigs(); masterpid = pid; originalpid = getpid(); /* * init() was invoked from a console that was not * the default console, nor was it an auxiliary. */ if (cttyname[0] == NULL) termhandler(0); /* Never returns */ main_loop(cttyname, B_TRUE); /* Never returns */ } } masterpid = getpid(); originalpid = getppid(); pidlist[nchild++] = originalpid; sa.sa_handler = childcleanup; sa.sa_flags = 0; (void) sigemptyset(&sa.sa_mask); (void) sigaction(SIGTERM, &sa, NULL); (void) sigaction(SIGHUP, &sa, NULL); sa.sa_handler = parenthandler; sa.sa_flags = SA_SIGINFO; (void) sigemptyset(&sa.sa_mask); (void) sigaction(SIGUSR1, &sa, NULL); sa.sa_handler = SIG_IGN; sa.sa_flags = 0; (void) sigemptyset(&sa.sa_mask); (void) sigaction(SIGCHLD, &sa, NULL); /* * If there isn't a password on root, then don't permit * the fanout capability of sulogin. */ if (*shpw->sp_pwdp != '\0') { ptr = namedlist; while (ptr != NULL) { p = strchr(ptr, ' '); if (p == NULL) { doit(ptr, cttyname); break; } *p++ = '\0'; doit(ptr, cttyname); ptr = p; } } if (pathcmp(cttyname, DEFAULT_CONSOLE) != 0) { if ((pid = fork()) == (pid_t)0) { setupsigs(); main_loop(DEFAULT_CONSOLE, B_FALSE); } else if (pid == -1) return (EXIT_FAILURE); pidlist[nchild++] = pid; } /* * When parent is all done, it pauses until one of its children * signals that its time to kill the underpriviledged. */ (void) wait(NULL); return (0); }
/* The list in CONSCONFIG gives the persistence capability in the proto */ static void removefromlist(char *dev) { int lckfd; FILE *fp, *nfp; char newfile[MAXPATHLEN + 1]; char len; char value[MAXPATHLEN + 1]; boolean_t newcontents = B_FALSE; /* update file of devices configured to get console msgs. */ lckfd = getlock(); if ((fp = fopen(CONSCONFIG, "r")) == NULL) { (void) close(lckfd); (void) unlink(CONSADMLOCK); return; } /* Open new file */ (void) snprintf(newfile, sizeof (newfile), "%s%d", CONSCONFIG, (int)getpid()); if ((nfp = fopen(newfile, "w")) == NULL) { (void) close(lckfd); (void) unlink(CONSADMLOCK); die(gettext("cannot create new %s file"), CONSCONFIG); } /* Add header to new file */ (void) fprintf(nfp, "%s", conshdr); /* * Check whether the path duplicates what is already in the * file. */ while (fgets(value, MAXPATHLEN, fp) != NULL) { /* skip comments */ if (value[0] == COMMENT || value[0] == NEWLINE || value[0] == SPACE || value[0] == TAB) continue; len = strlen(value); value[len - 1] = NULL; /* Clear carriage return */ if (pathcmp(dev, value) == 0) { /* they match so don't write it */ continue; } (void) fprintf(nfp, "%s\n", value); newcontents = B_TRUE; } (void) fclose(fp); (void) fclose(nfp); /* Remove the file if there aren't any auxiliary consoles */ if (newcontents) (void) rename(newfile, CONSCONFIG); else { (void) unlink(CONSCONFIG); (void) unlink(newfile); } (void) close(lckfd); (void) unlink(CONSADMLOCK); }
/* * special_contents_remove * * Given a set of entries to remove and an alternate root, this function * will do everything required to ensure that the entries are removed * from the contents file if they are listed in the special_contents * file. The contents file will get changed only in the case that the * entire operation has succeeded. * * ient The number of entries. * ppcfent The entries to remove. * pcroot The alternate install root. Could be NULL. In this * case, assume root is '/' * * Result: 0 on success, nonzero on failure. If an error occurs, an * error string will get output to standard error alerting the user. * Side effects: The contents file may change as a result of this call, * such that lines in the in the file will be changed or removed. * If the call fails, a t.contents file may be left behind. This * temporary file should be removed subsequently. */ int special_contents_remove(int ient, struct cfent **ppcfent, const char *pcroot) { int result = 0; /* Assume we will succeed. Return result. */ char **ppcSC = NULL; /* The special contents rules, sorted. */ int i, j; /* Indexes into contents & special contents */ FILE *fpi = NULL, /* Input of contents file */ *fpo = NULL; /* Output to temp contents file */ char cpath[PATH_MAX], /* Contents file path */ tcpath[PATH_MAX]; /* Temp contents file path */ const char *pccontents = VSADMREL "/install/contents"; const char *pctcontents = VSADMREL "/install/t.contents"; char line[LINESZ]; /* Reads in and writes out contents lines. */ time_t t; /* Used to create a timestamp comment. */ int max; /* Max number of special contents entries. */ int *piIndex; /* An index to ppcfents to remove from cfile */ cpath[0] = tcpath[0] = '\0'; if (ient == 0 || ppcfent == NULL || ppcfent[0] == NULL) { goto remove_done; } if ((get_special_contents(pcroot, &ppcSC, &max)) != 0) { result = 1; goto remove_done; } /* Check if there are no special contents actions to take. */ if (ppcSC == NULL) { goto remove_done; } if (pcroot == NULL) pcroot = "/"; if (pcroot[strlen(pcroot) - 1] == '/') { if (snprintf(cpath, PATH_MAX, "%s%s", pcroot, pccontents) >= PATH_MAX || snprintf(tcpath, PATH_MAX, "%s%s", pcroot, pctcontents) >= PATH_MAX) { progerr(gettext(SPECIAL_INPUT)); result = -1; goto remove_done; } } else { if (snprintf(cpath, PATH_MAX, "%s/%s", pcroot, pccontents) >= PATH_MAX || snprintf(tcpath, PATH_MAX, "%s/%s", pcroot, pctcontents) >= PATH_MAX) { progerr(gettext(SPECIAL_INPUT)); result = -1; goto remove_done; } } /* Open the temporary contents file to write, contents to read. */ if (access(cpath, F_OK | R_OK) != 0) { /* * This is not a problem since no contents means nothing * to remove due to special contents rules. */ result = 0; cpath[0] = '\0'; /* This signals omission of 'rename cleanup' */ goto remove_done; } if (access(cpath, W_OK) != 0) { /* can't write contents file, something is wrong. */ progerr(gettext(SPECIAL_ACCESS)); result = 1; goto remove_done; } if ((fpi = fopen(cpath, "r")) == NULL) { /* Given the access test above, this should not happen. */ progerr(gettext(SPECIAL_ACCESS)); result = 1; goto remove_done; } if ((fpo = fopen(tcpath, "w")) == NULL) { /* open t.contents failed */ progerr(gettext(SPECIAL_ACCESS)); result = 1; goto remove_done; } if (generate_special_contents_rules(ient, ppcfent, ppcSC, max, &piIndex) != 0) { result = 1; goto remove_done; } /* * Copy contents to t.contents unless there is an entry in * the ppcfent array which corresponds to an index set to 1. * * These items are the removed package contents which matche an * entry in ppcSC (the special_contents rules). * * Since both the contents and rules are sorted, we can * make a single efficient pass. */ (void) memset(line, 0, LINESZ); for (i = 0, j = 0; fgets(line, LINESZ, fpi) != NULL; ) { char *pcpath = NULL; /* * Note: This could be done better: We should figure out * which are the last 2 lines and only trim those off. * This will suffice to do this and will only be done as * part of special_contents handling. */ if (line[0] == '#') continue; /* Do not copy the final 2 comment lines */ pcpath = get_path(line); if (pcpath != NULL && i < ient) { int k = 0; while (piIndex[i] == 0) i++; if (i < ient) k = pathcmp(pcpath, ppcfent[i]); if (k < 0 || i >= ient) { /* Just copy contents -> t.contents */ /*EMPTY*/ } else if (k == 0) { /* We have a match. Do not copy the content. */ i++; free(pcpath); (void) memset(line, 0, LINESZ); continue; } else while (i < ient) { /* * This is a complex case: The content * entry is further along alphabetically * than the rule. Skip over all rules which * apply until we come to a rule which is * greater than the current entry, or equal * to it. If equal, do not copy, otherwise * do copy the entry. */ if (piIndex[i] == 0) { i++; continue; } else if ((k = pathcmp(pcpath, ppcfent[i])) >= 0) { i++; if (k == 0) { free(pcpath); (void) memset(line, 0, LINESZ); break; } } else { /* path < rule, end special case */ break; } } /* * Avoid copying the old content when path == rule * This occurs when the complex case ends on a match. */ if (k == 0) continue; } if (fprintf(fpo, "%s", line) < 0) { /* Failing to write output would be catastrophic. */ progerr(gettext(SPECIAL_ACCESS)); result = 1; break; } (void) memset(line, 0, LINESZ); } t = time(NULL); (void) fprintf(fpo, "# Last modified by pkgremove\n"); (void) fprintf(fpo, "# %s", ctime(&t)); remove_done: free_special_contents(&ppcSC, max); if (fpi != NULL) (void) fclose(fpi); if (fpo != NULL) (void) fclose(fpo); if (result == 0) { if (tcpath[0] != '\0' && cpath[0] != '\0' && rename(tcpath, cpath) != 0) { progerr(gettext(SPECIAL_ACCESS)); result = 1; } } else { if (tcpath[0] != '\0' && remove(tcpath) != 0) { /* * Do not output a diagnostic message. This condition * occurs only when we are unable to clean up after * a failure. A temporary file will linger. */ result = 1; } } return (result); }
static int sort_dir_list(const void *one, const void *two) { int retval; char *pfirst, *psecond; dir_entry_t *first = (dir_entry_t *) one; dir_entry_t *second = (dir_entry_t *) two; int first_is_dir = 0; int second_is_dir = 0; if(first->type == DIRECTORY) first_is_dir = 1; else if(first->type == LINK) first_is_dir = (first->name[strlen(first->name) - 1] == '/'); if(second->type == DIRECTORY) second_is_dir = 1; else if(second->type == LINK) second_is_dir = (second->name[strlen(second->name) - 1] == '/'); if(first_is_dir != second_is_dir) return first_is_dir ? -1 : 1; if(pathcmp(first->name, "../") == 0) return -1; else if(pathcmp(second->name, "../") == 0) return 1; retval = 0; switch(sort_type) { case SORT_BY_NAME: case SORT_BY_INAME: if(first->name[0] == '.' && second->name[0] != '.') retval = -1; else if(first->name[0] != '.' && second->name[0] == '.') retval = 1; else retval = compare_file_names(first->name, second->name, sort_type == SORT_BY_INAME); break; case SORT_BY_EXTENSION: pfirst = strrchr(first->name, '.'); psecond = strrchr(second->name, '.'); if(pfirst && psecond) retval = compare_file_names(++pfirst, ++psecond, 0); else if(pfirst || psecond) retval = pfirst ? -1 : 1; else retval = compare_file_names(first->name, second->name, 0); break; case SORT_BY_SIZE: { if(first_is_dir) tree_get_data(curr_stats.dirsize_cache, first->name, &first->size); if(second_is_dir) tree_get_data(curr_stats.dirsize_cache, second->name, &second->size); retval = (first->size < second->size) ? -1 : (first->size > second->size); } break; case SORT_BY_TIME_MODIFIED: retval = first->mtime - second->mtime; break; case SORT_BY_TIME_ACCESSED: retval = first->atime - second->atime; break; case SORT_BY_TIME_CHANGED: retval = first->ctime - second->ctime; break; #ifndef _WIN32 case SORT_BY_MODE: retval = first->mode - second->mode; break; case SORT_BY_OWNER_NAME: /* FIXME */ case SORT_BY_OWNER_ID: retval = first->uid - second->uid; break; case SORT_BY_GROUP_NAME: /* FIXME */ case SORT_BY_GROUP_ID: retval = first->gid - second->gid; break; #endif } if(retval == 0) retval = first->list_num - second->list_num; else if(sort_descending) retval = -retval; return retval; }
int w32g_uniq_playlist(int *is_selected_removed) { int nremoved; int i, n, j1, j2, cursel; HWND hListBox; hListBox = playlist_box(); if(hListBox) cursel = ListBox_GetCurSel(hListBox); else cursel = -1; if(is_selected_removed != NULL) *is_selected_removed = 0; nremoved = 0; n = playlist.nfiles; for(i = 0; i < n - 1; i++) { int save_n; /* remove list[i] from list[i+1 .. n-1] */ j1 = j2 = i + 1; save_n = n; while(j2 < save_n) /* j1 <= j2 */ { if(pathcmp(playlist.list[i].filename, playlist.list[j2].filename, 0) == 0) { nremoved++; n--; free(playlist.list[j2].filename); if(j2 == playlist.selected && is_selected_removed != NULL && !*is_selected_removed) { *is_selected_removed = 1; playlist.selected = j1; } if(j2 < playlist.selected) playlist.selected--; if(j2 < cursel) cursel--; } else { playlist.list[j1] = playlist.list[j2]; j1++; } j2++; } } if(nremoved) { for(i = 0; i < nremoved; i++) ListBox_DeleteString(hListBox, --playlist.nfiles); if(cursel >= 0){ ListBox_SetCurSel(hListBox, cursel); SetNumListWnd(cursel,playlist.nfiles); } w32g_update_playlist(); } return nremoved; }
static int mypathcmp(const void *a, const void *b) { const char *x=*(const char **)a; const char *y=*(const char **)b; return pathcmp(x, y); }
static int myalphasort(const struct dirent **a, const struct dirent **b) { return pathcmp((*a)->d_name, (*b)->d_name); }