Files
QNX/lib/util/lsdashl.c
2025-08-20 19:02:58 +08:00

160 lines
3.8 KiB
C

/*
* $QNXLicenseC:
* Copyright 2007, QNX Software Systems. All Rights Reserved.
*
* You must obtain a written license from and pay applicable license fees to QNX
* Software Systems before you may reproduce, modify or distribute this software,
* or any work that includes all or part of this software. Free development
* licenses are available for evaluation and non-commercial purposes. For more
* information visit http://licensing.qnx.com or email licensing@qnx.com.
*
* This file may contain contributions from others. Please review this entire
* file for other proprietary rights or license notices, as well as the QNX
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
* for other information.
* $
*/
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef __MINGW32__
#include <lib/compat.h>
#else
#include <pwd.h>
#include <grp.h>
#endif
#include <lsdashl.h>
struct name_cache {
struct name_cache *next;
unsigned id;
char *name;
} *users, *groups;
#define SIX_MONTHS ((long) 6 * 30 * 24 * 60 * 60) /* same as GNU */
/* make permissions string from file mode */
char *str_mode(mode_t fmode) {
static char perms[1+3+3+3+1]; /* static so we can return it */
char *p = perms;
/* directory ? */
if (S_ISDIR(fmode)) *p='d';
else if (S_ISNAM(fmode)) *p='n';
else if (S_ISLNK(fmode)) *p='l';
else if (S_ISCHR(fmode)) *p='c';
else if (S_ISBLK(fmode)) *p='b';
else if (S_ISSOCK(fmode)) *p='s';
else if (S_ISFIFO(fmode)) *p='p';
else *p='-';
p++;
/* Handle USER permissions */
*p++ = (fmode & S_IRUSR) ? 'r' : '-';
*p++ = (fmode & S_IWUSR) ? 'w' : '-';
if (fmode & S_ISUID)
*p++ = (fmode & S_IXUSR) ? 's' : 'S';
else
*p++ = (fmode & S_IXUSR) ? 'x' : '-';
/* Handle GROUP permissions */
*p++ = (fmode & S_IRGRP) ? 'r' : '-';
*p++ = (fmode & S_IWGRP) ? 'w' : '-';
if (fmode & S_ISGID)
*p++ = (fmode & S_IXGRP) ? 's' : 'L';
else
*p++ = (fmode & S_IXGRP) ? 'x' : '-';
/* Handle OTHER permissions */
*p++ = (fmode & S_IROTH) ? 'r' : '-';
*p++ = (fmode & S_IWOTH) ? 'w' : '-';
if (fmode & S_ISVTX)
*p++ = (fmode & S_IXOTH) ? 't' : 'T';
else
*p++ = (fmode & S_IXOTH) ? 'x' : '-';
*p = 0;
return perms;
}
/* return user name or user id string */
char *uid(uid_t uid) {
return(struid(uid));
}
/* return group name or group id string */
char *gid(gid_t gid) {
return(strgid(gid));
}
/* return the date formatted a la ls */
char *age(time_t then, mode_t mode) {
static time_t now = 0; /* only recompute time() once */
static char date[28]; /* return buffer with date string */
long stale;
if ((then==0L)&&(S_ISCHR(mode))) return "--- -- --:--";
if (now == 0) time(&now);
if ((stale = now - then) < 0)
stale = -stale;
strftime(date, sizeof date, stale < SIX_MONTHS ?
"%h %d %H:%M" : "%h %d %Y", localtime(&then));
return date;
}
char *struid(uid_t id)
{
struct name_cache *tail = users;
struct passwd *pwent;
char *name, buff[6];
while (tail && tail->id != id)
tail = tail->next;
if (tail == 0 || tail->id != id) {
if ((pwent = getpwuid(id)) == 0)
sprintf(name = buff, "%u", id);
else
name = pwent->pw_name;
if ((tail = malloc(sizeof *tail)) == 0)
return name;
tail->id = id;
tail->name = strdup(name);
tail->next = users;
users = tail;
}
return tail->name;
}
char *strgid(gid_t id)
{
struct name_cache *tail = groups;
struct group *grent;
char *name, buff[6];
while (tail && tail->id != id)
tail = tail->next;
if (tail == 0 || tail->id != id) {
if ((grent = getgrgid(id)) == 0)
sprintf(name = buff, "%u", id);
else
name = grent->gr_name;
if ((tail = malloc(sizeof *tail)) == 0)
return name;
tail->id = id;
tail->name = strdup(name);
tail->next = groups;
groups = tail;
}
return tail->name;
}