* This software is Copyright (c) 1986 by Rick Adams.
* Permission is hereby granted to copy, reproduce, redistribute or
* otherwise use this software as long as: there is no monetary
* profit gained specifically from the use or reproduction or this
* software, it is not sold, rented, traded or otherwise marketed, and
* this copyright notice is included prominently in any copy
* The author make no claims as to the fitness or correctness of
* this software for any use whatsoever, and it is provided as is.
* Any use of this software is at the user's own risk.
* funcs - functions used by many programs
static char *SccsId
= "@(#)funcs.c 2.31 1/17/86";
#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
* nglist is a list of newsgroups.
* sublist is a list of subscriptions.
* sublist may have "meta newsgroups" in it.
* All fields are NGDELIM separated,
* and there is an NGDELIM at the end of each argument.
* Currently implemented glitches:
* sublist uses 'all' like shell uses '*', and '.' like shell '/'.
* If subscription X matches Y, it also matches Y.anything.
register char *nglist
, *sublist
;
for (n
= nglist
; *n
!= '\0' && rc
== FALSE
;) {
for (s
= sublist
; *s
!= '\0';) {
rc
= rc
|| ptrncmp(s
, n
);
rc
= rc
&& !ptrncmp(s
+1, n
);
while (*s
++ != NGDELIM
&& *s
!= '\0')
while (*n
++ != NGDELIM
&& *n
!= '\0')
* Compare two newsgroups for equality.
* The first one may be a "meta" newsgroup.
register char *ng1
, *ng2
;
while (*ng1
!= NGDELIM
&& *ng1
!= '\0') {
if (ng1
[0]=='a' && ng1
[1]=='l' && ng1
[2]=='l') {
while (*ng2
!= NGDELIM
&& *ng2
!= '.' && *ng2
!= '\0')
return ptrncmp(ng1
, ng2
);
} else if (*ng1
++ != *ng2
++)
return *ng2
== '.' || *ng2
== NGDELIM
|| *ng2
== '\0';
* This version resets uid, gid, and umask.
* Called with fsubr(ushell, s, NULL)
(void) sprintf(a
, "A=%s", filename
);
for (envp
= env
+ 1 ; *environ
!= NULL
&& envp
< env
+ 98 ; environ
++)
if ((*environ
)[0] != 'A' || (*environ
)[1] != '=')
execle(SHELL
, SHELL
, "-c", s
, (char *)0, env
);
* Fork and call a subroutine with two args.
* Return pid without waiting.
while ((pid
= fork()) == -1)
* Wait on a child process.
int (*onhup
)(), (*onint
)();
onint
= signal(SIGINT
, SIG_IGN
);
onhup
= signal(SIGHUP
, SIG_IGN
);
while ((w
= wait(&status
)) != pid
&& w
!= -1)
(void) signal(SIGINT
, onint
);
(void) signal(SIGHUP
, onhup
);
* Strip trailing newlines, blanks, and tabs from 's'.
* Return TRUE if newline was found, else FALSE.
while (--p
>= s
&& (*p
== '\n' || *p
== ' ' || *p
== '\t'));
register char *name
, *fmode
;
if ((fp
= fopen(name
, fmode
)) == NULL
) {
* IHCC users only see the "filename" that was in trouble,
* not the whole path. (for security!)
fname
= rindex(name
, '/') + 1;
xerror("Cannot open %s (%s): %s", fname
, fmode
, errmsg(errno
));
/* kludge for setuid not being honored for root */
if ((uid
== 0) && (duid
!= 0) && ((*fmode
== 'a') || (*fmode
== 'w')))
(void) chown(name
, duid
, dgid
);
extern char *sys_errlist
[];
(void) sprintf(ebuf
, "Error %d", code
);
return sys_errlist
[code
];
register char *full
, *pref
;
while ((pc
= *pref
++) != '\0') {
static char rbuf
[BUFLEN
];
(void) sprintf(rbuf
, "%s/%s", SPOOL
, ngname
);
for (p
=rbuf
+strlen(SPOOL
); *p
; p
++)
* Return TRUE iff ngname is a valid newsgroup name
fp
= xfopen(ACTIVE
, "r");
while(fgets(abuf
, BUFLEN
, fp
) != NULL
) {
if (*--q
== '\0' && *--p
== ' ') {
xerror(message
, arg1
, arg2
, arg3
)
(void) sprintf(buffer
, message
, arg1
, arg2
, arg3
);
log(fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
_dolog(0, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
logerr(fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
_dolog(1, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
* Log the given message, with printf strings and parameters allowed,
* on the log file, if it can be written. The date and an attempt at
* figuring out the remote system name are also logged.
_dolog(which
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
register char *p
, *logtime
;
char logfname
[BUFLEN
]; /* the log file */
(void) strcpy(rmtsys
, header
.path
);
(void) strcpy(rmtsys
, p
+1);
(void) strcpy(rmtsys
, "local");
(void) sprintf(msg
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
fprintf(stderr
,"%s: %s\n", Progname
, msg
);
for (i
=0; i
<=which
;i
++) {
(void) sprintf(logfname
, "%s/%s", LIB
, lfsuffix
[i
]);
if (access(logfname
, 0) == 0 && (logfile
= fopen(logfname
, "a")) != NULL
) {
#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
flags
= fcntl(fileno(logfile
), F_GETFL
, 0);
(void) fcntl(fileno(logfile
), F_SETFL
, flags
|O_APPEND
);
(void) lseek(fileno(logfile
), 0L, 2);
fprintf(logfile
, "%s\t%s\t%s: %s\n", logtime
,
header
.ident
[0] ? header
.ident
: username
, Progname
, msg
);
fprintf(logfile
, "%s\t%s\t%s\n", logtime
,
* vmslink allows simulation of file linking under VMS.
if (access(outfile
,0) == 0) {
fp
= fopen(outfile
, "w");
(void) fprintf(fp
, "%s", infile
);
* vmsdelete deletes all revisions of a file. It attempts to
* appear as unlink(2) under conventional Unix in other respects.
while (unlink(file
) == 0)
* Convert a Unix file to a VMS fixed record format file by
* executing the 'unixtovms' command.
sprintf(buf
, "exec /etc/unixtovms %s", file
);
* Convert a VMS fixed record format file to a Unix file by
* executing the 'vmstounix' command.
sprintf(buf
,"exec /etc/vmstounix %s", file
);
#if !defined(BSD4_2) && !defined(BSD4_1C)
* make a directory. Also make sure that the directory is owned
#if defined(USG) && !defined(CHEAP)
if (chown(path
, duid
, dgid
) == 0)
(void) chmod(path
, perm
&(~N_UMASK
));
#endif /* USG && !CHEAP */
(void) umask(perm
&N_UMASK
);
(void) execlp("mkdir", "mkdir", path
, (char *)NULL
);
#endif /* !BSD4_2 && ! BSD4_1C */
register char *str
, *chars
;
* This routine checks to see if the posting user is allowed to
* post to the given newsgroup. If the username is not in the file
* $LIBDIR/authorized then the default in the symbol FASCIST is used.
* fascist(user, newgroups)
* Format of the file "authorized" is:
* naughty_person:junk,net.politics
* operator:!net.all,general,test,mod.unix
* An open environment could have FASCIST set to "all"
* and then individual entries could be made in the authorized file
* to prevent certain individuals from posting to such a wide
* Note that a distribution of "all" does NOT mean to allow postings
* only to local groups -- "all" includes "all.all".
* Use "all,!all.all" to get this behavior
* Eugene Spafford spaf@gatech May 22, 1985
fascist(user
, newsgroups
)
register char *user
, *newsgroups
;
char facuser
[BUFLEN
], facgroups
[BUFLEN
], factemp
[BUFLEN
];
/* First, open the necessary file...$LIBDIR/authorized and see if there
* is an entry for this user
(void) strncpy(facgroups
, FASCIST
, BUFLEN
);
sprintf(factemp
, "%s/%s", LIBDIR
, "authorized");
facfd
= fopen(factemp
, "r");
if (facfd
!= NULL
) { /* If no such file, we go with the global default */
while (fscanf(facfd
, "%[^:]:%s\n", facuser
, factemp
) != EOF
)
if (strncmp(facuser
, user
, BUFLEN
) == 0) {
(void) strcat(facgroups
, ",");
(void) strcat(facgroups
, factemp
);
fprintf(stderr
, "facgroups = %s\n", facgroups
);
fprintf(stderr
, "newsgroups = %s\n", newsgroups
);
/* We step through the newsgroups being posted to and check each against
* the restriction list. *ALL* posted groups must match the restriction
* list or we don't allow the posting.
while (*newsgroups
!= '\0') {
while (*newsgroups
!= '\0' && *newsgroups
!= NGDELIM
)
*facptr
++ = *newsgroups
++;
if (*newsgroups
== NGDELIM
)
fprintf(stderr
, "Checking newsgroup '%s'\n", factemp
);
if (ngmatch(factemp
, facgroups
) == FALSE
)
/* must be okay -- return */
fprintf (stderr
, "Newsgroups approved for this poster.\n");