~ubuntu-branches/ubuntu/trusty/dovecot/trusty-updates

« back to all changes in this revision

Viewing changes to src/lib/ostream-file.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-01-08 09:35:49 UTC
  • mfrom: (1.15.3) (96.1.1 trusty-proposed)
  • Revision ID: package-import@ubuntu.com-20140108093549-814nkqdcxfbvgktg
Tags: 1:2.2.9-1ubuntu1
* Merge from Debian unstable, remaining changes:
  + Add mail-stack-delivery package:
    - Update d/rules
    - d/control: convert existing dovecot-postfix package to a dummy
      package and add new mail-stack-delivery package.
    - Update maintainer scripts.
    - Rename d/dovecot-postfix.* to debian/mail-stack-delivery.*
    - d/mail-stack-delivery.preinst: Move previously installed backups and
      config files to a new package namespace.
    - d/mail-stack-delivery.prerm: Added to handle downgrades.
  + Use Snakeoil SSL certificates by default:
    - d/control: Depend on ssl-cert.
    - d/dovecot-core.postinst: Relax grep for SSL_* a bit.
  + Add autopkgtest to debian/tests/*.
  + Add ufw integration:
    - d/dovecot-core.ufw.profile: new ufw profile.
    - d/rules: install profile in dovecot-core.
    - d/control: dovecot-core - suggest ufw.
  + d/dovecot-core.dirs: Added usr/share/doc/dovecot-core
  + Add apport hook:
    - d/rules, d/source_dovecot.py
  + Add upstart job:
    - d/rules, d/dovecot-core.dovecot.upstart, d/control,
      d/dovecot-core.dirs, dovecot-imapd.{postrm, postinst, prerm},
      d/dovecot-pop3d.{postinst, postrm, prerm}.
      d/mail-stack-deliver.postinst: Convert init script to upstart.
  + Use the autotools-dev dh addon to update config.guess/config.sub for
    arm64.
* Dropped changes, included in Debian:
  - Update Dovecot name to reflect distribution in login greeting.
  - Update Drac plugin for >= 2.0.0 support.
* d/control: Drop dovecot-postfix package as its no longer required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
 
1
/* Copyright (c) 2002-2013 Dovecot authors, see the included COPYING file */
2
2
 
3
3
/* @UNSAFE: whole file */
4
4
 
5
5
#include "lib.h"
6
6
#include "ioloop.h"
7
7
#include "write-full.h"
8
 
#include "network.h"
 
8
#include "net.h"
9
9
#include "sendfile-util.h"
10
10
#include "istream.h"
11
11
#include "istream-private.h"
67
67
        fstream->ostream.ostream.closed = TRUE;
68
68
}
69
69
 
70
 
static void o_stream_file_close(struct iostream_private *stream)
 
70
static void o_stream_file_close(struct iostream_private *stream,
 
71
                                bool close_parent ATTR_UNUSED)
71
72
{
72
73
        struct file_ostream *fstream = (struct file_ostream *)stream;
73
74
 
74
75
        /* flush output before really closing it */
75
 
        o_stream_flush(&fstream->ostream.ostream);
 
76
        (void)o_stream_flush(&fstream->ostream.ostream);
76
77
 
77
78
        stream_closed(fstream);
78
79
}
152
153
 
153
154
        ret = lseek(fstream->fd, (off_t)fstream->buffer_offset, SEEK_SET);
154
155
        if (ret < 0) {
 
156
                io_stream_set_error(&fstream->ostream.iostream,
 
157
                                    "lseek() failed: %m");
155
158
                fstream->ostream.ostream.stream_errno = errno;
156
159
                return -1;
157
160
        }
158
161
 
159
162
        if (ret != (off_t)fstream->buffer_offset) {
 
163
                io_stream_set_error(&fstream->ostream.iostream,
 
164
                                    "lseek() returned wrong value");
160
165
                fstream->ostream.ostream.stream_errno = EINVAL;
161
166
                return -1;
162
167
        }
174
179
 
175
180
        o_stream_socket_cork(fstream);
176
181
        if (iov_size == 1) {
 
182
                i_assert(iov->iov_len > 0);
 
183
 
177
184
                if (!fstream->file ||
178
185
                    fstream->real_offset == fstream->buffer_offset) {
179
186
                        ret = write(fstream->fd, iov->iov_base, iov->iov_len);
394
401
{
395
402
        struct file_ostream *fstream = (struct file_ostream *)stream;
396
403
 
397
 
        if (offset > OFF_T_MAX || !fstream->file) {
 
404
        if (offset > OFF_T_MAX) {
398
405
                stream->ostream.stream_errno = EINVAL;
399
406
                return -1;
400
407
        }
 
408
        if (!fstream->file) {
 
409
                stream->ostream.stream_errno = ESPIPE;
 
410
                return -1;
 
411
        }
401
412
 
402
413
        if (buffer_flush(fstream) < 0)
403
414
                return -1;
505
516
                if (fstream->tail == fstream->buffer_size)
506
517
                        fstream->tail = 0;
507
518
 
508
 
                if (fstream->head == fstream->tail)
 
519
                if (fstream->head == fstream->tail &&
 
520
                    fstream->buffer_size > 0)
509
521
                        fstream->full = TRUE;
510
522
        }
511
523
 
674
686
                                struct istream *instream, int in_fd)
675
687
{
676
688
        struct file_ostream *foutstream = (struct file_ostream *)outstream;
677
 
        const struct stat *st;
678
689
        uoff_t start_offset;
679
690
        uoff_t in_size, offset, send_size, v_offset;
680
691
        ssize_t ret;
681
692
 
682
 
        st = i_stream_stat(instream, TRUE);
683
 
        if (st == NULL) {
684
 
                outstream->ostream.stream_errno = instream->stream_errno;
 
693
        if ((ret = i_stream_get_size(instream, TRUE, &in_size)) <= 0) {
 
694
                outstream->ostream.stream_errno = ret == 0 ? ESPIPE :
 
695
                        instream->stream_errno;
685
696
                return -1;
686
697
        }
687
 
        in_size = st->st_size;
688
698
 
689
699
        o_stream_socket_cork(foutstream);
690
700
 
812
822
                                   struct istream *instream, bool same_stream)
813
823
{
814
824
        struct file_ostream *foutstream = (struct file_ostream *)outstream;
815
 
        const struct stat *st;
816
 
        off_t in_abs_offset, ret;
 
825
        uoff_t in_size;
 
826
        off_t in_abs_offset, ret = 0;
817
827
 
818
828
        if (same_stream) {
819
829
                /* copying data within same fd. we'll have to be careful with
820
830
                   seeks and overlapping writes. */
821
 
                st = i_stream_stat(instream, TRUE);
822
 
                if (st == NULL) {
823
 
                        outstream->ostream.stream_errno = instream->stream_errno;
 
831
                if ((ret = i_stream_get_size(instream, TRUE, &in_size)) < 0) {
 
832
                        outstream->ostream.stream_errno =
 
833
                                instream->stream_errno;
824
834
                        return -1;
825
835
                }
826
 
                i_assert(instream->v_offset <= (uoff_t)st->st_size);
 
836
                /* if we couldn't find out the size, it means that instream
 
837
                   isn't a regular file_istream. we can be reasonably sure that
 
838
                   we can copy it safely the regular way. (there's really no
 
839
                   other possibility, other than failing completely.) */
 
840
        }
 
841
        if (ret > 0) {
 
842
                i_assert(instream->v_offset <= in_size);
827
843
 
828
844
                in_abs_offset = instream->real_stream->abs_start_offset +
829
845
                        instream->v_offset;
831
847
                if (ret == 0) {
832
848
                        /* copying data over itself. we don't really
833
849
                           need to do that, just fake it. */
834
 
                        return st->st_size - instream->v_offset;
 
850
                        return in_size - instream->v_offset;
835
851
                }
836
 
                if (ret > 0 && st->st_size > ret) {
 
852
                if (ret > 0 && in_size > (uoff_t)ret) {
837
853
                        /* overlapping */
838
854
                        i_assert(instream->seekable);
839
855
                        return io_stream_copy_backwards(outstream, instream,
840
 
                                                        st->st_size);
 
856
                                                        in_size);
841
857
                }
842
858
        }
843
859
 
866
882
                foutstream->no_sendfile = TRUE;
867
883
        }
868
884
 
869
 
        same_stream = i_stream_get_fd(instream) == foutstream->fd;
 
885
        same_stream = i_stream_get_fd(instream) == foutstream->fd &&
 
886
                foutstream->fd != -1;
870
887
        return io_stream_copy_stream(outstream, instream, same_stream);
871
888
}
872
889
 
933
950
 
934
951
        fstream = o_stream_create_fd_common(fd, autoclose_fd);
935
952
        fstream->ostream.max_buffer_size = max_buffer_size;
936
 
        ostream = o_stream_create(&fstream->ostream, NULL);
 
953
        ostream = o_stream_create(&fstream->ostream, NULL, fd);
937
954
 
938
955
        offset = lseek(fd, 0, SEEK_CUR);
939
956
        if (offset >= 0) {
969
986
        fstream->real_offset = offset;
970
987
        fstream->buffer_offset = offset;
971
988
 
972
 
        ostream = o_stream_create(&fstream->ostream, NULL);
 
989
        ostream = o_stream_create(&fstream->ostream, NULL, fd);
973
990
        ostream->offset = offset;
974
991
        return ostream;
975
992
}