~ubuntu-branches/ubuntu/karmic/debianutils/karmic

1 by Clint Adams
Apply patch from Robert Millan to not ship installkernel and
1
#include <stdio.h>
2
#include <unistd.h>
3
#include <stdlib.h>
3 by Clint Adams
Start shipping and installing a starter /etc/shells.
4
#ifdef HAVE_GETOPT_H
1 by Clint Adams
Apply patch from Robert Millan to not ship installkernel and
5
#include <getopt.h>
3 by Clint Adams
Start shipping and installing a starter /etc/shells.
6
#endif /* HAVE_GETOPT_H */
1 by Clint Adams
Apply patch from Robert Millan to not ship installkernel and
7
#include <errno.h>
8
#include <sys/types.h>
9
#include <sys/stat.h>
10
#include <fcntl.h>
11
#include <string.h>
12
13
char *progname;
14
15
void
16
usage (int status)
17
{
18
  if (status)
19
    fprintf(stderr, "Try `%s --help' for more information.\n", progname);
20
  else
21
    printf("Usage: %s [OPTION]\n\n"
22
"Create a temporary file in a safe manner.\n\n"
23
"-d, --directory=DIR  place temporary file in DIR\n"
24
"-p, --prefix=STRING  set temporary file's prefix to STRING\n"
25
"-s, --suffix=STRING  set temporary file's suffix to STRING\n"
26
"-m, --mode=MODE      open with MODE instead of 0600\n"
27
"-n, --name=FILE      use FILE instead of tempnam(3)\n"
28
"    --help           display this help and exit\n"
29
"    --version        output version information and exit\n", progname);
30
  exit(status);
31
}
32
33
34
void
35
syserror (const char *fx)
36
{
37
  perror(fx);
38
  exit(1);
39
}
40
41
42
int
43
parsemode (const char *in, mode_t *out)
44
{
45
  char *endptr;
46
  long int mode;
47
  mode = strtol(in, &endptr, 8);
48
  if (*endptr || mode<0 || mode>07777)
49
    return 1;
50
  *out = (mode_t) mode;
51
  return 0;
52
}
53
54
55
int
56
main (int argc, char **argv)
57
{
58
  char *name=0, *dir=0, *pfx=0, *sfx=0;
59
  mode_t mode = 0600;
60
  int fd, optc;
61
  struct option long_options[] = {
62
    {"prefix", required_argument, 0, 'p'},
63
    {"suffix", required_argument, 0, 's'},
64
    {"directory", required_argument, 0, 'd'},
65
    {"mode", required_argument, 0, 'm'},
66
    {"name", required_argument, 0, 'n'},
67
    {"help", no_argument, 0, 'h'},
68
    {"version", no_argument, 0, 'v'},
69
    {0, 0, 0, 0}
70
  };
71
  progname = argv[0];
72
73
  while ((optc = getopt_long (argc, argv, "p:s:d:m:n:", long_options, 0))
74
	 != EOF) {
75
    switch (optc) {
76
    case 0:
77
      break;
78
    case 'p':
79
      pfx = optarg;
80
      break;
81
    case 's':
82
      sfx = optarg;
83
      break;
84
    case 'd':
85
      dir = optarg;
86
      break;
87
    case 'm':
88
      if (parsemode(optarg, &mode)) {
89
	fprintf(stderr, "Invalid mode `%s'.  Mode must be octal.\n", optarg);
90
	usage(1);
91
      }
92
      break;
93
    case 'n':
94
      name = optarg;
95
      break;
96
    case 'h':
97
      usage(0);
98
    case 'v':
99
      puts("tempfile " PACKAGE_VERSION);
100
      exit(0);
101
    default:
102
      usage(1);
103
    }
104
  }
105
106
  if (name) {
107
    if ((fd = open(name, O_RDWR | O_CREAT | O_EXCL, mode)) < 0)
108
      syserror("open");
109
  }
110
111
  else {
112
    for (;;) {
113
      if (!(name = tempnam(dir, pfx)))
114
	syserror("tempnam");
115
      if ((fd = open(name, O_RDWR | O_CREAT | O_EXCL, mode)) < 0) {
116
	if (errno == EEXIST) {
117
	  free(name);
118
	  continue;
119
	}
120
	syserror("open");
121
      }
122
      if (sfx) {
123
	char *namesfx;
124
	if (!(namesfx = malloc(strlen(name) + strlen(sfx) + 1)))
125
	  syserror("malloc");
126
	strcpy(namesfx, name);
127
	strcat(namesfx, sfx);
128
	if (link(name, namesfx) < 0) {
129
	  if (errno == EEXIST) {
130
	    if (unlink(name) < 0)
131
	      syserror("unlink");
132
	    free(name);
133
	    free(namesfx);
134
	    continue;
135
	  }
136
	  syserror("link");
137
	}
138
	if (unlink(name) < 0)
139
	  syserror("unlink");
140
	free(name);
141
	name = namesfx;
142
      }
143
      break;
144
    }
145
  }
146
  
147
  if (close(fd))
148
    syserror("close");
149
  puts(name);
150
  exit(0);
151
}