1993-08-05 18:28:27 +00:00
|
|
|
|
/* work.c
|
|
|
|
|
Routines to read command files.
|
|
|
|
|
|
1995-08-19 21:30:30 +00:00
|
|
|
|
Copyright (C) 1991, 1992, 1993, 1995 Ian Lance Taylor
|
1993-08-05 18:28:27 +00:00
|
|
|
|
|
|
|
|
|
This file is part of the Taylor UUCP package.
|
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
|
|
|
|
published by the Free Software Foundation; either version 2 of the
|
|
|
|
|
License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
|
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
1995-08-19 21:30:30 +00:00
|
|
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
1993-08-05 18:28:27 +00:00
|
|
|
|
|
|
|
|
|
The author of the program may be contacted at ian@airs.com or
|
1995-08-19 21:30:30 +00:00
|
|
|
|
c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
|
1993-08-05 18:28:27 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "uucp.h"
|
|
|
|
|
|
|
|
|
|
#if USE_RCS_ID
|
1999-08-27 23:37:10 +00:00
|
|
|
|
const char work_rcsid[] = "$FreeBSD$";
|
1993-08-05 18:28:27 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "uudefs.h"
|
|
|
|
|
#include "uuconf.h"
|
|
|
|
|
#include "system.h"
|
|
|
|
|
#include "sysdep.h"
|
|
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
|
|
#if HAVE_OPENDIR
|
|
|
|
|
#if HAVE_DIRENT_H
|
|
|
|
|
#include <dirent.h>
|
|
|
|
|
#else /* ! HAVE_DIRENT_H */
|
|
|
|
|
#include <sys/dir.h>
|
|
|
|
|
#define dirent direct
|
|
|
|
|
#endif /* ! HAVE_DIRENT_H */
|
|
|
|
|
#endif /* HAVE_OPENDIR */
|
|
|
|
|
|
|
|
|
|
/* Local functions. */
|
|
|
|
|
|
|
|
|
|
static char *zswork_directory P((const char *zsystem));
|
|
|
|
|
static boolean fswork_file P((const char *zsystem, const char *zfile,
|
|
|
|
|
char *pbgrade));
|
|
|
|
|
static int iswork_cmp P((constpointer pkey, constpointer pdatum));
|
|
|
|
|
|
|
|
|
|
/* These functions can support multiple actions going on at once.
|
|
|
|
|
This allows the UUCP package to send and receive multiple files at
|
1994-05-07 18:14:43 +00:00
|
|
|
|
the same time. */
|
1993-08-05 18:28:27 +00:00
|
|
|
|
|
1994-05-07 18:14:43 +00:00
|
|
|
|
/* To avoid wasting a lot of time scanning the spool directory, which
|
|
|
|
|
might cause the remote system to time out, we limit each scan to
|
|
|
|
|
pick up at most a certain number of files. */
|
|
|
|
|
#define COMMANDS_PER_SCAN (200)
|
|
|
|
|
|
|
|
|
|
/* The ssfilename structure holds the name of a work file, as well as
|
|
|
|
|
its grade. */
|
|
|
|
|
|
|
|
|
|
struct ssfilename
|
|
|
|
|
{
|
|
|
|
|
char *zfile;
|
|
|
|
|
char bgrade;
|
|
|
|
|
/* Some compiler may need this, and it won't normally hurt. */
|
|
|
|
|
char bdummy;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* The ssfile structure holds a command file name and all the lines
|
1993-08-05 18:28:27 +00:00
|
|
|
|
read in from that command file. The union within the ssline
|
|
|
|
|
structure initially holds a line from the file and then holds a
|
|
|
|
|
pointer back to the ssfile structure; a pointer to this union is
|
|
|
|
|
used as a sequence pointer. The ztemp entry of the ssline
|
|
|
|
|
structure holds the name of a temporary file to delete, if any. */
|
|
|
|
|
|
|
|
|
|
#define CFILELINES (10)
|
|
|
|
|
|
|
|
|
|
struct ssline
|
|
|
|
|
{
|
|
|
|
|
char *zline;
|
|
|
|
|
struct ssfile *qfile;
|
|
|
|
|
char *ztemp;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ssfile
|
|
|
|
|
{
|
|
|
|
|
char *zfile;
|
1994-05-07 18:14:43 +00:00
|
|
|
|
char bgrade;
|
|
|
|
|
/* bdummy is needed for some buggy compilers. */
|
|
|
|
|
char bdummy;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
int clines;
|
|
|
|
|
int cdid;
|
|
|
|
|
struct ssline aslines[CFILELINES];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Static variables for the work scan. */
|
|
|
|
|
|
1994-05-07 18:14:43 +00:00
|
|
|
|
static struct ssfilename *asSwork_files;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
static size_t cSwork_files;
|
|
|
|
|
static size_t iSwork_file;
|
|
|
|
|
static struct ssfile *qSwork_file;
|
|
|
|
|
|
|
|
|
|
/* Given a system name, return a directory to search for work. */
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
zswork_directory (zsystem)
|
|
|
|
|
const char *zsystem;
|
|
|
|
|
{
|
|
|
|
|
#if SPOOLDIR_V2
|
|
|
|
|
return zbufcpy (".");
|
|
|
|
|
#endif /* SPOOLDIR_V2 */
|
|
|
|
|
#if SPOOLDIR_BSD42 || SPOOLDIR_BSD43
|
|
|
|
|
return zbufcpy ("C.");
|
|
|
|
|
#endif /* SPOOLDIR_BSD42 || SPOOLDIR_BSD43 */
|
|
|
|
|
#if SPOOLDIR_HDB || SPOOLDIR_SVR4
|
|
|
|
|
return zbufcpy (zsystem);
|
|
|
|
|
#endif /* SPOOLDIR_HDB || SPOOLDIR_SVR4 */
|
|
|
|
|
#if SPOOLDIR_ULTRIX
|
|
|
|
|
return zsappend3 ("sys",
|
|
|
|
|
(fsultrix_has_spool (zsystem)
|
|
|
|
|
? zsystem
|
|
|
|
|
: "DEFAULT"),
|
|
|
|
|
"C.");
|
|
|
|
|
#endif /* SPOOLDIR_ULTRIX */
|
|
|
|
|
#if SPOOLDIR_TAYLOR
|
|
|
|
|
return zsysdep_in_dir (zsystem, "C.");
|
|
|
|
|
#endif /* SPOOLDIR_TAYLOR */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* See whether a file name from the directory returned by
|
|
|
|
|
zswork_directory is really a command for a particular system.
|
|
|
|
|
Return the command grade. */
|
|
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
|
static boolean
|
|
|
|
|
fswork_file (zsystem, zfile, pbgrade)
|
|
|
|
|
const char *zsystem;
|
|
|
|
|
const char *zfile;
|
|
|
|
|
char *pbgrade;
|
|
|
|
|
{
|
|
|
|
|
#if SPOOLDIR_V2 || SPOOLDIR_BSD42 || SPOOLDIR_BSD43 || SPOOLDIR_ULTRIX
|
|
|
|
|
int cfilesys, csys;
|
|
|
|
|
|
|
|
|
|
/* The file name should be C.ssssssgqqqq, where g is exactly one
|
|
|
|
|
letter and qqqq is exactly four numbers. The system name may be
|
|
|
|
|
truncated to six or seven characters. The system name of the
|
|
|
|
|
file must match the system name we're looking for, since there
|
|
|
|
|
could be work files for several systems in one directory. */
|
|
|
|
|
if (zfile[0] != 'C' || zfile[1] != '.')
|
|
|
|
|
return FALSE;
|
|
|
|
|
csys = strlen (zsystem);
|
|
|
|
|
cfilesys = strlen (zfile) - 7;
|
|
|
|
|
if (csys != cfilesys
|
|
|
|
|
&& (csys < 6 || (cfilesys != 6 && cfilesys != 7)))
|
|
|
|
|
return FALSE;
|
|
|
|
|
*pbgrade = zfile[cfilesys + 2];
|
|
|
|
|
return strncmp (zfile + 2, zsystem, cfilesys) == 0;
|
|
|
|
|
#endif /* V2 || BSD42 || BSD43 || ULTRIX */
|
|
|
|
|
#if SPOOLDIR_HDB || SPOOLDIR_SVR4
|
|
|
|
|
int clen;
|
|
|
|
|
|
|
|
|
|
/* The HDB file name should be C.ssssssgqqqq where g is exactly one
|
|
|
|
|
letter and qqqq is exactly four numbers or letters. We don't
|
|
|
|
|
check the system name, because it is guaranteed by the directory
|
|
|
|
|
we are looking in and some versions of uucp set it to the local
|
|
|
|
|
system rather than the remote one. I'm not sure of the exact
|
|
|
|
|
format of the SVR4 file name, but it does not include the grade
|
|
|
|
|
at all. */
|
|
|
|
|
if (zfile[0] != 'C' || zfile[1] != '.')
|
|
|
|
|
return FALSE;
|
|
|
|
|
clen = strlen (zfile);
|
|
|
|
|
if (clen < 7)
|
|
|
|
|
return FALSE;
|
|
|
|
|
#if ! SPOOLDIR_SVR4
|
|
|
|
|
*pbgrade = zfile[clen - 5];
|
|
|
|
|
#endif
|
|
|
|
|
return TRUE;
|
|
|
|
|
#endif /* SPOOLDIR_HDB || SPOOLDIR_SVR4 */
|
|
|
|
|
#if SPOOLDIR_TAYLOR
|
|
|
|
|
/* We don't keep the system name in the file name, since that
|
|
|
|
|
forces truncation. Our file names are always C.gqqqq. */
|
|
|
|
|
*pbgrade = zfile[2];
|
|
|
|
|
return (zfile[0] == 'C'
|
|
|
|
|
&& zfile[1] == '.'
|
1995-08-19 21:30:30 +00:00
|
|
|
|
&& zfile[2] != '\0');
|
1993-08-05 18:28:27 +00:00
|
|
|
|
#endif /* SPOOLDIR_TAYLOR */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* A comparison function to look through the list of file names. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
iswork_cmp (pkey, pdatum)
|
|
|
|
|
constpointer pkey;
|
|
|
|
|
constpointer pdatum;
|
|
|
|
|
{
|
1994-05-07 18:14:43 +00:00
|
|
|
|
const struct ssfilename *qkey = (const struct ssfilename *) pkey;
|
|
|
|
|
const struct ssfilename *qdatum = (const struct ssfilename *) pdatum;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
|
1994-05-07 18:14:43 +00:00
|
|
|
|
return strcmp (qkey->zfile, qdatum->zfile);
|
1993-08-05 18:28:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* See whether there is any work to do for a particular system. */
|
|
|
|
|
|
|
|
|
|
boolean
|
|
|
|
|
fsysdep_has_work (qsys)
|
|
|
|
|
const struct uuconf_system *qsys;
|
|
|
|
|
{
|
|
|
|
|
char *zdir;
|
|
|
|
|
DIR *qdir;
|
|
|
|
|
struct dirent *qentry;
|
|
|
|
|
#if SPOOLDIR_SVR4
|
|
|
|
|
DIR *qgdir;
|
|
|
|
|
struct dirent *qgentry;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
zdir = zswork_directory (qsys->uuconf_zname);
|
|
|
|
|
if (zdir == NULL)
|
|
|
|
|
return FALSE;
|
|
|
|
|
qdir = opendir ((char *) zdir);
|
|
|
|
|
if (qdir == NULL)
|
|
|
|
|
{
|
|
|
|
|
ubuffree (zdir);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if SPOOLDIR_SVR4
|
|
|
|
|
qgdir = qdir;
|
|
|
|
|
while ((qgentry = readdir (qgdir)) != NULL)
|
|
|
|
|
{
|
|
|
|
|
char *zsub;
|
|
|
|
|
|
|
|
|
|
if (qgentry->d_name[0] == '.'
|
|
|
|
|
|| qgentry->d_name[1] != '\0')
|
|
|
|
|
continue;
|
|
|
|
|
zsub = zsysdep_in_dir (zdir, qgentry->d_name);
|
|
|
|
|
qdir = opendir (zsub);
|
|
|
|
|
ubuffree (zsub);
|
|
|
|
|
if (qdir == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
while ((qentry = readdir (qdir)) != NULL)
|
|
|
|
|
{
|
|
|
|
|
char bgrade;
|
|
|
|
|
|
|
|
|
|
if (fswork_file (qsys->uuconf_zname, qentry->d_name, &bgrade))
|
|
|
|
|
{
|
|
|
|
|
closedir (qdir);
|
|
|
|
|
#if SPOOLDIR_SVR4
|
|
|
|
|
closedir (qgdir);
|
|
|
|
|
#endif
|
|
|
|
|
ubuffree (zdir);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if SPOOLDIR_SVR4
|
|
|
|
|
closedir (qdir);
|
|
|
|
|
}
|
|
|
|
|
qdir = qgdir;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
closedir (qdir);
|
|
|
|
|
ubuffree (zdir);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Initialize the work scan. We have to read all the files in the
|
|
|
|
|
work directory, so that we can sort them by work grade. The bgrade
|
|
|
|
|
argument is the minimum grade to consider. We don't want to return
|
|
|
|
|
files that we have already considered; usysdep_get_work_free will
|
|
|
|
|
clear the data out when we are done with the system. This returns
|
|
|
|
|
FALSE on error. */
|
|
|
|
|
|
|
|
|
|
#define CWORKFILES (10)
|
|
|
|
|
|
|
|
|
|
boolean
|
|
|
|
|
fsysdep_get_work_init (qsys, bgrade)
|
|
|
|
|
const struct uuconf_system *qsys;
|
|
|
|
|
int bgrade;
|
|
|
|
|
{
|
|
|
|
|
char *zdir;
|
|
|
|
|
DIR *qdir;
|
|
|
|
|
struct dirent *qentry;
|
|
|
|
|
size_t chad;
|
|
|
|
|
size_t callocated;
|
|
|
|
|
#if SPOOLDIR_SVR4
|
|
|
|
|
DIR *qgdir;
|
|
|
|
|
struct dirent *qgentry;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
zdir = zswork_directory (qsys->uuconf_zname);
|
|
|
|
|
if (zdir == NULL)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
qdir = opendir (zdir);
|
|
|
|
|
if (qdir == NULL)
|
|
|
|
|
{
|
|
|
|
|
boolean fret;
|
|
|
|
|
|
|
|
|
|
if (errno == ENOENT)
|
|
|
|
|
fret = TRUE;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ulog (LOG_ERROR, "opendir (%s): %s", zdir, strerror (errno));
|
|
|
|
|
fret = FALSE;
|
|
|
|
|
}
|
|
|
|
|
ubuffree (zdir);
|
|
|
|
|
return fret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chad = cSwork_files;
|
|
|
|
|
callocated = cSwork_files;
|
|
|
|
|
|
|
|
|
|
/* Sort the files we already know about so that we can check the new
|
|
|
|
|
ones with bsearch. It would be faster to use a hash table, and
|
|
|
|
|
the code should be probably be changed. The sort done at the end
|
|
|
|
|
of this function does not suffice because it only includes the
|
|
|
|
|
files added last time, and does not sort the entire array. Some
|
|
|
|
|
(bad) qsort implementations are very slow when given a sorted
|
|
|
|
|
array, which causes particularly bad effects here. */
|
|
|
|
|
if (chad > 0)
|
1994-05-07 18:14:43 +00:00
|
|
|
|
qsort ((pointer) asSwork_files, chad, sizeof (struct ssfilename),
|
|
|
|
|
iswork_cmp);
|
1993-08-05 18:28:27 +00:00
|
|
|
|
|
|
|
|
|
#if SPOOLDIR_SVR4
|
|
|
|
|
qgdir = qdir;
|
|
|
|
|
while ((qgentry = readdir (qgdir)) != NULL)
|
|
|
|
|
{
|
|
|
|
|
char *zsub;
|
|
|
|
|
|
|
|
|
|
if (qgentry->d_name[0] == '.'
|
|
|
|
|
|| qgentry->d_name[1] != '\0'
|
|
|
|
|
|| UUCONF_GRADE_CMP (bgrade, qgentry->d_name[0]) < 0)
|
|
|
|
|
continue;
|
|
|
|
|
zsub = zsysdep_in_dir (zdir, qgentry->d_name);
|
|
|
|
|
qdir = opendir (zsub);
|
|
|
|
|
if (qdir == NULL)
|
|
|
|
|
{
|
|
|
|
|
if (errno != ENOTDIR && errno != ENOENT)
|
|
|
|
|
{
|
|
|
|
|
ulog (LOG_ERROR, "opendir (%s): %s", zsub,
|
|
|
|
|
strerror (errno));
|
|
|
|
|
ubuffree (zsub);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
ubuffree (zsub);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
ubuffree (zsub);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
while ((qentry = readdir (qdir)) != NULL)
|
|
|
|
|
{
|
|
|
|
|
char bfilegrade;
|
|
|
|
|
char *zname;
|
1994-05-07 18:14:43 +00:00
|
|
|
|
struct ssfilename slook;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
|
|
|
|
|
#if ! SPOOLDIR_SVR4
|
|
|
|
|
zname = zbufcpy (qentry->d_name);
|
|
|
|
|
#else
|
|
|
|
|
zname = zsysdep_in_dir (qgentry->d_name, qentry->d_name);
|
|
|
|
|
bfilegrade = qgentry->d_name[0];
|
|
|
|
|
#endif
|
|
|
|
|
|
1994-05-07 18:14:43 +00:00
|
|
|
|
slook.zfile = zname;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
if (! fswork_file (qsys->uuconf_zname, qentry->d_name,
|
|
|
|
|
&bfilegrade)
|
|
|
|
|
|| UUCONF_GRADE_CMP (bgrade, bfilegrade) < 0
|
1994-05-07 18:14:43 +00:00
|
|
|
|
|| (asSwork_files != NULL
|
|
|
|
|
&& bsearch ((pointer) &slook,
|
|
|
|
|
(pointer) asSwork_files,
|
|
|
|
|
chad, sizeof (struct ssfilename),
|
1993-08-05 18:28:27 +00:00
|
|
|
|
iswork_cmp) != NULL))
|
|
|
|
|
ubuffree (zname);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DEBUG_MESSAGE1 (DEBUG_SPOOLDIR,
|
|
|
|
|
"fsysdep_get_work_init: Found %s",
|
|
|
|
|
zname);
|
|
|
|
|
|
|
|
|
|
if (cSwork_files >= callocated)
|
|
|
|
|
{
|
|
|
|
|
callocated += CWORKFILES;
|
1994-05-07 18:14:43 +00:00
|
|
|
|
asSwork_files =
|
|
|
|
|
((struct ssfilename *)
|
|
|
|
|
xrealloc ((pointer) asSwork_files,
|
|
|
|
|
(callocated * sizeof (struct ssfilename))));
|
1993-08-05 18:28:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
1994-05-07 18:14:43 +00:00
|
|
|
|
asSwork_files[cSwork_files].zfile = zname;
|
|
|
|
|
asSwork_files[cSwork_files].bgrade = bfilegrade;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
++cSwork_files;
|
1994-05-07 18:14:43 +00:00
|
|
|
|
if (cSwork_files - chad > COMMANDS_PER_SCAN)
|
|
|
|
|
break;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if SPOOLDIR_SVR4
|
|
|
|
|
closedir (qdir);
|
1994-05-07 18:14:43 +00:00
|
|
|
|
if (cSwork_files - chad > COMMANDS_PER_SCAN)
|
|
|
|
|
break;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
}
|
|
|
|
|
qdir = qgdir;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
closedir (qdir);
|
|
|
|
|
ubuffree (zdir);
|
|
|
|
|
|
|
|
|
|
/* Sorting the files alphabetically will get the grades in the
|
|
|
|
|
right order, since all the file prefixes are the same. */
|
1994-05-07 18:14:43 +00:00
|
|
|
|
if (cSwork_files > iSwork_file)
|
|
|
|
|
qsort ((pointer) (asSwork_files + iSwork_file),
|
|
|
|
|
cSwork_files - iSwork_file,
|
|
|
|
|
sizeof (struct ssfilename), iswork_cmp);
|
1993-08-05 18:28:27 +00:00
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the next work entry for a system. This must parse the next
|
|
|
|
|
line in the next work file. The type of command is set into
|
1995-08-19 21:30:30 +00:00
|
|
|
|
qcmd->bcmd If there are no more commands, qcmd->bcmd is set to 'H'.
|
1993-08-05 18:28:27 +00:00
|
|
|
|
Each field in the structure is set to point to a spot in an
|
1995-08-19 21:30:30 +00:00
|
|
|
|
malloced string. The grade argument is never used; it has been
|
|
|
|
|
used by fsysdep_get_work_init. */
|
1993-08-05 18:28:27 +00:00
|
|
|
|
|
1995-08-19 21:30:30 +00:00
|
|
|
|
/*ARGSUSED*/
|
1993-08-05 18:28:27 +00:00
|
|
|
|
boolean
|
|
|
|
|
fsysdep_get_work (qsys, bgrade, qcmd)
|
|
|
|
|
const struct uuconf_system *qsys;
|
|
|
|
|
int bgrade;
|
|
|
|
|
struct scmd *qcmd;
|
|
|
|
|
{
|
|
|
|
|
char *zdir;
|
|
|
|
|
|
|
|
|
|
if (qSwork_file != NULL && qSwork_file->cdid >= qSwork_file->clines)
|
|
|
|
|
qSwork_file = NULL;
|
|
|
|
|
|
1994-05-07 18:14:43 +00:00
|
|
|
|
if (asSwork_files == NULL)
|
1993-08-05 18:28:27 +00:00
|
|
|
|
{
|
|
|
|
|
qcmd->bcmd = 'H';
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zdir = NULL;
|
|
|
|
|
|
|
|
|
|
/* This loop continues until a line is returned. */
|
|
|
|
|
while (TRUE)
|
|
|
|
|
{
|
|
|
|
|
/* This loop continues until a file is opened and read in. */
|
|
|
|
|
while (qSwork_file == NULL)
|
|
|
|
|
{
|
|
|
|
|
FILE *e;
|
|
|
|
|
struct ssfile *qfile;
|
|
|
|
|
int iline, callocated;
|
|
|
|
|
char *zline;
|
|
|
|
|
size_t cline;
|
|
|
|
|
char *zname;
|
1994-05-07 18:14:43 +00:00
|
|
|
|
char bfilegrade;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
|
|
|
|
|
/* Read all the lines of a command file into memory. */
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
if (iSwork_file >= cSwork_files)
|
|
|
|
|
{
|
1995-08-19 21:30:30 +00:00
|
|
|
|
qcmd->bcmd = 'H';
|
|
|
|
|
ubuffree (zdir);
|
|
|
|
|
return TRUE;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (zdir == NULL)
|
|
|
|
|
{
|
|
|
|
|
zdir = zswork_directory (qsys->uuconf_zname);
|
|
|
|
|
if (zdir == NULL)
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
1994-05-07 18:14:43 +00:00
|
|
|
|
zname = zsysdep_in_dir (zdir, asSwork_files[iSwork_file].zfile);
|
|
|
|
|
bfilegrade = asSwork_files[iSwork_file].bgrade;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
|
|
|
|
|
++iSwork_file;
|
|
|
|
|
|
|
|
|
|
e = fopen (zname, "r");
|
|
|
|
|
if (e == NULL)
|
|
|
|
|
{
|
|
|
|
|
ulog (LOG_ERROR, "fopen (%s): %s", zname,
|
|
|
|
|
strerror (errno));
|
|
|
|
|
ubuffree (zname);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while (e == NULL);
|
1995-08-19 21:30:30 +00:00
|
|
|
|
|
1993-08-05 18:28:27 +00:00
|
|
|
|
qfile = (struct ssfile *) xmalloc (sizeof (struct ssfile));
|
|
|
|
|
callocated = CFILELINES;
|
|
|
|
|
iline = 0;
|
|
|
|
|
|
|
|
|
|
zline = NULL;
|
|
|
|
|
cline = 0;
|
|
|
|
|
while (getline (&zline, &cline, e) > 0)
|
|
|
|
|
{
|
|
|
|
|
if (iline >= callocated)
|
|
|
|
|
{
|
|
|
|
|
/* The sizeof (struct ssfile) includes CFILELINES
|
|
|
|
|
entries already, so using callocated * sizeof
|
|
|
|
|
(struct ssline) will give us callocated *
|
|
|
|
|
CFILELINES entries. */
|
|
|
|
|
qfile =
|
|
|
|
|
((struct ssfile *)
|
|
|
|
|
xrealloc ((pointer) qfile,
|
|
|
|
|
(sizeof (struct ssfile) +
|
|
|
|
|
(callocated * sizeof (struct ssline)))));
|
|
|
|
|
callocated += CFILELINES;
|
|
|
|
|
}
|
|
|
|
|
qfile->aslines[iline].zline = zbufcpy (zline);
|
|
|
|
|
qfile->aslines[iline].qfile = NULL;
|
|
|
|
|
qfile->aslines[iline].ztemp = NULL;
|
|
|
|
|
iline++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xfree ((pointer) zline);
|
|
|
|
|
|
|
|
|
|
if (fclose (e) != 0)
|
|
|
|
|
ulog (LOG_ERROR, "fclose: %s", strerror (errno));
|
|
|
|
|
|
|
|
|
|
if (iline == 0)
|
|
|
|
|
{
|
|
|
|
|
/* There were no lines in the file; this is a poll file,
|
|
|
|
|
for which we return a 'P' command. */
|
|
|
|
|
qfile->aslines[0].zline = zbufcpy ("P");
|
|
|
|
|
qfile->aslines[0].qfile = NULL;
|
|
|
|
|
qfile->aslines[0].ztemp = NULL;
|
|
|
|
|
iline = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qfile->zfile = zname;
|
1994-05-07 18:14:43 +00:00
|
|
|
|
qfile->bgrade = bfilegrade;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
qfile->clines = iline;
|
|
|
|
|
qfile->cdid = 0;
|
|
|
|
|
qSwork_file = qfile;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This loop continues until all the lines from the current file
|
|
|
|
|
are used up, or a line is returned. */
|
|
|
|
|
while (TRUE)
|
|
|
|
|
{
|
|
|
|
|
int iline;
|
1995-08-19 21:30:30 +00:00
|
|
|
|
|
1993-08-05 18:28:27 +00:00
|
|
|
|
if (qSwork_file->cdid >= qSwork_file->clines)
|
|
|
|
|
{
|
|
|
|
|
/* We don't want to free qSwork_file here, since it must
|
|
|
|
|
remain until all the lines have been completed. It
|
|
|
|
|
is freed in fsysdep_did_work. */
|
|
|
|
|
qSwork_file = NULL;
|
|
|
|
|
/* Go back to the main loop which finds another file. */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iline = qSwork_file->cdid;
|
|
|
|
|
++qSwork_file->cdid;
|
|
|
|
|
|
|
|
|
|
/* Now parse the line into a command. */
|
|
|
|
|
if (! fparse_cmd (qSwork_file->aslines[iline].zline, qcmd))
|
|
|
|
|
{
|
|
|
|
|
ulog (LOG_ERROR, "Bad line in command file %s",
|
|
|
|
|
qSwork_file->zfile);
|
|
|
|
|
ubuffree (qSwork_file->aslines[iline].zline);
|
|
|
|
|
qSwork_file->aslines[iline].zline = NULL;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
1994-05-07 18:14:43 +00:00
|
|
|
|
qcmd->bgrade = qSwork_file->bgrade;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
|
|
|
|
|
qSwork_file->aslines[iline].qfile = qSwork_file;
|
|
|
|
|
qcmd->pseq = (pointer) (&qSwork_file->aslines[iline]);
|
|
|
|
|
|
|
|
|
|
if (qcmd->bcmd == 'S' || qcmd->bcmd == 'E')
|
|
|
|
|
{
|
|
|
|
|
char *zreal;
|
|
|
|
|
|
|
|
|
|
zreal = zsysdep_spool_file_name (qsys, qcmd->ztemp,
|
|
|
|
|
qcmd->pseq);
|
|
|
|
|
if (zreal == NULL)
|
|
|
|
|
{
|
|
|
|
|
ubuffree (qSwork_file->aslines[iline].zline);
|
|
|
|
|
qSwork_file->aslines[iline].zline = NULL;
|
|
|
|
|
ubuffree (zdir);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
qSwork_file->aslines[iline].ztemp = zreal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ubuffree (zdir);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* When a command has been complete, fsysdep_did_work is called. The
|
|
|
|
|
sequence entry was set above to be the address of an aslines
|
|
|
|
|
structure whose pfile entry points to the ssfile corresponding to
|
|
|
|
|
this file. We can then check whether all the lines have been
|
|
|
|
|
completed (they will have been if the pfile entry is NULL) and
|
|
|
|
|
remove the file if they have been. This means that we only remove
|
|
|
|
|
a command file if we manage to complete every transfer it specifies
|
|
|
|
|
in a single UUCP session. I don't know if this is how regular UUCP
|
|
|
|
|
works. */
|
|
|
|
|
|
|
|
|
|
boolean
|
|
|
|
|
fsysdep_did_work (pseq)
|
|
|
|
|
pointer pseq;
|
|
|
|
|
{
|
|
|
|
|
struct ssfile *qfile;
|
|
|
|
|
struct ssline *qline;
|
|
|
|
|
int i;
|
1995-08-19 21:30:30 +00:00
|
|
|
|
|
1993-08-05 18:28:27 +00:00
|
|
|
|
qline = (struct ssline *) pseq;
|
|
|
|
|
|
|
|
|
|
ubuffree (qline->zline);
|
|
|
|
|
qline->zline = NULL;
|
|
|
|
|
|
|
|
|
|
qfile = qline->qfile;
|
|
|
|
|
qline->qfile = NULL;
|
|
|
|
|
|
|
|
|
|
/* Remove the temporary file, if there is one. It really doesn't
|
|
|
|
|
matter if this fails, and not checking the return value lets us
|
|
|
|
|
attempt to remove D.0 or whatever an unused temporary file is
|
|
|
|
|
called without complaining. */
|
|
|
|
|
if (qline->ztemp != NULL)
|
|
|
|
|
{
|
|
|
|
|
(void) remove (qline->ztemp);
|
|
|
|
|
ubuffree (qline->ztemp);
|
|
|
|
|
qline->ztemp = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If not all the lines have been returned from fsysdep_get_work,
|
|
|
|
|
we can't remove the file yet. */
|
|
|
|
|
if (qfile->cdid < qfile->clines)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
/* See whether all the commands have been completed. */
|
|
|
|
|
for (i = 0; i < qfile->clines; i++)
|
|
|
|
|
if (qfile->aslines[i].qfile != NULL)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
/* All commands have finished. */
|
|
|
|
|
if (remove (qfile->zfile) != 0)
|
|
|
|
|
{
|
|
|
|
|
ulog (LOG_ERROR, "remove (%s): %s", qfile->zfile,
|
|
|
|
|
strerror (errno));
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ubuffree (qfile->zfile);
|
|
|
|
|
xfree ((pointer) qfile);
|
|
|
|
|
|
|
|
|
|
if (qfile == qSwork_file)
|
|
|
|
|
qSwork_file = NULL;
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free up the results of a work scan, when we're done with this
|
|
|
|
|
system. */
|
|
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
|
void
|
|
|
|
|
usysdep_get_work_free (qsys)
|
|
|
|
|
const struct uuconf_system *qsys;
|
|
|
|
|
{
|
1994-05-07 18:14:43 +00:00
|
|
|
|
if (asSwork_files != NULL)
|
1993-08-05 18:28:27 +00:00
|
|
|
|
{
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < cSwork_files; i++)
|
1994-05-07 18:14:43 +00:00
|
|
|
|
ubuffree ((pointer) asSwork_files[i].zfile);
|
|
|
|
|
xfree ((pointer) asSwork_files);
|
|
|
|
|
asSwork_files = NULL;
|
1993-08-05 18:28:27 +00:00
|
|
|
|
cSwork_files = 0;
|
|
|
|
|
iSwork_file = 0;
|
|
|
|
|
}
|
|
|
|
|
if (qSwork_file != NULL)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
ubuffree (qSwork_file->zfile);
|
|
|
|
|
for (i = 0; i < qSwork_file->cdid; i++)
|
|
|
|
|
{
|
|
|
|
|
ubuffree (qSwork_file->aslines[i].zline);
|
|
|
|
|
ubuffree (qSwork_file->aslines[i].ztemp);
|
|
|
|
|
}
|
|
|
|
|
for (i = qSwork_file->cdid; i < qSwork_file->clines; i++)
|
|
|
|
|
ubuffree (qSwork_file->aslines[i].zline);
|
|
|
|
|
xfree ((pointer) qSwork_file);
|
|
|
|
|
qSwork_file = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Save the temporary file used by a send command, and return an
|
|
|
|
|
informative message to mail to the requestor. This is called when
|
|
|
|
|
a file transfer failed, to make sure that the potentially valuable
|
|
|
|
|
file is not completely lost. */
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
zsysdep_save_temp_file (pseq)
|
|
|
|
|
pointer pseq;
|
|
|
|
|
{
|
|
|
|
|
struct ssline *qline = (struct ssline *) pseq;
|
|
|
|
|
char *zto, *zslash;
|
|
|
|
|
size_t cwant;
|
|
|
|
|
static char *zbuf;
|
|
|
|
|
static int cbuf;
|
|
|
|
|
|
|
|
|
|
if (! fsysdep_file_exists (qline->ztemp))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
zslash = strrchr (qline->ztemp, '/');
|
|
|
|
|
if (zslash == NULL)
|
|
|
|
|
zslash = qline->ztemp;
|
|
|
|
|
else
|
|
|
|
|
++zslash;
|
|
|
|
|
|
|
|
|
|
zto = zbufalc (sizeof PRESERVEDIR + sizeof "/" + strlen (zslash));
|
|
|
|
|
sprintf (zto, "%s/%s", PRESERVEDIR, zslash);
|
|
|
|
|
|
|
|
|
|
if (! fsysdep_move_file (qline->ztemp, zto, TRUE, FALSE, FALSE,
|
|
|
|
|
(const char *) NULL))
|
|
|
|
|
{
|
1994-05-07 18:14:43 +00:00
|
|
|
|
/* Leave the file where it was, not that is much help. */
|
1993-08-05 18:28:27 +00:00
|
|
|
|
ubuffree (zto);
|
|
|
|
|
return "Could not move file to preservation directory";
|
|
|
|
|
}
|
1995-08-19 21:30:30 +00:00
|
|
|
|
|
1993-08-05 18:28:27 +00:00
|
|
|
|
cwant = sizeof "File saved as\n\t/" + strlen (zSspooldir) + strlen (zto);
|
|
|
|
|
if (cwant > cbuf)
|
|
|
|
|
{
|
|
|
|
|
ubuffree (zbuf);
|
|
|
|
|
zbuf = zbufalc (cwant);
|
|
|
|
|
cbuf = cwant;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sprintf (zbuf, "File saved as\n\t%s/%s", zSspooldir, zto);
|
|
|
|
|
ubuffree (zto);
|
|
|
|
|
return zbuf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the jobid of a work file. This is needed by uustat. */
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
zsysdep_jobid (qsys, pseq)
|
|
|
|
|
const struct uuconf_system *qsys;
|
|
|
|
|
pointer pseq;
|
|
|
|
|
{
|
|
|
|
|
return zsfile_to_jobid (qsys, ((struct ssline *) pseq)->qfile->zfile,
|
|
|
|
|
bsgrade (pseq));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the grade of a work file. The pseq argument can be NULL when
|
|
|
|
|
this is called from zsysdep_spool_file_name, and simply means that
|
|
|
|
|
this is a remote file; returning -1 will cause zsfind_file to do
|
|
|
|
|
the right thing. */
|
|
|
|
|
|
1994-05-07 18:14:43 +00:00
|
|
|
|
int
|
1993-08-05 18:28:27 +00:00
|
|
|
|
bsgrade (pseq)
|
|
|
|
|
pointer pseq;
|
|
|
|
|
{
|
|
|
|
|
const char *zfile;
|
|
|
|
|
char bgrade;
|
|
|
|
|
|
|
|
|
|
if (pseq == NULL)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
zfile = ((struct ssline *) pseq)->qfile->zfile;
|
|
|
|
|
|
1995-08-19 21:30:30 +00:00
|
|
|
|
#if SPOOLDIR_TAYLOR
|
|
|
|
|
bgrade = *(strrchr (zfile, '/') + 3);
|
|
|
|
|
#else
|
1993-08-05 18:28:27 +00:00
|
|
|
|
#if ! SPOOLDIR_SVR4
|
|
|
|
|
bgrade = zfile[strlen (zfile) - CSEQLEN - 1];
|
|
|
|
|
#else
|
|
|
|
|
bgrade = *(strchr (zfile, '/') + 1);
|
1995-08-19 21:30:30 +00:00
|
|
|
|
#endif
|
1993-08-05 18:28:27 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return bgrade;
|
|
|
|
|
}
|