📄 newls.c
字号:
register struct lbuf *ep; register int width; if ((dirf = opendir(dir)) == NULL) { fflush(stdout); fprintf(stderr, "ls: "); perror(dir); err = 2; return; } else { tblocks = 0; while (dentry = readdir(dirf)) { if (aflg==0 && dentry->d_name[0]=='.' && (dentry->d_name[1]=='\0' || dentry->d_name[1]=='.' && dentry->d_name[2]=='\0') ) /* check for directory items '.', '..' */ continue; ep = gstat(makename(dir, dentry->d_name), 0); if (ep==NULL) continue; else { ep->lnum = dentry->d_ino; ep->lname = malloc(dentry->d_namlen + 1); if (ep->lname==NULL) { fflush(stdout); fprintf(stderr, "ls: out of memory\n"); err = 2; nomocore = 1; break; } strcpy(ep->lname, dentry->d_name); } } closedir(dirf); colwidth = fixedwidth + filewidth; }}/* get status of file and recomputes tblocks; * argfl = 1 if file is a name in ls-command and = 0 * for filename in a directory whose name is an * argument in the command; * stores a pointer in flist[nfiles] and * returns that pointer; * returns NULL if failed; */struct lbuf *gstat(file, argfl)char *file;{ extern int stat(), lstat(); int (*statf)() = lstat; struct stat statb, statb1; register struct lbuf *rep; char buf[MAXPATHLEN + 2]; register int cc; char *malloc(), *realloc(); if (nomocore) return(NULL); else if (nfiles >= maxfils) { /* all flist/lbuf pair assigned files time to get some more space */ maxfils += quantn; if((flist=(struct lbuf **)realloc((char *)flist, (unsigned)(maxfils * sizeof(struct lbuf *)))) == NULL || (nxtlbf = (struct lbuf *)malloc((unsigned)(quantn * sizeof(struct lbuf)))) == NULL) { fprintf(stderr, "ls: out of memory\n"); nomocore = 1; return(NULL); } }/* nfiles is reset to nargs for each directory * that is given as an argument maxn is checked * to prevent the assignment of an lbuf to a flist entry * that already has one assigned. */ if(nfiles >= maxn) { rep = nxtlbf++; flist[nfiles++] = rep; maxn = nfiles; }else { rep = flist[nfiles++]; } rep->lflags = 0; rep->llinkto = NULL; if (argfl || statreq) { if ((*statf)(file, &statb) < 0) { if (statf == lstat || lstat(file, &statb) < 0) { fflush(stdout); fprintf(stderr, "ls: "); perror(file); nfiles--; return(NULL); } } else { rep->lnum = statb.st_ino; rep->lsize = statb.st_size; rep->lblks = statb.st_blocks; switch(statb.st_mode&S_IFMT) { case S_IFDIR: rep->ltype = 'd'; break; case S_IFBLK: rep->ltype = 'b'; rep->lsize = statb.st_rdev; break; case S_IFCHR: rep->ltype = 'c'; rep->lsize = statb.st_rdev; break; case S_IFIFO: rep->ltype = 'p'; break; case S_IFSOCK: rep->ltype = 's'; rep->lsize = 0; break; case S_IFLNK: rep->ltype = 'l'; if (lflg) { cc = readlink(file, buf, MAXPATHLEN); if (cc >= 0) { /* * here we follow the symbolic * link to generate the proper * Fflg marker for the object, * eg, /bin -> /pub/bin/ */ buf[cc] = '\0'; rep->llinkto = malloc(strlen(buf) + 1); if (rep->llinkto==NULL) { fflush(stdout); fprintf(stderr, "ls: out of memory\n"); err = 2; nomocore = 1; break; } strcpy(rep->llinkto, buf); } break; } /* * this is a hack from UCB to avoid having * ls /bin behave differently from ls /bin/ * when /bin is a symbolic link. We hack the * hack to have that happen, but only for * explicit arguments, by inspecting argfl. */ if (!argfl || stat(file, &statb1) < 0) break; if ((statb1.st_mode & S_IFMT) == S_IFDIR) { statb = statb1; rep->ltype = 'd'; rep->lsize = statb.st_size; rep->lblks = statb.st_blocks; } break; default: rep->ltype = '-'; } rep->lflags = statb.st_mode & ~S_IFMT; /* mask ISARG and other file-type bits */ rep->luid = statb.st_uid; rep->lgid = statb.st_gid; rep->lnl = statb.st_nlink; rep->lmtime = statb.st_mtime; if (rep->ltype != 'b' && rep->ltype != 'c') tblocks += statb.st_blocks; } } return(rep);}/* returns pathname of the form dir/file; * dir is a null-terminated string; */char *makename(dir, file) char *dir, *file;{ static char dfile[MAXPATHLEN+1]; /* dfile is static as this is returned * by makename(); */ if (strlen(dir)+1+strlen(file) > MAXPATHLEN) { fprintf(stderr, "ls: filename too long\n"); exit(1); } if (strcmp(dir, "") == 0 || strcmp(dir, ".") == 0) { (void) strcpy(dfile, file); return(dfile); } (void) strcpy(dfile, dir); if (dir[strlen(dir) - 1] != '/' && *file != '/') (void) strcat(dfile, "/"); (void) strcat(dfile, file); return(dfile);}/* rest should be done with nameserver or database */#include <pwd.h>#include <grp.h>#include <utmp.h>struct utmp utmp;#define NMAX (sizeof (utmp.ut_name))#define SCPYN(a, b) strncpy(a, b, NMAX)#undef MAXUID#define MAXUID 2048#define MINUID -2 /* for nfs */#define MAXGID 300char namebuf[MAXUID - MINUID][NMAX+1];char (*names)[NMAX+1] = namebuf - MINUID;char outrangename[NMAX+1];int outrangeuid = -1;char groups[MAXGID][NMAX+1];char outrangegroup[NMAX+1];int outrangegid = -1;char *getname(uid){ register struct passwd *pw; extern struct passwd *getpwuid(); if (uid >= MINUID && uid < MAXUID && names[uid][0]) return (&names[uid][0]); if (uid >= MINUID && uid == outrangeuid) return (outrangename); if (uid < MINUID) return (NULL); pw = getpwuid(uid); if (pw == NULL) return (NULL); if (uid >= MINUID && uid < MAXUID) { SCPYN(names[uid], pw->pw_name); return (&names[uid][0]); } outrangeuid = uid; SCPYN(outrangename, pw->pw_name); return (outrangename);}char *getgroup(gid){ register struct group *gr; static init; extern struct group *getgrent(); if (gid >= 0 && gid < MAXGID && groups[gid][0]) return (&groups[gid][0]); if (gid >= 0 && gid == outrangegid) return (outrangegroup);rescan: if (init == 2) { if (gid < MAXGID) return (0); setgrent(); while (gr = getgrent()) { if (gr->gr_gid != gid) continue; outrangegid = gr->gr_gid; SCPYN(outrangegroup, gr->gr_name); endgrent(); return (outrangegroup); } endgrent(); return (0); } if (init == 0) setgrent(), init = 1; while (gr = getgrent()) { if (gr->gr_gid < 0 || gr->gr_gid >= MAXGID) { if (gr->gr_gid == gid) { outrangegid = gr->gr_gid; SCPYN(outrangegroup, gr->gr_name); return (outrangegroup); } continue; } if (groups[gr->gr_gid][0]) continue; SCPYN(groups[gr->gr_gid], gr->gr_name); if (gr->gr_gid == gid) return (&groups[gid][0]); } init = 2; goto rescan;}compar(pp1, pp2) /* return >0 if item pointed by pp2 should appear first */struct lbuf **pp1, **pp2;{ register struct lbuf *p1, *p2; p1 = *pp1; p2 = *pp2;/* compare two names in ls-command one of which is file * and the other is a directory; * this portion is not used for comparing files within * a directory name of ls-command; */ if (p1->lflags&ISARG && p1->ltype=='d') { if (!(p2->lflags&ISARG && p2->ltype=='d')) return(1); } else { if (p2->lflags&ISARG && p2->ltype=='d') return(-1); } return(strcmp(p1->lname, p2->lname));}pprintf(s) register char *s;{ register int c; register int cc; while(c = *s++) { curcol++; putc(c, stdout); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -