Ejemplo n.º 1
0
QVariant Note::header(uint column)
{
    if (column >= uint(headers().count()))
        return QVariant();

    return headers()[column];
}
Ejemplo n.º 2
0
void ResourceResponse::platformLazyInit(InitLevel initLevel)
{
    if (m_initLevel > initLevel)
        return;

    if (m_isNull || !m_cfResponse.get())
        return;

    if (m_initLevel < CommonFieldsOnly && initLevel >= CommonFieldsOnly) {
        m_url = CFURLResponseGetURL(m_cfResponse.get());
        m_mimeType = CFURLResponseGetMIMEType(m_cfResponse.get());
        m_expectedContentLength = CFURLResponseGetExpectedContentLength(m_cfResponse.get());
        m_textEncodingName = CFURLResponseGetTextEncodingName(m_cfResponse.get());

        // Workaround for <rdar://problem/8757088>, can be removed once that is fixed.
        unsigned textEncodingNameLength = m_textEncodingName.length();
        if (textEncodingNameLength >= 2 && m_textEncodingName[0U] == '"' && m_textEncodingName[textEncodingNameLength - 1] == '"')
            m_textEncodingName = m_textEncodingName.substring(1, textEncodingNameLength - 2);

        m_lastModifiedDate = toTimeT(CFURLResponseGetLastModifiedDate(m_cfResponse.get()));

        CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get());
        if (httpResponse) {
            m_httpStatusCode = CFHTTPMessageGetResponseStatusCode(httpResponse);
            
            RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse));
            
            for (int i = 0; i < numCommonHeaderFields; i++) {
                CFStringRef value;
                if (CFDictionaryGetValueIfPresent(headers.get(), commonHeaderFields[i], (const void **)&value))
                    m_httpHeaderFields.set(commonHeaderFields[i], value);
            }
        } else
            m_httpStatusCode = 0;
    }

    if (m_initLevel < CommonAndUncommonFields && initLevel >= CommonAndUncommonFields) {
        CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get());
        if (httpResponse) {
            RetainPtr<CFStringRef> statusLine(AdoptCF, CFHTTPMessageCopyResponseStatusLine(httpResponse));
            m_httpStatusText = extractReasonPhraseFromHTTPStatusLine(statusLine.get());

            RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse));
            CFIndex headerCount = CFDictionaryGetCount(headers.get());
            Vector<const void*, 128> keys(headerCount);
            Vector<const void*, 128> values(headerCount);
            CFDictionaryGetKeysAndValues(headers.get(), keys.data(), values.data());
            for (int i = 0; i < headerCount; ++i)
                m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]);
        }
    }
    
    if (m_initLevel < AllFields && initLevel >= AllFields) {
        RetainPtr<CFStringRef> suggestedFilename(AdoptCF, CFURLResponseCopySuggestedFilename(m_cfResponse.get()));
        m_suggestedFilename = suggestedFilename.get();
    }

    m_initLevel = initLevel;
}
Ejemplo n.º 3
0
void client() {
	while(1) {
		printf("Process id which wait: %d\n", getpid());
		cd = accept(ld, (struct sockaddr *)&caddr, &size_caddr);
		kill(getppid(), SIGUSR1);
		if (cd == -1) {
			printf("accept error \n");
		}
		printf("Process id which works: %d\n", getpid());
		printf("client in %d descriptor. Client addr is %d \n", cd, caddr.sin_addr.s_addr);
		fd = fdopen(cd, "r");
		if (fd == NULL) {
			printf("error open client descriptor as file \n");
		}
		while ((res = getline(&line, &len, fd)) != -1) {
			if (strstr(line, "GET")) {
				parseFileName(line, &filepath, &filepath_len);
			}
			if (strcmp(line, "\r\n") == 0) {
				empty_str_count++;
			}
			else {
				empty_str_count = 0;
			}
			if (empty_str_count == 1) {
				break;
			}
			printf("%s", line);
		}
		printf("open %s \n", filepath);
		file = fopen(filepath, "r");
		if (file == NULL) {
			printf("404 File Not Found \n");
			headers(cd, 0, 404);
		}
		else {
			fseek(file, 0L, SEEK_END);
			filesize = ftell(file);
			fseek(file, 0L, SEEK_SET);
			headers(cd, filesize, 200);
			while (getline(&line, &len, file) != -1) {
				res = send(cd, line, len, 0);
				if (res == -1) {
					printf("send error \n");
				}
			}
		}
		while(1);
		close(cd);
		//while(1);
		kill(getppid(), SIGUSR2);
	}
}
Ejemplo n.º 4
0
depsRef depsScanForHeaders(const char *path)
{
	PATHSPLIT f;
	char buf[MAXJPATH];
	time_t time;
	HEADER *h;

	if (!inState(DEPS_STATE_INIT | DEPS_STATE_SEARCH))
	{
		if (!inState(DEPS_STATE_SEARCH)) setErr(DEPS_ERROR_NOT_SEARCH);
		if (!inState(DEPS_STATE_INIT)) setErr(DEPS_ERROR_NOT_INIT);
		return NULL;
	}
	setErr(0);

	path_split(path, &f);
	path_normalize(&f, NULL);
	path_tostring(&f, buf);

	timestamp(buf, &time);
	if (!time)
		return NULL;

	h = headers(buf, time);
	return (depsRef) h;
}
Ejemplo n.º 5
0
int
main(int argc, char *argv[]) {

  if (argc != 2) {
    std::cerr << "Usage: " << argv[0] << " url" << std::endl;
    return 1;
  }

  try {
    http::client client;
    http::client::request request{network::uri{std::string{argv[1]}}};
    request.version("1.0");
    request.append_header("Connection", "close");
    request.append_header("User-Agent", "cpp-netlib read_headers example");
    auto future_response = client.head(request);
    auto response = future_response.get();

    std::cout << "HTTP version: " << response.version() << std::endl;
    std::cout << "HTTP status: " << static_cast<int>(response.status()) << std::endl;
    std::cout << "HTTP status message: " << response.status_message() << std::endl;
    std::cout << std::endl;
    for (auto header : response.headers()) {
      std::cout << header.first << ": " << header.second << std::endl;
    }
  }
  catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
    return 1;
  }

  return 0;
}
Ejemplo n.º 6
0
/* ***************************************
 * @描述:发送一个文件到客户端
 * @输入:[in] client:	客户端文件描述符
 * 	  [in] filename:文件名
 * @输出:无
 * **************************************/
void serve_file(int client, const char *filename)
{
	FILE *resource = NULL;
	int numchars = 1;
	char buf[1024];

	/* 读取并丢弃header */
	buf[0] = 'A';
	buf[1] = '\0';
	while((numchars > 0) && strcmp("\n", buf))
		numchars = get_line(client, buf, sizeof(buf));
	
	/* 打开server 文件 */
	resource = fopen(filename, "r");
	if(resource == NULL)
		not_found(client);
	else
	{
		/* 写HTTP header */
		headers(client, filename);
		/* 复制文件 */
		cat(client, resource);
	}
	fclose(resource);
}
void SessionStore::resetSession(HttpServerRequest &request) const
{
    // init variables
    QList<QByteArray> headers(request.headers().values("Cookie"));
    QByteArray newValue;

    // remove old cookies
    request.headers().remove("Cookie");

    // find cookies that don't match this store's settings
    for (int i = 0;i != headers.size();++i) {
        QList<QNetworkCookie> cookies(QNetworkCookie::parseCookies(headers[i]));

        for (int i = 0;i != cookies.size();++i) {
            if (cookies[i].name() != settings.name) {
                newValue
                    += cookies[i].toRawForm(QNetworkCookie::NameAndValueOnly)
                    + "; ";
            }
        }
    }

    if (!newValue.isEmpty()) {
        // removes the final "; "
        newValue.remove(newValue.size() - 2, 2);
    }

    // update the request headers
    request.headers().insert("Cookie", newValue);
}
Ejemplo n.º 8
0
/*
 * Scroll to the next/previous screen
 */
int
scroll(char arg[])
{
	int s, size;
	int cur[1];

	cur[0] = 0;
	size = screensize();
	s = screen;
	switch (*arg) {
	case 0:
	case '+':
		s++;
		if (s * size >= msgCount) {
			printf("On last screenful of messages\n");
			return (0);
		}
		screen = s;
		break;

	case '-':
		if (--s < 0) {
			printf("On first screenful of messages\n");
			return (0);
		}
		screen = s;
		break;

	default:
		printf("Unrecognized scrolling command \"%s\"\n", arg);
		return (1);
	}
	return (headers(cur));
}
Ejemplo n.º 9
0
spx_private void SendResponse(EV_P_ ev_async *watcher, int revents){/*{{{*/
        ev_async_stop(loop, watcher);
        err_t err = 0;
        struct server_context * ctx = (struct server_context *) watcher->data;
        if(NULL == ctx){
            SpxLog1(g_log, SpxLogError, "SendResponse ctx is NULL");
            return; 
        }

        if(NULL != ctx->response){
            ctx->resp_size = strlen(ctx->response);
            headers(ctx->fd, strlen(ctx->response));

            int remain_size = ctx->resp_size - ctx->resp_len;
            if(remain_size >= SPLIT_SIZE){
                ctx->split_size = SPLIT_SIZE;
            }else{
                ctx->split_size = remain_size;
            }

            RegisterAayncWatcher(&ctx->async_watcher, Sender, ctx);
            ev_async_start(loop, &ctx->async_watcher);
            ev_async_send(loop, &ctx->async_watcher);
        }else{
            RequestException(ctx, bad_request);
        }
}/*}}}*/
Ejemplo n.º 10
0
Boolean HTTPMessage::_lookupHeaderIndex(
    Array<HTTPHeader>& headers_,
    const char* fieldName,
    Uint32& headerIndex,
    Boolean allowNamespacePrefix)
{
    ArrayIterator<HTTPHeader> headers(headers_);

    for (Uint32 i = 0, n = headers.size(); i < n; i++)
    {
        if ((System::strcasecmp(headers[i].first.getData(), fieldName) == 0) ||
            (allowNamespacePrefix && (headers[i].first.size() >= 3) &&
             (headers[i].first[0] >= '0') && (headers[i].first[0] <= '9') &&
             (headers[i].first[1] >= '0') && (headers[i].first[1] <= '9') &&
             (headers[i].first[2] == '-') &&
             (System::strcasecmp(
                  headers[i].first.getData() + 3, fieldName) == 0)))
        {
            headerIndex = i;
            return true;
        }
    }

    // Not found:
    return false;
}
Ejemplo n.º 11
0
const std::string& ws::apache2request::header(const string& str) {
  std::map<std::string, std::string> &all = const_cast<std::map<std::string, std::string>& > (headers());
  if(all.find(str) == headers().end()) {
    return no_value;
  }
  return all[str];
}
void
GMMessageDragSource::GetSelectionData
	(
	JXSelectionData*	data,
	const JCharacter*	id
	)
{
	if (strcmp(id, kDNDClassID) == 0)
		{
		GMessageDragData* messageData =
			dynamic_cast<GMessageDragData*>(data);
		assert(messageData != NULL);

		messageData->SetDirector(itsDir->GetDir());
		JPtrArray<GMessageHeader> headers(JPtrArrayT::kForgetAll);

		GMessageHeader* header = itsDir->GetMessageHeader();
		headers.Append(header);
		messageData->SetHeaders(&headers);
		}
	else
		{
		JXImageWidget::GetSelectionData(data, id);
		}
}
Ejemplo n.º 13
0
void serve_file(int client, const char *filename)
{
 FILE *resource = NULL;
 int numchars = 1;
 char buf[1024];

 //确保 buf 里面有东西,能进入下面的 while 循环
 buf[0] = 'A'; buf[1] = '\0';
 //循环作用是读取并忽略掉这个 http 请求后面的所有内容
 while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
  numchars = get_line(client, buf, sizeof(buf));

 //打开这个传进来的这个路径所指的文件
 resource = fopen(filename, "r");
 if (resource == NULL)
  not_found(client);
 else
 {
  //打开成功后,将这个文件的基本信息封装成 response 的头部(header)并返回
  headers(client, filename);
  //接着把这个文件的内容读出来作为 response 的 body 发送到客户端
  cat(client, resource);
 }
 
 fclose(resource);
}
Ejemplo n.º 14
0
String
WinINetRequest::send()
{
    if (m_used) {
        throw XArch("class is one time use.");
    }
    m_used = true;

    openSession();
    connect();
    openRequest();
    
    String headers("Content-Type: text/html");
    if (!HttpSendRequest(m_request, headers.c_str(), (DWORD)headers.length(), NULL, NULL)) {
        throw XArch(new XArchEvalWindows());
    }
    
    std::stringstream result;
    CHAR buffer[1025];
    DWORD read = 0;

    while (InternetReadFile(m_request, buffer, sizeof(buffer) - 1, &read) && (read != 0)) {
        buffer[read] = 0;
        result << buffer;
        read = 0;
    }

    return result.str();
}
Ejemplo n.º 15
0
Boolean HTTPMessage::lookupHeader(
    Array<HTTPHeader>& headers_,
    const String& fieldName,
    String& fieldValue,
    Boolean allowNamespacePrefix)
{
    ArrayIterator<HTTPHeader> headers(headers_);

    for (Uint32 i = 0, n = headers.size(); i < n; i++)
    {
        if (String::equalNoCase(headers[i].first, fieldName) ||
            (allowNamespacePrefix && (headers[i].first.size() >= 3) &&
             (headers[i].first[0] >= '0') && (headers[i].first[0] <= '9') &&
             (headers[i].first[1] >= '0') && (headers[i].first[1] <= '9') &&
             (headers[i].first[2] == Char16('-')) &&
             String::equalNoCase(headers[i].first.subString(3), fieldName)))
        {
            fieldValue = headers[i].second;
            return true;
        }
    }

    // Not found:
    return false;
}
Ejemplo n.º 16
0
 response post(request request, string_type const& body = string_type(),
               string_type const& content_type = string_type(),
               body_callback_function_type body_handler =
                   body_callback_function_type(),
               body_generator_function_type body_generator =
                   body_generator_function_type()) {
   if (body != string_type()) {
     request << remove_header("Content-Length")
             << header("Content-Length",
                       boost::lexical_cast<string_type>(body.size()))
             << boost::network::body(body);
   }
   typename headers_range<basic_request<Tag> >::type content_type_headers =
       headers(request)["Content-Type"];
   if (content_type != string_type()) {
     if (!boost::empty(content_type_headers))
       request << remove_header("Content-Type");
     request << header("Content-Type", content_type);
   } else {
     if (boost::empty(content_type_headers)) {
       typedef typename char_<Tag>::type char_type;
       static char_type content_type[] = "x-application/octet-stream";
       request << header("Content-Type", content_type);
     }
   }
   return pimpl->request_skeleton(request, "POST", true, body_handler,
                                  body_generator);
 }
QString AbstractHttpRequest::header(const QString & field) const
{
	QList<QString> list = headers(field);
	if (list.size() > 0)
		return list.at(0);

	return "";
}
TYPED_TEST(HTTPClientTest, GetDifferentPort) {
  TypeParam client;
  typename TypeParam::request r("http://www.boost.org:80/");
  auto response_ = client.get(r);
  auto range = headers(response_)["Content-Type"];
  EXPECT_TRUE(std::begin(range) != std::end(range));
  EXPECT_NE(0, body(response_).size());
}
Ejemplo n.º 19
0
BOOST_AUTO_TEST_CASE_TEMPLATE(https_client_get_test, client, client_types) {
    typename client::request request("https://www.google.com/");
    client client_;
    typename client::response response_ = client_.get(request);
    typename net::headers_range<typename client::response>::type range = headers(response_)["Content-Type"];
    BOOST_CHECK ( boost::begin(range) != boost::end(range) );
    BOOST_CHECK ( body(response_).size() != 0 );
}
Ejemplo n.º 20
0
TEST_F( HttpSocketReaderTests, readsSomeHeaders )
{
  std::string headers( "HEADERS" );
  socketApi_.sourceBuffer_ = headers.c_str();

  std::string actual = reader_.readToEnd( -1 );
  ASSERT_EQ( headers, actual );
};
BOOST_AUTO_TEST_CASE_TEMPLATE(http_get_test_different_port, client,
                              client_types) {
  typename client::request request("http://www.boost.org:80/");
  client client_;
  typename client::response response_ = client_.get(request);
  auto range = headers(response_)["Content-Type"];
  BOOST_CHECK(boost::begin(range) != boost::end(range));
  BOOST_CHECK(body(response_).size() != 0);
}
Ejemplo n.º 22
0
void KCToolServer::onSocketReadyRead()
{
	QTcpSocket *socket = qobject_cast<QTcpSocket*>(QObject::sender());

	// Parse the first line
	if(!socket->property("firstLineRead").toBool())
	{
		QString line(socket->readLine());
		int sepPos1(line.indexOf(" "));
		int sepPos2(line.indexOf(" ", sepPos1+1));
		QString method(line.left(sepPos1));
		QString path(line.mid(sepPos1+1, sepPos2 - sepPos1 - 1));
		socket->setProperty("method", method);
		socket->setProperty("path", path);
		socket->setProperty("firstLineRead", true);
	}

	// Parse Headers!
	if(!socket->property("headerRead").toBool()) {
		QVariantMap headers(socket->property("headers").toMap());

		while(socket->canReadLine()) {
			QString line = QString(socket->readLine()).trimmed();

			// The header section is terminated by an empty line
			if(line == "") {
				socket->setProperty("headerRead", true);
				break;
			}

			// Split it up
			int sepPos(line.indexOf(":"));
			QString key(line.left(sepPos).trimmed());
			QString val(line.mid(sepPos+1).trimmed());
			headers.insertMulti(key, val);
		}

		socket->setProperty("headers", headers);
	}

	qint64 contentLength = socket->property("headers").toMap().value("Content-Length").toLongLong();
	// Read the body into a buffer
	if(socket->bytesAvailable()) {
		QByteArray buffer(socket->property("buffer").toByteArray());
		qint64 toRead = contentLength - buffer.size();
		buffer.append(socket->read(toRead));
		socket->setProperty("buffer", buffer);
		socket->setProperty("toRead", contentLength - buffer.size());

		// If we have a Content-Length (toLong() fails with 0)
		if(contentLength > 0 && buffer.size() >= contentLength)
			this->handleRequest(socket);
	} else if(contentLength == -1 || contentLength == 0) {
		this->handleRequest(socket);
	}
}
Ejemplo n.º 23
0
static unsigned table2 (unsigned margin, char const * string, struct column * column)

{
	extern unsigned line;
	extern unsigned cols;
	extern char const * style_empty;
	extern char const * label_empty;
	struct column * object;
	line = 1;
	headers (column);
	indent (margin++, "<table>");
	indent (margin++, "<title>");
	indent (margin, "%s", string);
	indent (margin--, "</title>");
	indent (margin++, "<tgroup cols='%d'>", cols);
	indent (margin, "<colspec colname='%s'/>", column ->name);
	for (object = column ->next; object; object = object ->next)
	{
		indent (margin, "<colspec colname='%s'/>", object ->name);
	}
	indent (margin++, "<thead>");
	indent (margin++, "<row>");
	indent (margin++, "<entry>");
	indent (margin, "%s", column ->name);
	indent (margin--, "</entry>");
	for (object = column ->next; object; object = object ->next)
	{
		indent (margin++, "<entry>");
		indent (margin, "%s", object ->name);
		indent (margin--, "</entry>");
	}
	indent (margin--, "</row>");
	indent (margin--, "</thead>");
	indent (margin++, "<tbody>");
	for (columns (column); ! feof (stdin); columns (column))
	{
		indent (margin++, "<row>");
		indent (margin++, "<entry>");
		indent (margin, "%s", column ->name);
		indent (margin--, "</entry>");
		for (object = column ->next; object; object = object ->next)
		{
			indent (margin++, "<entry>");
			indent (margin, "%s", object ->label);
			indent (margin--, "</entry>");
			object->style = style_empty;
			object->label = label_empty;
		}
		indent (margin--, "</row>");
	}
	indent (margin--, "</tbody>");
	indent (margin--, "</tgroup>");
	indent (margin--, "</table>");
	finish (column);
	return (margin);
}
Ejemplo n.º 24
0
std::string	HttpRequest::getHeaders() const
{
  std::string					headers("");
  std::map<std::string, std::string>::const_iterator	it;

  for (it = this->_headers.begin(); it != this->_headers.end(); ++it)
    {
      headers += (*it).first + ": " + (*it).second + HttpRequest::separator;
    }
  return (headers);
}
Ejemplo n.º 25
0
Archivo: gc.c Proyecto: CRogers/obc
/* find_block -- find a free block of specified size */
static header *find_block(unsigned size, unsigned objsize) {
    header *h = NULL, *h2;
    int i = min(size/GC_PAGESIZE, BIG_BLOCK);

    ASSERT(size % GC_PAGESIZE == 0);

    do {
        for (headers(h2, free_list[i])) {
            /* This always succeeds for small blocks, and gives
            first-fit allocation for big blocks. */
            if (size <= h2->h_size) {
                h = h2;
                break;
            }
        }
        i++;
    } while (h == NULL && i <= BIG_BLOCK);

    if (h == NULL) {
        /* No suitable block was found.  Get a big chunk. */
        unsigned chunk = max(size, CHUNK_SIZE);
        GC_TRACE("[ex]");
        ASSERT(chunk % GC_PAGESIZE == 0);
        h = alloc_header();
        h->h_memory = (uchar *) get_memory(chunk);
        h->h_size = chunk;
        /* Add to the free list for merging and page table setup */
        h = free_block(h, FALSE);
    }

    ASSERT(h->h_memory != NULL && h->h_size >= size);
    unlink(h);

    if (size < h->h_size) {
        /* Split the block, and return the waste to the free
           list.  It's best to use header h for the waste: that
           way, we don't have to reset lots of page table
           entries when we chip a small piece off a big block. */
        h2 = alloc_header();
        h2->h_memory = h->h_memory;
        h2->h_size = size;
        page_setup(h2->h_memory, size, h2);

        h->h_memory += size;
        h->h_size -= size;
        make_free(h);

        h = h2;
    }

    h->h_objsize = objsize;
    h->h_epoch = gencount;
    return h;
}
Ejemplo n.º 26
0
void SevenZipArch::setHeaders()
{
  ColumnList columns;
  columns.append( FILENAME_COLUMN );
  columns.append( SIZE_COLUMN );
  columns.append( PACKED_COLUMN );
  columns.append( TIMESTAMP_COLUMN );
  columns.append( PERMISSION_COLUMN );

  emit headers( columns );
}
Ejemplo n.º 27
0
void ZooArch::setHeaders()
{
  ColumnList list;
  list.append( FILENAME_COLUMN );
  list.append( RATIO_COLUMN );
  list.append( SIZE_COLUMN );
  list.append( PACKED_COLUMN );
  list.append( TIMESTAMP_COLUMN );

  emit headers( list );
}
Ejemplo n.º 28
0
QString HttpReply::headerAsString()
{
    QString header;
    QList<QByteArray> headers(m_networkReply->rawHeaderList());
    QList<QByteArray>::iterator iter;
    for (iter = headers.begin(); iter != headers.end(); ++iter) {
        header += QString(*iter) +"::" + QString(m_networkReply->rawHeader(*iter));
        header += "\n";
    }
    return header;
}
Ejemplo n.º 29
0
Eigen::VectorXi calculate_column_widths(const Eigen::MatrixXd& values,
                                        const Eigen::Matrix<std::string, Eigen::Dynamic, 1>& headers,
                                        const int sig_figs,
                                        Eigen::Matrix<std::ios_base::fmtflags, Eigen::Dynamic, 1>& formats) {
  int n = values.cols();
  Eigen::VectorXi column_widths(n);
  formats.resize(n);
  for (int i = 0; i < n; i++) {
    column_widths(i) = calculate_column_width(values.col(i), headers(i), sig_figs, formats(i));
  }
  return column_widths;
}
Ejemplo n.º 30
0
static int
scroll1(char *arg, int onlynew)
{
	int size;
	int cur[1];

	cur[0] = onlynew ? -1 : 0;
	size = screensize();
	switch (*arg) {
	case '1': case '2': case '3': case '4': case '5':
	case '6': case '7': case '8': case '9': case '0':
		screen = atoi(arg);
		goto scroll_forward;
	case '\0':
		screen++;
		goto scroll_forward;
	case '$':
		screen = msgCount / size;
		goto scroll_forward;
	case '+':
		if (arg[1] == '\0')
			screen++;
		else
			screen += atoi(arg + 1);
scroll_forward:
		if (screen * size > msgCount) {
			screen = msgCount / size;
			printf(catgets(catd, CATSET, 7,
					"On last screenful of messages\n"));
		}
		break;

	case '-':
		if (arg[1] == '\0')
			screen--;
		else
			screen -= atoi(arg + 1);
		if (screen < 0) {
			screen = 0;
			printf(catgets(catd, CATSET, 8,
					"On first screenful of messages\n"));
		}
		if (cur[0] == -1)
			cur[0] = -2;
		break;

	default:
		printf(catgets(catd, CATSET, 9,
			"Unrecognized scrolling command \"%s\"\n"), arg);
		return(1);
	}
	return(headers(cur));
}