~peter-pearse/ubuntu/oneiric/at/prop001

« back to all changes in this revision

Viewing changes to at.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2005-11-09 12:57:45 UTC
  • Revision ID: james.westby@ubuntu.com-20051109125745-64eslxy1v1jjm2gm
Tags: 3.1.9ubuntu1
* Merge to new Debian version.
* Derooting patch was accepted in Debian; manually reapply remaining Ubuntu
  changes to the clean Debian version (see below).
* debian/control: Only recommend mail-transport-agent and prefer postfix.
* debian/rc: LSB init script.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* 
2
2
 *  at.c : Put file into atrun queue
3
3
 *  Copyright (C) 1993, 1994, 1995, 1996, 1997 Thomas Koenig
 
4
 *  Copyright (C) 2002, 2005 Ryan Murray
4
5
 *
5
6
 *  Atrun & Atq modifications
6
7
 *  Copyright (C) 1993  David Parsons
17
18
 *
18
19
 *  You should have received a copy of the GNU General Public License
19
20
 *  along with this program; if not, write to the Free Software
20
 
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
21
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21
22
 */
22
23
 
23
24
#ifdef HAVE_CONFIG_H
91
92
#define SIZE 255
92
93
 
93
94
#define TIMEFORMAT_POSIX        "%a %b %e %T %Y"
94
 
#define TIMEFORMAT_ISO          "%Y-%m-%d %H:%M"
95
95
#define TIMESIZE        50
96
96
 
97
97
enum {
108
108
 
109
109
/* File scope variables */
110
110
 
111
 
static char rcsid[] = "$Id: at.c,v 1.29 1997/09/28 20:00:16 ig25 Exp $";
 
111
static const char rcsid[] = "$Id: at.c,v 1.29 1997/09/28 20:00:16 ig25 Exp $";
112
112
char *no_export[] =
113
113
{
114
114
    "TERM", "DISPLAY", "_", "SHELLOPTS", "BASH_VERSINFO", "EUID", "GROUPS", "PPID", "UID"
240
240
    pid_t pid;
241
241
    int istty;
242
242
    int kill_errno;
 
243
    int rc;
 
244
    int mailsize = 128;
243
245
 
244
246
/* Install the signal handler for SIGINT; terminate after removing the
245
247
 * spool file if necessary
253
255
 
254
256
    ppos = atfile + strlen(ATJOB_DIR) + 1;
255
257
 
 
258
#ifdef _SC_LOGIN_NAME_MAX
 
259
    errno = 0;
 
260
    rc = sysconf(_SC_LOGIN_NAME_MAX);
 
261
    if (rc > 0)
 
262
        mailsize = rc;
 
263
#else
 
264
#  ifdef LOGIN_NAME_MAX
 
265
    mailsize = LOGIN_NAME_MAX;
 
266
#  endif
 
267
#endif
256
268
    /* Loop over all possible file names for running something at this
257
269
     * particular time, see if a file is there; the first empty slot at any
258
270
     * particular time is used.  Lock the file LFILE first to make sure
344
356
    mailname = getlogin();
345
357
    if (mailname == NULL)
346
358
        mailname = getenv("LOGNAME");
347
 
 
348
 
    if ((mailname == NULL) || (mailname[0] == '\0')
349
 
        || (strlen(mailname) > 8) || (getpwnam(mailname) == NULL)) {
 
359
    if (mailname == NULL || mailname[0] == '\0' || getpwnam(mailname) == NULL) {
350
360
        pass_entry = getpwuid(real_uid);
351
361
        if (pass_entry != NULL)
352
362
            mailname = pass_entry->pw_name;
353
363
    }
 
364
 
 
365
    if ((mailname == NULL) || (mailname[0] == '\0')
 
366
        || (strlen(mailname) > mailsize) ) {
 
367
        panic("Cannot find username to mail output to");
 
368
    }
354
369
    if (atinput != (char *) NULL) {
355
370
        fpin = freopen(atinput, "r", stdin);
356
371
        if (fpin == NULL)
357
372
            perr("Cannot open input file %.500s", atinput);
358
373
    }
359
 
    fprintf(fp, "#!/bin/sh\n# atrun uid=%d gid=%d\n# mail %8s %d\n",
 
374
 
 
375
    fprintf(fp, "#!/bin/sh\n# atrun uid=%d gid=%d\n# mail %s %d\n",
360
376
            real_uid, real_gid, mailname, send_mail);
361
377
 
362
378
    /* Write out the umask at the time of invocation
470
486
    /* Set the x bit so that we're ready to start executing
471
487
     */
472
488
 
473
 
    if (fchmod(fd2, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP) < 0)
 
489
    if (fchmod(fd2, S_IRUSR | S_IWUSR | S_IXUSR) < 0)
474
490
        perr("Cannot give away file");
475
491
 
476
492
    close(fd2);
477
493
 
478
494
    runtime = localtime(&runtimer);
479
495
 
480
 
    /* We only use the sick POSIX time format if POSIXLY_CORRECT
481
 
       is set.  Otherwise, we use ISO format.
482
 
     */
483
 
 
484
 
    if (getenv("POSIXLY_CORRECT") != NULL) {
485
 
        strftime(timestr, TIMESIZE, TIMEFORMAT_POSIX, runtime);
486
 
    } else {
487
 
        strftime(timestr, TIMESIZE, TIMEFORMAT_ISO, runtime);
488
 
    }
 
496
    strftime(timestr, TIMESIZE, TIMEFORMAT_POSIX, runtime);
489
497
    fprintf(stderr, "job %ld at %s\n", jobno, timestr);
490
498
 
491
499
    /* Signal atd, if present. Usual precautions taken... */
538
546
}
539
547
 
540
548
static void
541
 
list_jobs()
 
549
list_jobs(void)
542
550
{
543
551
    /* List all a user's jobs in the queue, by looping through ATJOB_DIR, 
544
552
     * or everybody's if we are root
583
591
        runtimer = 60 * (time_t) ctm;
584
592
        runtime = localtime(&runtimer);
585
593
 
586
 
        if (getenv("POSIXLY_CORRECT") != NULL) {
587
 
            strftime(timestr, TIMESIZE, TIMEFORMAT_POSIX, runtime);
588
 
        } else {
589
 
            strftime(timestr, TIMESIZE, TIMEFORMAT_ISO, runtime);
590
 
        }
 
594
        strftime(timestr, TIMESIZE, TIMEFORMAT_POSIX, runtime);
 
595
 
591
596
        if ((pwd = getpwuid(buf.st_uid)))
592
597
          printf("%ld\t%s %c %s\n", jobno, timestr, queue, pwd->pw_name);
593
598
        else
596
601
    PRIV_END
597
602
}
598
603
 
599
 
static void
 
604
static int
600
605
process_jobs(int argc, char **argv, int what)
601
606
{
602
607
    /* Delete every argument (job - ID) given
608
613
    unsigned long ctm;
609
614
    char queue;
610
615
    long jobno;
 
616
    int rc = EXIT_SUCCESS;
 
617
    int done;
611
618
 
 
619
    for (i = optind; i < argc; i++) {
 
620
        done = 0;
612
621
    PRIV_START
613
622
 
614
623
    if (chdir(ATJOB_DIR) != 0)
631
640
            if (sscanf(dirent->d_name, "%c%5lx%8lx", &queue, &jobno, &ctm) != 3)
632
641
            continue;
633
642
 
634
 
        for (i = optind; i < argc; i++) {
635
643
            if (atoi(argv[i]) == jobno) {
636
644
                if ((buf.st_uid != real_uid) && !(real_uid == 0)) {
637
645
                    fprintf(stderr, "%s: Not owner\n", argv[i]);
641
649
                case ATRM:
642
650
 
643
651
                    /*
644
 
                    PRIV_START
645
 
 
646
652
                    We need the unprivileged uid here since the file is owned by the real
647
653
                    (not effective) uid.
648
654
                    */
649
655
                    setregid(real_gid, effective_gid);
650
656
 
651
 
                        if (queue == '=') {
652
 
                            fprintf(stderr, "Warning: deleting running job\n");
653
 
                        }
654
 
                        if (unlink(dirent->d_name) != 0)
655
 
                            perr("Cannot unlink %.500s", dirent->d_name);
 
657
                    if (queue == '=') {
 
658
                        fprintf(stderr, "Warning: deleting running job\n");
 
659
                    }
 
660
                    if (unlink(dirent->d_name) != 0) {
 
661
                        perr("Cannot unlink %.500s", dirent->d_name);
 
662
                        rc = EXIT_FAILURE;
 
663
                    }
656
664
 
657
 
                    /*
658
 
                    PRIV_END
659
 
                    */
660
665
                    setregid(effective_gid, real_gid);
661
666
 
662
667
                    break;
666
671
                        FILE *fp;
667
672
                        int ch;
668
673
 
669
 
                        PRIV_START
670
 
 
671
 
                            fp = fopen(dirent->d_name, "r");
672
 
 
673
 
                        PRIV_END
674
 
 
675
 
                        if (!fp) {
676
 
                            perr("Cannot open %s", dirent->d_name);
677
 
                        }
678
 
                        while ((ch = getc(fp)) != EOF) {
679
 
                            putchar(ch);
680
 
                        }
 
674
                        setregid(real_gid, effective_gid);
 
675
                        fp = fopen(dirent->d_name, "r");
 
676
 
 
677
                        if (fp) {
 
678
                            while ((ch = getc(fp)) != EOF) {
 
679
                                putchar(ch);
 
680
                            }
 
681
                            done = 1;
 
682
                        }
 
683
                        else {
 
684
                            perr("Cannot open %.500s", dirent->d_name);
 
685
                            rc = EXIT_FAILURE;
 
686
                        }
 
687
                        setregid(effective_gid, real_gid);
681
688
                    }
682
689
                    break;
683
690
 
689
696
                }
690
697
            }
691
698
        }
 
699
        closedir(spool);
 
700
        if (done != 1) {
 
701
            fprintf(stderr, "Cannot find jobid %s\n", argv[i] );
 
702
            rc = EXIT_FAILURE;
 
703
        }
692
704
    }
 
705
    return rc;
693
706
}                               /* delete_jobs */
694
707
 
695
708
/* Global functions */
786
799
            queue_set = 1;
787
800
            break;
788
801
 
 
802
        case 'r':
789
803
        case 'd':
790
804
            if (program != AT)
791
805
                usage();
807
821
                usage();
808
822
 
809
823
            program = BATCH;
810
 
            options = "f:q:mvV";
 
824
            options = "";
811
825
            break;
812
826
 
813
827
        case 'V':
828
842
 
829
843
    if (disp_version)
830
844
        fprintf(stderr, "at version " VERSION "\n"
831
 
           "Bug reports to: ig25@rz.uni-karlsruhe.de (Thomas Koenig)\n");
 
845
           "Bug reports to: rmurray@debian.org (Ryan Murray)\n");
832
846
 
833
847
    /* select our program
834
848
     */
835
849
    if (!check_permission()) {
836
 
        fprintf(stderr, "You do not have permission to use %s.\n", namep);
 
850
        fprintf(stderr, "You do not have permission to use %.100s.\n", namep);
837
851
        exit(EXIT_FAILURE);
838
852
    }
839
853
    switch (program) {
 
854
        int i;
840
855
    case ATQ:
841
856
 
842
857
        REDUCE_PRIV(daemon_uid, daemon_gid)
 
858
 
843
859
            list_jobs();
844
860
        break;
845
861
 
846
862
    case ATRM:
847
863
 
848
864
        REDUCE_PRIV(daemon_uid, daemon_gid)
849
 
            process_jobs(argc, argv, ATRM);
 
865
        if (argc > optind) {
 
866
            for (i = optind; i < argc ; i++ )
 
867
                if (strspn(argv[i],"0123456789") != strlen(argv[i])) {
 
868
                    fprintf(stderr,"at: unknown jobid: %s\n", argv[i]);
 
869
                    exit(EXIT_FAILURE);
 
870
                }
 
871
            return process_jobs(argc, argv, ATRM);
 
872
        }
 
873
        else
 
874
            usage();
850
875
        break;
851
876
 
852
877
    case CAT:
853
878
 
854
 
        process_jobs(argc, argv, CAT);
 
879
        if (argc > optind) {
 
880
            for (i = optind; i < argc ; i++ )
 
881
                if (strspn(argv[i],"0123456789") != strlen(argv[i])) {
 
882
                    fprintf(stderr,"at: unknown jobid: %s", argv[i]);
 
883
                    exit(EXIT_FAILURE);
 
884
                }
 
885
            return process_jobs(argc, argv, CAT);
 
886
        }
 
887
        else
 
888
            usage();
855
889
        break;
856
890
 
857
891
    case AT: