~ubuntu-branches/ubuntu/oneiric/enigmail/oneiric-updates

« back to all changes in this revision

Viewing changes to config/nsinstall.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2010-04-10 01:42:24 UTC
  • Revision ID: james.westby@ubuntu.com-20100410014224-fbq9ui5x3b0h2t36
Tags: 2:1.0.1-0ubuntu1
* First releaase of enigmail 1.0.1 for tbird/icedove 3
  (LP: #527138)
* redo packaging from scratch 
  + add debian/make-orig target that uses xulrunner provided
    buildsystem + enigmail tarball to produce a proper orig.tar.gz
  + use debhelper 7 with mozilla-devscripts
  + use debian source format 3.0 (quilt)
  + patch enigmail to use frozen API only
    - add debian/patches/frozen_api.diff
  + patch build system to not link against -lxul - which isnt
    available for sdks produced by all-static apps like tbird
    - add debian/patches/build_system_dont_link_libxul.diff
  + add minimal build-depends to control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Mozilla Public License Version
 
6
 * 1.1 (the "License"); you may not use this file except in compliance with
 
7
 * the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/MPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 * Alternatively, the contents of this file may be used under the terms of
 
25
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 
26
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
28
 * of those above. If you wish to allow use of your version of this file only
 
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
30
 * use your version of this file under the terms of the MPL, indicate your
 
31
 * decision by deleting the provisions above and replace them with the notice
 
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
33
 * the provisions above, a recipient may use your version of this file under
 
34
 * the terms of any one of the MPL, the GPL or the LGPL.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
/*
 
38
** Netscape portable install command.
 
39
**
 
40
** Brendan Eich, 7/20/95
 
41
*/
 
42
#include <stdio.h>  /* OSF/1 requires this before grp.h, so put it first */
 
43
#include <assert.h>
 
44
#include <fcntl.h>
 
45
#include <errno.h>
 
46
#include <dirent.h>
 
47
#include <limits.h>
 
48
#include <grp.h>
 
49
#include <pwd.h>
 
50
#include <stdio.h>
 
51
#include <stdlib.h>
 
52
#include <string.h>
 
53
#include <unistd.h>
 
54
#include <utime.h>
 
55
#include <sys/types.h>
 
56
#include <sys/stat.h>
 
57
#include "pathsub.h"
 
58
 
 
59
#ifdef HAVE_GETOPT_H
 
60
#include <getopt.h>
 
61
#endif
 
62
 
 
63
#ifdef SUNOS4
 
64
#include "sunos4.h"
 
65
#endif
 
66
 
 
67
#ifdef NEXTSTEP
 
68
#include <bsd/libc.h>
 
69
#endif
 
70
 
 
71
#ifdef __QNX__
 
72
#include <unix.h>
 
73
#endif
 
74
 
 
75
#ifdef NEED_S_ISLNK
 
76
#if !defined(S_ISLNK) && defined(S_IFLNK)
 
77
#define S_ISLNK(a)      (((a) & S_IFMT) == S_IFLNK)
 
78
#endif
 
79
#endif
 
80
 
 
81
#ifndef _DIRECTORY_SEPARATOR
 
82
#define _DIRECTORY_SEPARATOR "/"
 
83
#endif /* _DIRECTORY_SEPARATOR */
 
84
 
 
85
#ifdef NEED_FCHMOD_PROTO
 
86
extern int fchmod(int fildes, mode_t mode);
 
87
#endif
 
88
 
 
89
static void
 
90
usage(void)
 
91
{
 
92
    fprintf(stderr,
 
93
        "usage: %s [-C cwd] [-L linkprefix] [-m mode] [-o owner] [-g group]\n"
 
94
        "       %*s [-DdltR] file [file ...] directory\n",
 
95
        program, (int) strlen(program), "");
 
96
    exit(2);
 
97
}
 
98
 
 
99
static int
 
100
mkdirs(char *path, mode_t mode)
 
101
{
 
102
    char *cp;
 
103
    struct stat sb;
 
104
    int res;
 
105
    int l;
 
106
 
 
107
    /* strip trailing "/." */
 
108
    l = strlen(path);
 
109
    if(l > 1 && path[l - 1] == '.' && path[l - 2] == '/')
 
110
        path[l - 2] = 0;
 
111
 
 
112
    while (*path == '/' && path[1] == '/')
 
113
        path++;
 
114
    for (cp = strrchr(path, '/'); cp && cp != path && *(cp - 1) == '/'; cp--);
 
115
    if (cp && cp != path) {
 
116
        *cp = '\0';
 
117
        if ((lstat(path, &sb) < 0 || !S_ISDIR(sb.st_mode)) &&
 
118
            mkdirs(path, mode) < 0) {
 
119
            return -1;
 
120
        }
 
121
        *cp = '/';
 
122
    }
 
123
    
 
124
    res = mkdir(path, mode);
 
125
    if ((res != 0) && (errno == EEXIST))
 
126
      return 0;
 
127
    else
 
128
      return res;
 
129
}
 
130
 
 
131
static uid_t
 
132
touid(char *owner)
 
133
{
 
134
    struct passwd *pw;
 
135
    uid_t uid;
 
136
    char *cp;
 
137
 
 
138
    pw = getpwnam(owner);
 
139
    if (pw)
 
140
        return pw->pw_uid;
 
141
    uid = strtol(owner, &cp, 0);
 
142
    if (uid == 0 && cp == owner)
 
143
        fail("cannot find uid for %s", owner);
 
144
    return uid;
 
145
}
 
146
 
 
147
static gid_t
 
148
togid(char *group)
 
149
{
 
150
    struct group *gr;
 
151
    gid_t gid;
 
152
    char *cp;
 
153
 
 
154
    gr = getgrnam(group);
 
155
    if (gr)
 
156
        return gr->gr_gid;
 
157
    gid = strtol(group, &cp, 0);
 
158
    if (gid == 0 && cp == group)
 
159
        fail("cannot find gid for %s", group);
 
160
    return gid;
 
161
}
 
162
 
 
163
static void
 
164
copyfile( char *name, char *toname, mode_t mode, char *group, char *owner,
 
165
          int dotimes, uid_t uid, gid_t gid )
 
166
{
 
167
  int fromfd, tofd = -1, cc, wc, exists;
 
168
  char buf[BUFSIZ], *bp;
 
169
  struct stat sb, tosb;
 
170
  struct utimbuf utb;
 
171
 
 
172
  exists = (lstat(toname, &tosb) == 0);
 
173
 
 
174
  fromfd = open(name, O_RDONLY);
 
175
  if (fromfd < 0 || fstat(fromfd, &sb) < 0)
 
176
    fail("cannot access %s", name);
 
177
  if (exists) {
 
178
    if (S_ISREG(tosb.st_mode)) {
 
179
      /* See if we can open it. This is more reliable than 'access'. */
 
180
      tofd = open(toname, O_CREAT | O_WRONLY, 0666);
 
181
    }
 
182
    if (tofd < 0) {
 
183
      (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname);
 
184
    }
 
185
  }
 
186
  if (tofd < 0) {
 
187
    tofd = open(toname, O_CREAT | O_WRONLY, 0666);
 
188
    if (tofd < 0)
 
189
      fail("cannot create %s", toname);
 
190
  }
 
191
 
 
192
  bp = buf;
 
193
  while ((cc = read(fromfd, bp, sizeof buf)) > 0)
 
194
  {
 
195
    while ((wc = write(tofd, bp, (unsigned int)cc)) > 0)
 
196
    {
 
197
      if ((cc -= wc) == 0)
 
198
        break;
 
199
      bp += wc;
 
200
    }
 
201
    if (wc < 0)
 
202
      fail("cannot write to %s", toname);
 
203
  }
 
204
  if (cc < 0)
 
205
    fail("cannot read from %s", name);
 
206
 
 
207
  if (ftruncate(tofd, sb.st_size) < 0)
 
208
    fail("cannot truncate %s", toname);
 
209
#if !defined(VMS)
 
210
  if (dotimes)
 
211
  {
 
212
    utb.actime = sb.st_atime;
 
213
    utb.modtime = sb.st_mtime;
 
214
    if (utime(toname, &utb) < 0)
 
215
      fail("cannot set times of %s", toname);
 
216
  }
 
217
#ifdef HAVE_FCHMOD
 
218
  if (fchmod(tofd, mode) < 0)
 
219
#else
 
220
  if (chmod(toname, mode) < 0)
 
221
#endif
 
222
    fail("cannot change mode of %s", toname);
 
223
#endif
 
224
  if ((owner || group) && fchown(tofd, uid, gid) < 0)
 
225
    fail("cannot change owner of %s", toname);
 
226
 
 
227
  /* Must check for delayed (NFS) write errors on close. */
 
228
  if (close(tofd) < 0)
 
229
    fail("cannot write to %s", toname);
 
230
  close(fromfd);
 
231
#if defined(VMS)
 
232
  if (chmod(toname, (mode & (S_IREAD | S_IWRITE))) < 0)
 
233
    fail("cannot change mode of %s", toname);
 
234
  if (dotimes)
 
235
  {
 
236
    utb.actime = sb.st_atime;
 
237
    utb.modtime = sb.st_mtime;
 
238
    if (utime(toname, &utb) < 0)
 
239
      fail("cannot set times of %s", toname);
 
240
  }
 
241
#endif
 
242
}
 
243
 
 
244
static void
 
245
copydir( char *from, char *to, mode_t mode, char *group, char *owner,
 
246
         int dotimes, uid_t uid, gid_t gid)
 
247
{
 
248
  int i;
 
249
  DIR *dir;
 
250
  struct dirent *ep;
 
251
  struct stat sb;
 
252
  char *base, *destdir, *direntry, *destentry;
 
253
 
 
254
  base = xbasename(from);
 
255
 
 
256
  /* create destination directory */
 
257
  destdir = xmalloc((unsigned int)(strlen(to) + 1 + strlen(base) + 1));
 
258
  sprintf(destdir, "%s%s%s", to, _DIRECTORY_SEPARATOR, base);
 
259
  if (mkdirs(destdir, mode) != 0) {
 
260
    fail("cannot make directory %s\n", destdir);
 
261
    return;
 
262
  }
 
263
 
 
264
  dir = opendir(from);
 
265
 
 
266
  direntry = xmalloc((unsigned int)PATH_MAX);
 
267
  destentry = xmalloc((unsigned int)PATH_MAX);
 
268
 
 
269
  while ((ep = readdir(dir)))
 
270
  {
 
271
    if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
 
272
      continue;
 
273
 
 
274
    sprintf(direntry, "%s/%s", from, ep->d_name);
 
275
    sprintf(destentry, "%s%s%s", destdir, _DIRECTORY_SEPARATOR, ep->d_name);
 
276
 
 
277
    if (stat(direntry, &sb) == 0 && S_ISDIR(sb.st_mode))
 
278
      copydir( direntry, destdir, mode, group, owner, dotimes, uid, gid );
 
279
    else
 
280
      copyfile( direntry, destentry, mode, group, owner, dotimes, uid, gid );
 
281
  }
 
282
 
 
283
  free(direntry);
 
284
  free(destentry);
 
285
  closedir(dir);
 
286
}
 
287
 
 
288
int
 
289
main(int argc, char **argv)
 
290
{
 
291
    int onlydir, dodir, dolink, dorelsymlink, dotimes, opt, len, lplen, tdlen, bnlen, exists, fromfd, tofd, cc, wc;
 
292
    mode_t mode = 0755;
 
293
    char *linkprefix, *owner, *group, *cp, *cwd, *todir, *toname, *name, *base, *linkname, *bp, buf[BUFSIZ];
 
294
    uid_t uid;
 
295
    gid_t gid;
 
296
    struct stat sb, tosb, fromsb;
 
297
    struct utimbuf utb;
 
298
 
 
299
    program = argv[0];
 
300
    cwd = linkname = linkprefix = owner = group = 0;
 
301
    onlydir = dodir = dolink = dorelsymlink = dotimes = lplen = 0;
 
302
 
 
303
    while ((opt = getopt(argc, argv, "C:DdlL:Rm:o:g:t")) != EOF) {
 
304
        switch (opt) {
 
305
          case 'C':
 
306
            cwd = optarg;
 
307
            break;
 
308
          case 'D':
 
309
            onlydir = 1;
 
310
            break;
 
311
          case 'd':
 
312
            dodir = 1;
 
313
            break;
 
314
          case 'l':
 
315
            dolink = 1;
 
316
            break;
 
317
          case 'L':
 
318
            linkprefix = optarg;
 
319
            lplen = strlen(linkprefix);
 
320
            dolink = 1;
 
321
            break;
 
322
     case 'R':
 
323
            dolink = dorelsymlink = 1;
 
324
            break;
 
325
          case 'm':
 
326
            mode = strtoul(optarg, &cp, 8);
 
327
            if (mode == 0 && cp == optarg)
 
328
                usage();
 
329
            break;
 
330
          case 'o':
 
331
            owner = optarg;
 
332
            break;
 
333
          case 'g':
 
334
            group = optarg;
 
335
            break;
 
336
          case 't':
 
337
            dotimes = 1;
 
338
            break;
 
339
          default:
 
340
            usage();
 
341
        }
 
342
    }
 
343
 
 
344
    argc -= optind;
 
345
    argv += optind;
 
346
    if (argc < 2 - onlydir)
 
347
        usage();
 
348
 
 
349
    todir = argv[argc-1];
 
350
    if ((stat(todir, &sb) < 0 || !S_ISDIR(sb.st_mode)) &&
 
351
        mkdirs(todir, 0777) < 0) {
 
352
        fail("cannot make directory %s", todir);
 
353
    }
 
354
    if (onlydir)
 
355
        return 0;
 
356
 
 
357
    if (!cwd) {
 
358
#ifndef NEEDS_GETCWD
 
359
#ifndef GETCWD_CANT_MALLOC
 
360
        cwd = getcwd(0, PATH_MAX);
 
361
#else
 
362
        cwd = malloc(PATH_MAX + 1);
 
363
        cwd = getcwd(cwd, PATH_MAX);
 
364
#endif
 
365
#else
 
366
        cwd = malloc(PATH_MAX + 1);
 
367
        cwd = getwd(cwd);
 
368
#endif
 
369
    }
 
370
 
 
371
    xchdir(todir);
 
372
#ifndef NEEDS_GETCWD
 
373
#ifndef GETCWD_CANT_MALLOC
 
374
    todir = getcwd(0, PATH_MAX);
 
375
#else
 
376
    todir = malloc(PATH_MAX + 1);
 
377
    todir = getcwd(todir, PATH_MAX);
 
378
#endif
 
379
#else
 
380
    todir = malloc(PATH_MAX + 1);
 
381
    todir = getwd(todir);
 
382
#endif
 
383
    tdlen = strlen(todir);
 
384
    xchdir(cwd);
 
385
    tdlen = strlen(todir);
 
386
 
 
387
    uid = owner ? touid(owner) : (uid_t)(-1);
 
388
    gid = group ? togid(group) : (gid_t)(-1);
 
389
 
 
390
    while (--argc > 0) {
 
391
        name = *argv++;
 
392
        len = strlen(name);
 
393
        base = xbasename(name);
 
394
        bnlen = strlen(base);
 
395
        toname = xmalloc((unsigned int)(tdlen + 1 + bnlen + 1));
 
396
        sprintf(toname, "%s%s%s", todir, _DIRECTORY_SEPARATOR, base);
 
397
        exists = (lstat(toname, &tosb) == 0);
 
398
 
 
399
        if (dodir) {
 
400
            /* -d means create a directory, always */
 
401
            if (exists && !S_ISDIR(tosb.st_mode)) {
 
402
                (void) unlink(toname);
 
403
                exists = 0;
 
404
            }
 
405
            if (!exists && mkdir(toname, mode) < 0)
 
406
                fail("cannot make directory %s", toname);
 
407
            if ((owner || group) && chown(toname, uid, gid) < 0)
 
408
                fail("cannot change owner of %s", toname);
 
409
        } else if (dolink) {
 
410
            if (access(name, R_OK) != 0) {
 
411
                fail("cannot access %s", name);
 
412
            }
 
413
            if (*name == '/') {
 
414
                /* source is absolute pathname, link to it directly */
 
415
                linkname = 0;
 
416
            } else {
 
417
                if (linkprefix) {
 
418
                    /* -L implies -l and prefixes names with a $cwd arg. */
 
419
                    len += lplen + 1;
 
420
                    linkname = xmalloc((unsigned int)(len + 1));
 
421
                    sprintf(linkname, "%s/%s", linkprefix, name);
 
422
                } else if (dorelsymlink) {
 
423
                    /* Symlink the relative path from todir to source name. */
 
424
                    linkname = xmalloc(PATH_MAX);
 
425
 
 
426
                    if (*todir == '/') {
 
427
                        /* todir is absolute: skip over common prefix. */
 
428
                        lplen = relatepaths(todir, cwd, linkname);
 
429
                        strcpy(linkname + lplen, name);
 
430
                    } else {
 
431
                        /* todir is named by a relative path: reverse it. */
 
432
                        reversepath(todir, name, len, linkname);
 
433
                        xchdir(cwd);
 
434
                    }
 
435
 
 
436
                    len = strlen(linkname);
 
437
                }
 
438
                name = linkname;
 
439
            }
 
440
 
 
441
            /* Check for a pre-existing symlink with identical content. */
 
442
            if ((exists && (!S_ISLNK(tosb.st_mode) ||
 
443
                                                readlink(toname, buf, sizeof buf) != len ||
 
444
                                                strncmp(buf, name, (unsigned int)len) != 0)) || 
 
445
                        ((stat(name, &fromsb) == 0) && 
 
446
                         (fromsb.st_mtime > tosb.st_mtime))) {
 
447
                (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname);
 
448
                exists = 0;
 
449
            }
 
450
            if (!exists && symlink(name, toname) < 0)
 
451
                fail("cannot make symbolic link %s", toname);
 
452
#ifdef HAVE_LCHOWN
 
453
            if ((owner || group) && lchown(toname, uid, gid) < 0)
 
454
                fail("cannot change owner of %s", toname);
 
455
#endif
 
456
 
 
457
            if (linkname) {
 
458
                free(linkname);
 
459
                linkname = 0;
 
460
            }
 
461
        } else {
 
462
            /* Copy from name to toname, which might be the same file. */
 
463
      if( stat(name, &sb) == 0 && S_IFDIR & sb.st_mode )
 
464
      {
 
465
        /* then is directory: must explicitly create destination dir  */
 
466
        /*  and manually copy files over                              */
 
467
        copydir( name, todir, mode, group, owner, dotimes, uid, gid );
 
468
      } 
 
469
      else
 
470
      {
 
471
        copyfile(name, toname, mode, group, owner, dotimes, uid, gid);
 
472
      }
 
473
    }
 
474
 
 
475
        free(toname);
 
476
    }
 
477
 
 
478
    free(cwd);
 
479
    free(todir);
 
480
    return 0;
 
481
}