source: trunk/athena/etc/desync/desync.c @ 10934

Revision 10934, 4.0 KB checked in by ghudson, 27 years ago (diff)
Declare getopt externals.
Line 
1/* Copyright 1996, 1997 by the Massachusetts Institute of Technology.
2 *
3 * Permission to use, copy, modify, and distribute this
4 * software and its documentation for any purpose and without
5 * fee is hereby granted, provided that the above copyright
6 * notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting
8 * documentation, and that the name of M.I.T. not be used in
9 * advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission.
11 * M.I.T. makes no representations about the suitability of
12 * this software for any purpose.  It is provided "as is"
13 * without express or implied warranty.
14 */
15
16static const char rcsid[] = "$Id: desync.c,v 1.4 1997-12-20 21:40:57 ghudson Exp $";
17
18/*
19 * desync - desynchronize cron jobs on networks
20 *
21 * This program is a tool which sleeps an ip-address dependent period
22 * of time in order to skew over the course of a set time cron jobs
23 * that would otherwise be synchronized. It should reside on local disk
24 * so as not to cause a fileserver load at its own invocation.
25 */
26
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <fcntl.h>
30#include <ctype.h>
31#include <string.h>
32#include <netinet/in.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <errno.h>
36
37#ifndef INADDR_NONE
38#define INADDR_NONE ((unsigned long) -1)
39#endif
40
41#define CONF SYSCONFDIR "/rc.conf"
42
43extern int optind;
44extern char *optarg;
45
46static char *progname;
47
48static unsigned long get_addr(void);
49
50int main(int argc, char **argv)
51{
52  const char *timefile = NULL;
53  int range, interval, c;
54  unsigned long tval, ip;
55  FILE *fp;
56
57  /* Save the program name. */
58  progname = argv[0];
59
60  /* Parse command-line flags. */
61  while ((c = getopt(argc, argv, "t:")) != -1)
62    {
63      switch (c) {
64      case 't':
65        timefile = optarg;
66        break;
67      default:
68        fprintf(stderr, "Usage: %s [-t timefile] [interval]\n");
69        return 2;
70      }
71    }
72
73  /* Get the time interval from the remaining argument, if there is one. */
74  argc -= optind;
75  argv += optind;
76  range = (argc == 1) ? atoi(argv[0]) : 3600;
77
78  ip = get_addr();
79  if (ip == INADDR_NONE)
80    return 2;
81
82  srand(ntohl(ip));
83  interval = rand() % range;
84
85  if (timefile)
86    {
87      fp = fopen(timefile, "r");
88      if (fp)
89        {
90          if (fscanf(fp, "%lu", &tval) != 1)
91            {
92              fprintf(stderr, "%s: Invalid time file %s\n", progname,
93                      timefile);
94              return 2;
95            }
96          fclose(fp);
97          if (time(NULL) >= tval)
98            {
99              unlink(timefile);
100              return 0;
101            }
102          else
103            return 1;
104        }
105      else
106        {
107          if (interval == 0)
108            return 0;
109          fp = fopen(timefile, "w");
110          if (fp == NULL)
111            {
112              fprintf(stderr, "%s: Couldn't open %s for writing: %s\n",
113                      progname, timefile, strerror(errno));
114              return 2;
115            }
116          fprintf(fp, "%lu\n", (unsigned long)(time(NULL) + interval));
117          fclose(fp);
118          return 1;
119        }
120    }
121  else
122    sleep(interval);
123
124  return 0;
125}
126
127static unsigned long get_addr()
128{
129  FILE *fp;
130  char buf[128], *p, *q;
131  unsigned long ip;
132
133  /* Open rc.conf for reading. */
134  fp = fopen(CONF, "r");
135  if (!fp)
136    {
137      fprintf(stderr, "%s: Can't open %s for reading: %s\n", progname, CONF,
138              strerror(errno));
139      return INADDR_NONE;
140    }
141
142  /* Look for the line setting ADDR. */
143  while (fgets(buf, sizeof(buf), fp) != NULL)
144    {
145      if (strncmp(buf, "ADDR", 4) == 0)
146        {
147          /* Find the value (or go on if ADDR isn't followed by '='). */
148          p = buf + 4;
149          while (isspace(*p))
150            p++;
151          if (*p != '=')
152            continue;
153          p++;
154          while (isspace(*p))
155            p++;
156
157          /* Truncate after the address. */
158          q = p;
159          while (isdigit(*q) || *q == '.')
160            q++;
161          *q = 0;
162
163          /* Parse the value into an IP address and test its validity. */
164          ip = inet_addr(p);
165          if (ip == INADDR_NONE)
166            fprintf(stderr, "%s: Invalid address: %s\n", progname, p);
167
168          fclose(fp);
169          return ip;
170        }
171    }
172
173  /* We didn't find it. */
174  fclose(fp);
175  fprintf(stderr, "%s: Can't find ADDR line in %s\n", progname, CONF);
176  return INADDR_NONE;
177}
Note: See TracBrowser for help on using the repository browser.