]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - gnu/libexec/uucp/libunix/splcmd.c
This commit was generated by cvs2svn to compensate for changes in r58809,
[FreeBSD/FreeBSD.git] / gnu / libexec / uucp / libunix / splcmd.c
1 /* splcmd.c
2    Spool a command.
3
4    Copyright (C) 1991, 1992, 1993, 1995 Ian Lance Taylor
5
6    This file is part of the Taylor UUCP package.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
22    The author of the program may be contacted at ian@airs.com or
23    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
24    */
25
26 #include "uucp.h"
27
28 #include "uudefs.h"
29 #include "uuconf.h"
30 #include "sysdep.h"
31 #include "system.h"
32
33 #include <errno.h>
34 #include <ctype.h>
35 \f
36 /* Given a set of commands to execute for a remote system, create a
37    command file holding them.  This creates a single command file
38    holding all the commands passed in.  It returns a jobid.  */
39
40 char *
41 zsysdep_spool_commands (qsys, bgrade, ccmds, pascmds)
42      const struct uuconf_system *qsys;
43      int bgrade;
44      int ccmds;
45      const struct scmd *pascmds;
46 {
47   char abtempfile[sizeof "TMP1234567890"];
48   char *ztemp;
49   FILE *e;
50   int i;
51   const struct scmd *q;
52   char *z;
53   char *zjobid;
54
55 #if DEBUG > 0
56   if (! UUCONF_GRADE_LEGAL (bgrade))
57     ulog (LOG_FATAL, "Bad grade %d", bgrade);
58 #endif
59
60   /* Write the commands into a temporary file and then rename it to
61      avoid a race with uucico reading the file.  */
62   sprintf (abtempfile, "TMP%010lx", (unsigned long) getpid ());
63   ztemp = zsfind_file (abtempfile, qsys->uuconf_zname, bgrade);
64   if (ztemp == NULL)
65     return NULL;
66
67   e = esysdep_fopen (ztemp, FALSE, FALSE, TRUE);
68   if (e == NULL)
69     {
70       ubuffree (ztemp);
71       return NULL;
72     }
73
74   for (i = 0, q = pascmds; i < ccmds; i++, q++)
75     {
76       switch (q->bcmd)
77         {
78         case 'S':
79           fprintf (e, "S %s %s %s -%s %s 0%o %s\n", q->zfrom, q->zto,
80                    q->zuser, q->zoptions, q->ztemp, q->imode,
81                    q->znotify == NULL ? (const char *) "" : q->znotify);
82           break;
83         case 'R':
84           fprintf (e, "R %s %s %s -%s\n", q->zfrom, q->zto, q->zuser,
85                    q->zoptions);
86           break;
87         case 'X':
88           fprintf (e, "X %s %s %s -%s\n", q->zfrom, q->zto, q->zuser,
89                    q->zoptions);
90           break;
91         case 'E':
92           fprintf (e, "E %s %s %s -%s %s 0%o %s 0 %s\n", q->zfrom, q->zto,
93                    q->zuser, q->zoptions, q->ztemp, q->imode,
94                    q->znotify, q->zcmd);
95           break;
96         default:
97           ulog (LOG_ERROR,
98                 "zsysdep_spool_commands: Unrecognized type %d",
99                 q->bcmd);
100           (void) fclose (e);
101           (void) remove (ztemp);
102           ubuffree (ztemp);
103           return NULL;
104         }
105     }
106
107   if (! fstdiosync (e, ztemp))
108     {
109       (void) fclose (e);
110       (void) remove (ztemp);
111       ubuffree (ztemp);
112       return NULL;
113     }
114
115   if (fclose (e) != 0)
116     {
117       ulog (LOG_ERROR, "fclose: %s", strerror (errno));
118       (void) remove (ztemp);
119       ubuffree (ztemp);
120       return NULL;
121     }
122
123   /* The filename returned by zscmd_file is subject to some unlikely
124      race conditions, so keep trying the link until the destination
125      file does not already exist.  Each call to zscmd_file should
126      return a file name which does not already exist, so we don't have
127      to do anything special before calling it again.  */
128   while (TRUE)
129     {
130       z = zscmd_file (qsys, bgrade);
131       if (z == NULL)
132         {
133           (void) remove (ztemp);
134           ubuffree (ztemp);
135           return NULL;
136         }
137
138       if (link (ztemp, z) >= 0)
139         break;
140
141       if (errno != EEXIST)
142         {
143           ulog (LOG_ERROR, "link (%s, %s): %s", ztemp, z, strerror (errno));
144           (void) remove (ztemp);
145           ubuffree (ztemp);
146           ubuffree (z);
147           return NULL;
148         }
149
150       ubuffree (z);
151     }
152
153   (void) remove (ztemp);
154   ubuffree (ztemp);
155
156   zjobid = zsfile_to_jobid (qsys, z, bgrade);
157   if (zjobid == NULL)
158     (void) remove (z);
159   ubuffree (z);
160   return zjobid;
161 }