#include "putty.h"
#include "misc.h"
int fznotify(sftpEventTypes type)
{
fprintf(stdout, "%c", (int)type + '0');
fflush(stdout);
return 0;
}
int fzprintf(sftpEventTypes type, const char* fmt, ...)
{
va_list ap;
char* str, *p, *s;
va_start(ap, fmt);
str = dupvprintf(fmt, ap);
p = str;
s = str;
while (1)
{
if (*p == '\r' || *p == '\n')
{
if (p != s)
{
*p = 0;
fprintf(stdout, "%c%s\n", (int)type + '0', s);
s = p + 1;
}
else
s++;
}
else if (!*p)
{
if (p != s)
{
*p = 0;
fprintf(stdout, "%c%s\n", (int)type + '0', s);
s = p + 1;
}
break;
}
p++;
}
sfree(str);
va_end(ap);
fflush(stdout);
return 0;
}
int fzprintf_raw_untrusted(sftpEventTypes type, const char* fmt, ...)
{
va_list ap;
char* str, *p, *s;
va_start(ap, fmt);
str = dupvprintf(fmt, ap);
p = str;
s = str;
while (*p)
{
if (*p == '\r')
p++;
else if (*p == '\n')
{
if (s != str)
*s++ = ' ';
p++;
}
else if (*p)
*s++ = *p++;
}
while (s != str && *(s - 1) == ' ')
s--;
*s = 0;
if (*str)
fprintf(stdout, "%c%s\n", (int)type + '0', str);
sfree(str);
va_end(ap);
fflush(stdout);
return 0;
}
int fzprintf_raw(sftpEventTypes type, const char* fmt, ...)
{
va_list ap;
char* str ;
va_start(ap, fmt);
str = dupvprintf(fmt, ap);
fprintf(stdout, "%c", (int)type + '0');
fprintf(stdout, str);
sfree(str);
va_end(ap);
fflush(stdout);
return 0;
}
int fznotify1(sftpEventTypes type, int data)
{
fprintf(stdout, "%c%d\n", (int)type + '0', data);
fflush(stdout);
return 0;
}
int bytesAvailable[2] = { 0, 0 };
char* input_pushback = 0;
#ifndef _WINDOWS
#include <unistd.h>
char *input_buf = 0;
int input_buflen = 0, input_bufsize = 0;
#endif
static int ReadQuotas(int i)
{
#ifdef _WINDOWS
HANDLE hin;
DWORD savemode, newmode;
hin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hin, &savemode);
newmode = savemode | ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT;
newmode &= ~ENABLE_ECHO_INPUT;
SetConsoleMode(hin, newmode);
while (bytesAvailable[i] == 0)
{
DWORD read;
BOOL r;
char buffer[21];
r = ReadFile(hin, buffer, 20, &read, 0);
if (!r || read == 0)
fatalbox("ReadFile failed in ReadQuotas");
buffer[read] = 0;
if (buffer[0] != '-')
{
if (input_pushback != 0)
fatalbox("input_pushback not null!");
else
input_pushback = strdup(buffer);
}
else
ProcessQuotaCmd(buffer);
}
SetConsoleMode(hin, savemode);
#else
char* line;
while (bytesAvailable[i] == 0)
{
int error = 0;
line = read_input_line(1, &error);
if (line == NULL || error)
{
fatalbox("read_input_line failed in ReadQuotas");
break;
}
if (line[0] != '-')
{
if (input_pushback != 0)
fatalbox("input_pushback not null!");
else
input_pushback = strdup(line);
}
else
ProcessQuotaCmd(line);
sfree(line);
}
#endif //_WINDOWS
return 1;
}
int RequestQuota(int i, int bytes)
{
if (bytesAvailable[i] == 0)
{
bytesAvailable[i] = 0;
fznotify(sftpUsedQuotaRecv + i);
}
if (bytesAvailable[i] == 0)
{
ReadQuotas(i);
}
if (bytesAvailable[i] == -1)
return bytes;
if (bytesAvailable[i] > bytes)
return bytes;
return bytesAvailable[i];
}
void UpdateQuota(int i, int bytes)
{
if (bytesAvailable[i] == -1)
return;
if (bytesAvailable[i] > bytes)
bytesAvailable[i] -= bytes;
else
bytesAvailable[i] = 0;
}
int ProcessQuotaCmd(const char* line)
{
int direction = 0, number, pos;
if (line[0] != '-')
return 0;
if (line[1] == '0')
direction = 0;
else if (line[1] == '1')
direction = 1;
else
fatalbox("Invalid data received in ReadQuotas: Unknown direction");
if (line[2] == '-')
{
bytesAvailable[direction] = -1;
return 0;
}
number = 0;
for (pos = 2;; pos++)
{
if (line[pos] == 0 || line[pos] == '\r' || line[pos] == '\n')
break;
if (line[pos] < '0' || line[pos] > '9')
fatalbox("Invalid data received in ReadQuotas: Bytecount not a number");
number *= 10;
number += line[pos] - '0';
}
if (bytesAvailable[direction] == -1)
bytesAvailable[direction] = number;
else
bytesAvailable[direction] += number;
return 1;
}
char* get_input_pushback()
{
char* pushback = input_pushback;
input_pushback = 0;
return pushback;
}
int has_input_pushback()
{
if (input_pushback != 0)
return 1;
else
return 0;
}
#ifndef _WINDOWS
static void clear_input_buffers(int free)
{
if (free && input_buf != NULL)
sfree(input_buf);
input_buf = 0;
input_bufsize = 0;
input_buflen = 0;
}
char* read_input_line(int force, int* error)
{
int ret;
do {
if (input_buflen >= input_bufsize) {
input_bufsize = input_buflen + 512;
input_buf = sresize(input_buf, input_bufsize, char);
}
ret = read(0, input_buf+input_buflen, 1);
if (ret < 0) {
perror("read");
*error = 1;
clear_input_buffers(1);
return NULL;
}
if (ret == 0) {
/* eof on stdin; no error, but no answer either */
*error = 1;
clear_input_buffers(1);
return NULL;
}
if (input_buf[input_buflen++] == '\n') {
/* we have a full line */
char* buf = input_buf;
clear_input_buffers(0);
return buf;
}
} while(force);
return NULL;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1