+static void sendwhole(int fd, struct stat *sb, const char *contype, int head)
+{
+ printf("HTTP/1.1 200 OK\n");
+ printf("Content-Type: %s\n", contype);
+ printf("Content-Length: %ji\n", (intmax_t)sb->st_size);
+ printf("Last-Modified: %s\n", fmthttpdate(sb->st_mtime));
+ printf("Date: %s\n", fmthttpdate(time(NULL)));
+ printf("\n");
+ fflush(stdout);
+ if(!head)
+ passdata(fd, 1, -1);
+}
+
+static void sendrange(int fd, struct stat *sb, const char *contype, char *spec, int head)
+{
+ char buf[strlen(spec) + 1];
+ char *p, *e;
+ off_t start, end;
+
+ if(strncmp(spec, "bytes=", 6))
+ goto error;
+ strcpy(buf, spec + 6);
+ if((p = strchr(buf, '-')) == NULL)
+ goto error;
+ if(p == buf) {
+ if(!p[1])
+ goto error;
+ end = sb->st_size;
+ start = end - strtoll(p + 1, &e, 10);
+ if(*e)
+ goto error;
+ if(start < 0)
+ start = 0;
+ } else {
+ *(p++) = 0;
+ start = strtoll(buf, &e, 10);
+ if(*e)
+ goto error;
+ if(*p) {
+ end = strtoll(p, &e, 10) + 1;
+ if(*e)
+ goto error;
+ } else {
+ end = sb->st_size;
+ }
+ }
+ if(start >= sb->st_size) {
+ printf("HTTP/1.1 416 Not satisfiable\n");
+ printf("Content-Range: */%ji\n", (intmax_t)sb->st_size);
+ printf("Content-Length: 0\n");
+ printf("Last-Modified: %s\n", fmthttpdate(sb->st_mtime));
+ printf("Date: %s\n", fmthttpdate(time(NULL)));
+ printf("\n");
+ return;
+ }
+ if((start < 0) || (start >= end))
+ goto error;
+ if(end > sb->st_size)
+ end = sb->st_size;
+ errno = 0;
+ if(lseek(fd, start, SEEK_SET) != start) {
+ simpleerror(1, 500, "Internal Error", "Could not seek properly to beginning of requested byte range.");
+ flog(LOG_ERR, "sendfile: could not seek properly when serving partial content: %s", strerror(errno));
+ exit(1);
+ }
+ printf("HTTP/1.1 206 Partial content\n");
+ printf("Content-Range: bytes %ji-%ji/%ji\n", (intmax_t)start, (intmax_t)(end - 1), (intmax_t)sb->st_size);
+ printf("Content-Length: %ji\n", (intmax_t)(end - start));
+ printf("Content-Type: %s\n", contype);
+ printf("Last-Modified: %s\n", fmthttpdate(sb->st_mtime));
+ printf("Date: %s\n", fmthttpdate(time(NULL)));
+ printf("\n");
+ fflush(stdout);
+ if(!head)
+ passdata(fd, 1, end - start);
+ return;
+
+error:
+ sendwhole(fd, sb, contype, head);
+}
+