mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
Standard pgindent run for 8.1.
This commit is contained in:
parent
790c01d280
commit
1dc3498251
@ -125,10 +125,10 @@ Datum
|
|||||||
gbt_cash_penalty(PG_FUNCTION_ARGS)
|
gbt_cash_penalty(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
cashKEY *origentry = (cashKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
|
cashKEY *origentry = (cashKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
|
||||||
cashKEY *newentry = (cashKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
cashKEY *newentry = (cashKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
||||||
float *result = (float *) PG_GETARG_POINTER(2);
|
float *result = (float *) PG_GETARG_POINTER(2);
|
||||||
|
|
||||||
penalty_num(result,origentry->lower,origentry->upper,newentry->lower,newentry->upper);
|
penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
|
|
||||||
@ -138,8 +138,8 @@ Datum
|
|||||||
gbt_cash_picksplit(PG_FUNCTION_ARGS)
|
gbt_cash_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -148,15 +148,15 @@ gbt_date_penalty(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
diff = DatumGetInt32(DirectFunctionCall2(
|
diff = DatumGetInt32(DirectFunctionCall2(
|
||||||
date_mi,
|
date_mi,
|
||||||
DateADTGetDatum(newentry->upper),
|
DateADTGetDatum(newentry->upper),
|
||||||
DateADTGetDatum(origentry->upper)));
|
DateADTGetDatum(origentry->upper)));
|
||||||
|
|
||||||
res = Max(diff, 0);
|
res = Max(diff, 0);
|
||||||
|
|
||||||
diff = DatumGetInt32(DirectFunctionCall2(
|
diff = DatumGetInt32(DirectFunctionCall2(
|
||||||
date_mi,
|
date_mi,
|
||||||
DateADTGetDatum(origentry->lower),
|
DateADTGetDatum(origentry->lower),
|
||||||
DateADTGetDatum(newentry->lower)));
|
DateADTGetDatum(newentry->lower)));
|
||||||
|
|
||||||
res += Max(diff, 0);
|
res += Max(diff, 0);
|
||||||
|
|
||||||
@ -166,8 +166,8 @@ gbt_date_penalty(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
diff = DatumGetInt32(DirectFunctionCall2(
|
diff = DatumGetInt32(DirectFunctionCall2(
|
||||||
date_mi,
|
date_mi,
|
||||||
DateADTGetDatum(origentry->upper),
|
DateADTGetDatum(origentry->upper),
|
||||||
DateADTGetDatum(origentry->lower)));
|
DateADTGetDatum(origentry->lower)));
|
||||||
*result += FLT_MIN;
|
*result += FLT_MIN;
|
||||||
*result += (float) (res / ((double) (res + diff)));
|
*result += (float) (res / ((double) (res + diff)));
|
||||||
*result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
|
*result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
|
||||||
@ -181,8 +181,8 @@ Datum
|
|||||||
gbt_date_picksplit(PG_FUNCTION_ARGS)
|
gbt_date_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ gbt_float4_penalty(PG_FUNCTION_ARGS)
|
|||||||
float4KEY *newentry = (float4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
float4KEY *newentry = (float4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
||||||
float *result = (float *) PG_GETARG_POINTER(2);
|
float *result = (float *) PG_GETARG_POINTER(2);
|
||||||
|
|
||||||
penalty_num(result,origentry->lower,origentry->upper,newentry->lower,newentry->upper);
|
penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
|
|
||||||
@ -137,8 +137,8 @@ Datum
|
|||||||
gbt_float4_picksplit(PG_FUNCTION_ARGS)
|
gbt_float4_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ gbt_float8_penalty(PG_FUNCTION_ARGS)
|
|||||||
float8KEY *newentry = (float8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
float8KEY *newentry = (float8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
||||||
float *result = (float *) PG_GETARG_POINTER(2);
|
float *result = (float *) PG_GETARG_POINTER(2);
|
||||||
|
|
||||||
penalty_num(result,origentry->lower,origentry->upper,newentry->lower,newentry->upper);
|
penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
|
|
||||||
@ -139,8 +139,8 @@ Datum
|
|||||||
gbt_float8_picksplit(PG_FUNCTION_ARGS)
|
gbt_float8_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ gbt_inet_penalty(PG_FUNCTION_ARGS)
|
|||||||
inetKEY *newentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
inetKEY *newentry = (inetKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
||||||
float *result = (float *) PG_GETARG_POINTER(2);
|
float *result = (float *) PG_GETARG_POINTER(2);
|
||||||
|
|
||||||
penalty_num(result,origentry->lower,origentry->upper,newentry->lower,newentry->upper);
|
penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
|
|
||||||
@ -204,8 +204,8 @@ Datum
|
|||||||
gbt_inet_picksplit(PG_FUNCTION_ARGS)
|
gbt_inet_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -128,10 +128,10 @@ Datum
|
|||||||
gbt_int2_penalty(PG_FUNCTION_ARGS)
|
gbt_int2_penalty(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
int16KEY *origentry = (int16KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
|
int16KEY *origentry = (int16KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
|
||||||
int16KEY *newentry = (int16KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
int16KEY *newentry = (int16KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
||||||
float *result = (float *) PG_GETARG_POINTER(2);
|
float *result = (float *) PG_GETARG_POINTER(2);
|
||||||
|
|
||||||
penalty_num(result,origentry->lower,origentry->upper,newentry->lower,newentry->upper);
|
penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
@ -140,8 +140,8 @@ Datum
|
|||||||
gbt_int2_picksplit(PG_FUNCTION_ARGS)
|
gbt_int2_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -126,10 +126,10 @@ Datum
|
|||||||
gbt_int4_penalty(PG_FUNCTION_ARGS)
|
gbt_int4_penalty(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
int32KEY *origentry = (int32KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
|
int32KEY *origentry = (int32KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
|
||||||
int32KEY *newentry = (int32KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
int32KEY *newentry = (int32KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
||||||
float *result = (float *) PG_GETARG_POINTER(2);
|
float *result = (float *) PG_GETARG_POINTER(2);
|
||||||
|
|
||||||
penalty_num(result,origentry->lower,origentry->upper,newentry->lower,newentry->upper);
|
penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
@ -138,8 +138,8 @@ Datum
|
|||||||
gbt_int4_picksplit(PG_FUNCTION_ARGS)
|
gbt_int4_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -125,10 +125,10 @@ Datum
|
|||||||
gbt_int8_penalty(PG_FUNCTION_ARGS)
|
gbt_int8_penalty(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
int64KEY *origentry = (int64KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
|
int64KEY *origentry = (int64KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
|
||||||
int64KEY *newentry = (int64KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
int64KEY *newentry = (int64KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
||||||
float *result = (float *) PG_GETARG_POINTER(2);
|
float *result = (float *) PG_GETARG_POINTER(2);
|
||||||
|
|
||||||
penalty_num(result,origentry->lower,origentry->upper,newentry->lower,newentry->upper);
|
penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
@ -137,8 +137,8 @@ Datum
|
|||||||
gbt_int8_picksplit(PG_FUNCTION_ARGS)
|
gbt_int8_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,8 @@ gbt_intvkey_cmp(const void *a, const void *b)
|
|||||||
{
|
{
|
||||||
return DatumGetInt32(
|
return DatumGetInt32(
|
||||||
DirectFunctionCall2(interval_cmp,
|
DirectFunctionCall2(interval_cmp,
|
||||||
IntervalPGetDatum(((Nsrt *) a)->t),
|
IntervalPGetDatum(((Nsrt *) a)->t),
|
||||||
IntervalPGetDatum(((Nsrt *) b)->t)
|
IntervalPGetDatum(((Nsrt *) b)->t)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ intr2num(const Interval *i)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* INTERVALSIZE should be the actual size-on-disk of an Interval, as shown
|
* INTERVALSIZE should be the actual size-on-disk of an Interval, as shown
|
||||||
* in pg_type. This might be less than sizeof(Interval) if the compiler
|
* in pg_type. This might be less than sizeof(Interval) if the compiler
|
||||||
* insists on adding alignment padding at the end of the struct.
|
* insists on adding alignment padding at the end of the struct.
|
||||||
*/
|
*/
|
||||||
#define INTERVALSIZE 16
|
#define INTERVALSIZE 16
|
||||||
@ -202,7 +202,7 @@ gbt_intv_penalty(PG_FUNCTION_ARGS)
|
|||||||
inew[0] = intr2num(&newentry->lower);
|
inew[0] = intr2num(&newentry->lower);
|
||||||
inew[1] = intr2num(&newentry->upper);
|
inew[1] = intr2num(&newentry->upper);
|
||||||
|
|
||||||
penalty_num(result,iorg[0],iorg[1],inew[0],inew[1]);
|
penalty_num(result, iorg[0], iorg[1], inew[0], inew[1]);
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
|
|
||||||
@ -212,8 +212,8 @@ Datum
|
|||||||
gbt_intv_picksplit(PG_FUNCTION_ARGS)
|
gbt_intv_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,8 @@ gbt_macadkey_cmp(const void *a, const void *b)
|
|||||||
return DatumGetInt32(
|
return DatumGetInt32(
|
||||||
DirectFunctionCall2(
|
DirectFunctionCall2(
|
||||||
macaddr_cmp,
|
macaddr_cmp,
|
||||||
PointerGetDatum(&((Nsrt *) a)->t[0]),
|
PointerGetDatum(&((Nsrt *) a)->t[0]),
|
||||||
PointerGetDatum(&((Nsrt *) b)->t[0])
|
PointerGetDatum(&((Nsrt *) b)->t[0])
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -157,7 +157,7 @@ gbt_macad_penalty(PG_FUNCTION_ARGS)
|
|||||||
inew[0] = mac_2_uint64(&newentry->lower);
|
inew[0] = mac_2_uint64(&newentry->lower);
|
||||||
inew[1] = mac_2_uint64(&newentry->upper);
|
inew[1] = mac_2_uint64(&newentry->upper);
|
||||||
|
|
||||||
penalty_num(result,iorg[0],iorg[1],inew[0],inew[1]);
|
penalty_num(result, iorg[0], iorg[1], inew[0], inew[1]);
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
|
|
||||||
@ -167,8 +167,8 @@ Datum
|
|||||||
gbt_macad_picksplit(PG_FUNCTION_ARGS)
|
gbt_macad_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ gbt_oid_penalty(PG_FUNCTION_ARGS)
|
|||||||
oidKEY *newentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
oidKEY *newentry = (oidKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
||||||
float *result = (float *) PG_GETARG_POINTER(2);
|
float *result = (float *) PG_GETARG_POINTER(2);
|
||||||
|
|
||||||
penalty_num(result,origentry->lower,origentry->upper,newentry->lower,newentry->upper);
|
penalty_num(result, origentry->lower, origentry->upper, newentry->lower, newentry->upper);
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
@ -138,8 +138,8 @@ Datum
|
|||||||
gbt_oid_picksplit(PG_FUNCTION_ARGS)
|
gbt_oid_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ gbt_text_compress(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
||||||
|
|
||||||
if ( tinfo.eml == 0 )
|
if (tinfo.eml == 0)
|
||||||
{
|
{
|
||||||
tinfo.eml = pg_database_encoding_max_length();
|
tinfo.eml = pg_database_encoding_max_length();
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ gbt_bpchar_compress(PG_FUNCTION_ARGS)
|
|||||||
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
||||||
GISTENTRY *retval;
|
GISTENTRY *retval;
|
||||||
|
|
||||||
if ( tinfo.eml == 0 )
|
if (tinfo.eml == 0)
|
||||||
{
|
{
|
||||||
tinfo.eml = pg_database_encoding_max_length();
|
tinfo.eml = pg_database_encoding_max_length();
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ gbt_bpchar_compress(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
|
|
||||||
Datum d = DirectFunctionCall1(rtrim1, entry->key);
|
Datum d = DirectFunctionCall1(rtrim1, entry->key);
|
||||||
GISTENTRY trim;
|
GISTENTRY trim;
|
||||||
|
|
||||||
gistentryinit(trim, d,
|
gistentryinit(trim, d,
|
||||||
entry->rel, entry->page,
|
entry->rel, entry->page,
|
||||||
@ -136,7 +136,7 @@ gbt_text_consistent(PG_FUNCTION_ARGS)
|
|||||||
bool retval = FALSE;
|
bool retval = FALSE;
|
||||||
GBT_VARKEY_R r = gbt_var_key_readable(key);
|
GBT_VARKEY_R r = gbt_var_key_readable(key);
|
||||||
|
|
||||||
if ( tinfo.eml == 0 )
|
if (tinfo.eml == 0)
|
||||||
{
|
{
|
||||||
tinfo.eml = pg_database_encoding_max_length();
|
tinfo.eml = pg_database_encoding_max_length();
|
||||||
}
|
}
|
||||||
@ -158,7 +158,7 @@ gbt_bpchar_consistent(PG_FUNCTION_ARGS)
|
|||||||
bool retval;
|
bool retval;
|
||||||
GBT_VARKEY_R r = gbt_var_key_readable(key);
|
GBT_VARKEY_R r = gbt_var_key_readable(key);
|
||||||
|
|
||||||
if ( tinfo.eml == 0 )
|
if (tinfo.eml == 0)
|
||||||
{
|
{
|
||||||
tinfo.eml = pg_database_encoding_max_length();
|
tinfo.eml = pg_database_encoding_max_length();
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ static bool
|
|||||||
gbt_timegt(const void *a, const void *b)
|
gbt_timegt(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return DatumGetBool(
|
return DatumGetBool(
|
||||||
DirectFunctionCall2(time_gt, PointerGetDatum(a), PointerGetDatum(b))
|
DirectFunctionCall2(time_gt, PointerGetDatum(a), PointerGetDatum(b))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ static bool
|
|||||||
gbt_timege(const void *a, const void *b)
|
gbt_timege(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return DatumGetBool(
|
return DatumGetBool(
|
||||||
DirectFunctionCall2(time_ge, PointerGetDatum(a), PointerGetDatum(b))
|
DirectFunctionCall2(time_ge, PointerGetDatum(a), PointerGetDatum(b))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ static bool
|
|||||||
gbt_timeeq(const void *a, const void *b)
|
gbt_timeeq(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return DatumGetBool(
|
return DatumGetBool(
|
||||||
DirectFunctionCall2(time_eq, PointerGetDatum(a), PointerGetDatum(b))
|
DirectFunctionCall2(time_eq, PointerGetDatum(a), PointerGetDatum(b))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ static bool
|
|||||||
gbt_timele(const void *a, const void *b)
|
gbt_timele(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return DatumGetBool(
|
return DatumGetBool(
|
||||||
DirectFunctionCall2(time_le, PointerGetDatum(a), PointerGetDatum(b))
|
DirectFunctionCall2(time_le, PointerGetDatum(a), PointerGetDatum(b))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ static bool
|
|||||||
gbt_timelt(const void *a, const void *b)
|
gbt_timelt(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return DatumGetBool(
|
return DatumGetBool(
|
||||||
DirectFunctionCall2(time_lt, PointerGetDatum(a), PointerGetDatum(b))
|
DirectFunctionCall2(time_lt, PointerGetDatum(a), PointerGetDatum(b))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,15 +212,15 @@ gbt_time_penalty(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
intr = DatumGetIntervalP(DirectFunctionCall2(
|
intr = DatumGetIntervalP(DirectFunctionCall2(
|
||||||
time_mi_time,
|
time_mi_time,
|
||||||
P_TimeADTGetDatum(newentry->upper),
|
P_TimeADTGetDatum(newentry->upper),
|
||||||
P_TimeADTGetDatum(origentry->upper)));
|
P_TimeADTGetDatum(origentry->upper)));
|
||||||
res = INTERVAL_TO_SEC(intr);
|
res = INTERVAL_TO_SEC(intr);
|
||||||
res = Max(res, 0);
|
res = Max(res, 0);
|
||||||
|
|
||||||
intr = DatumGetIntervalP(DirectFunctionCall2(
|
intr = DatumGetIntervalP(DirectFunctionCall2(
|
||||||
time_mi_time,
|
time_mi_time,
|
||||||
P_TimeADTGetDatum(origentry->lower),
|
P_TimeADTGetDatum(origentry->lower),
|
||||||
P_TimeADTGetDatum(newentry->lower)));
|
P_TimeADTGetDatum(newentry->lower)));
|
||||||
res2 = INTERVAL_TO_SEC(intr);
|
res2 = INTERVAL_TO_SEC(intr);
|
||||||
res2 = Max(res2, 0);
|
res2 = Max(res2, 0);
|
||||||
|
|
||||||
@ -232,8 +232,8 @@ gbt_time_penalty(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
intr = DatumGetIntervalP(DirectFunctionCall2(
|
intr = DatumGetIntervalP(DirectFunctionCall2(
|
||||||
time_mi_time,
|
time_mi_time,
|
||||||
P_TimeADTGetDatum(origentry->upper),
|
P_TimeADTGetDatum(origentry->upper),
|
||||||
P_TimeADTGetDatum(origentry->lower)));
|
P_TimeADTGetDatum(origentry->lower)));
|
||||||
*result += FLT_MIN;
|
*result += FLT_MIN;
|
||||||
*result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
|
*result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
|
||||||
*result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
|
*result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
|
||||||
@ -247,8 +247,8 @@ Datum
|
|||||||
gbt_time_picksplit(PG_FUNCTION_ARGS)
|
gbt_time_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -32,13 +32,13 @@ Datum gbt_ts_penalty(PG_FUNCTION_ARGS);
|
|||||||
Datum gbt_ts_same(PG_FUNCTION_ARGS);
|
Datum gbt_ts_same(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
|
|
||||||
#define P_TimestampGetDatum(x) PointerGetDatum( &(x) )
|
#define P_TimestampGetDatum(x) PointerGetDatum( &(x) )
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
gbt_tsgt(const void *a, const void *b)
|
gbt_tsgt(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return DatumGetBool(
|
return DatumGetBool(
|
||||||
DirectFunctionCall2(timestamp_gt, PointerGetDatum(a), PointerGetDatum(b))
|
DirectFunctionCall2(timestamp_gt, PointerGetDatum(a), PointerGetDatum(b))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ static bool
|
|||||||
gbt_tsge(const void *a, const void *b)
|
gbt_tsge(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return DatumGetBool(
|
return DatumGetBool(
|
||||||
DirectFunctionCall2(timestamp_ge, PointerGetDatum(a), PointerGetDatum(b))
|
DirectFunctionCall2(timestamp_ge, PointerGetDatum(a), PointerGetDatum(b))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ static bool
|
|||||||
gbt_tseq(const void *a, const void *b)
|
gbt_tseq(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return DatumGetBool(
|
return DatumGetBool(
|
||||||
DirectFunctionCall2(timestamp_eq, PointerGetDatum(a), PointerGetDatum(b))
|
DirectFunctionCall2(timestamp_eq, PointerGetDatum(a), PointerGetDatum(b))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ static bool
|
|||||||
gbt_tsle(const void *a, const void *b)
|
gbt_tsle(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return DatumGetBool(
|
return DatumGetBool(
|
||||||
DirectFunctionCall2(timestamp_le, PointerGetDatum(a), PointerGetDatum(b))
|
DirectFunctionCall2(timestamp_le, PointerGetDatum(a), PointerGetDatum(b))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ static bool
|
|||||||
gbt_tslt(const void *a, const void *b)
|
gbt_tslt(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
return DatumGetBool(
|
return DatumGetBool(
|
||||||
DirectFunctionCall2(timestamp_lt, PointerGetDatum(a), PointerGetDatum(b))
|
DirectFunctionCall2(timestamp_lt, PointerGetDatum(a), PointerGetDatum(b))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ tstz_to_ts_gmt(Timestamp *gmt, TimestampTz *ts)
|
|||||||
*gmt = *ts;
|
*gmt = *ts;
|
||||||
DecodeSpecial(0, "gmt", &val);
|
DecodeSpecial(0, "gmt", &val);
|
||||||
|
|
||||||
if ( *ts < DT_NOEND && *ts > DT_NOBEGIN )
|
if (*ts < DT_NOEND && *ts > DT_NOBEGIN)
|
||||||
{
|
{
|
||||||
tz = val * 60;
|
tz = val * 60;
|
||||||
|
|
||||||
@ -217,10 +217,10 @@ gbt_ts_union(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
|
|
||||||
#define penalty_check_max_float(val) do { \
|
#define penalty_check_max_float(val) do { \
|
||||||
if ( val > FLT_MAX ) \
|
if ( val > FLT_MAX ) \
|
||||||
val = FLT_MAX; \
|
val = FLT_MAX; \
|
||||||
if ( val < -FLT_MAX ) \
|
if ( val < -FLT_MAX ) \
|
||||||
val = -FLT_MAX; \
|
val = -FLT_MAX; \
|
||||||
} while(false);
|
} while(false);
|
||||||
|
|
||||||
|
|
||||||
@ -232,24 +232,24 @@ gbt_ts_penalty(PG_FUNCTION_ARGS)
|
|||||||
tsKEY *newentry = (tsKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
tsKEY *newentry = (tsKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
|
||||||
float *result = (float *) PG_GETARG_POINTER(2);
|
float *result = (float *) PG_GETARG_POINTER(2);
|
||||||
|
|
||||||
double orgdbl[2],
|
double orgdbl[2],
|
||||||
newdbl[2];
|
newdbl[2];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We are allways using "double" timestamps here.
|
* We are allways using "double" timestamps here. Precision should be good
|
||||||
Precision should be good enough.
|
* enough.
|
||||||
*/
|
*/
|
||||||
orgdbl[0] = ( (double) origentry->lower ) ;
|
orgdbl[0] = ((double) origentry->lower);
|
||||||
orgdbl[1] = ( (double) origentry->upper ) ;
|
orgdbl[1] = ((double) origentry->upper);
|
||||||
newdbl[0] = ( (double) newentry->lower ) ;
|
newdbl[0] = ((double) newentry->lower);
|
||||||
newdbl[1] = ( (double) newentry->upper ) ;
|
newdbl[1] = ((double) newentry->upper);
|
||||||
|
|
||||||
penalty_check_max_float( orgdbl[0] );
|
penalty_check_max_float(orgdbl[0]);
|
||||||
penalty_check_max_float( orgdbl[1] );
|
penalty_check_max_float(orgdbl[1]);
|
||||||
penalty_check_max_float( newdbl[0] );
|
penalty_check_max_float(newdbl[0]);
|
||||||
penalty_check_max_float( newdbl[1] );
|
penalty_check_max_float(newdbl[1]);
|
||||||
|
|
||||||
penalty_num(result,orgdbl[0],orgdbl[1],newdbl[0],newdbl[1]);
|
penalty_num(result, orgdbl[0], orgdbl[1], newdbl[0], newdbl[1]);
|
||||||
|
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
|
|
||||||
@ -260,8 +260,8 @@ Datum
|
|||||||
gbt_ts_picksplit(PG_FUNCTION_ARGS)
|
gbt_ts_picksplit(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
PG_RETURN_POINTER(gbt_num_picksplit(
|
PG_RETURN_POINTER(gbt_num_picksplit(
|
||||||
(GistEntryVector *) PG_GETARG_POINTER(0),
|
(GistEntryVector *) PG_GETARG_POINTER(0),
|
||||||
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
|
||||||
&tinfo
|
&tinfo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -48,17 +48,17 @@ typedef struct
|
|||||||
* Note: The factor 0.49 in following macro avoids floating point overflows
|
* Note: The factor 0.49 in following macro avoids floating point overflows
|
||||||
*/
|
*/
|
||||||
#define penalty_num(result,olower,oupper,nlower,nupper) do { \
|
#define penalty_num(result,olower,oupper,nlower,nupper) do { \
|
||||||
double tmp = 0.0F; \
|
double tmp = 0.0F; \
|
||||||
(*(result)) = 0.0F; \
|
(*(result)) = 0.0F; \
|
||||||
if ( (nupper) > (oupper) ) \
|
if ( (nupper) > (oupper) ) \
|
||||||
tmp += ( ((double)nupper)*0.49F - ((double)oupper)*0.49F ); \
|
tmp += ( ((double)nupper)*0.49F - ((double)oupper)*0.49F ); \
|
||||||
if ( (olower) > (nlower) ) \
|
if ( (olower) > (nlower) ) \
|
||||||
tmp += ( ((double)olower)*0.49F - ((double)nlower)*0.49F ); \
|
tmp += ( ((double)olower)*0.49F - ((double)nlower)*0.49F ); \
|
||||||
if (tmp > 0.0F) \
|
if (tmp > 0.0F) \
|
||||||
{ \
|
{ \
|
||||||
(*(result)) += FLT_MIN; \
|
(*(result)) += FLT_MIN; \
|
||||||
(*(result)) += (float) ( ((double)(tmp)) / ( (double)(tmp) + ( ((double)(oupper))*0.49F - ((double)(olower))*0.49F ) ) ); \
|
(*(result)) += (float) ( ((double)(tmp)) / ( (double)(tmp) + ( ((double)(oupper))*0.49F - ((double)(olower))*0.49F ) ) ); \
|
||||||
(*(result)) *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1)); \
|
(*(result)) *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1)); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
PG_FUNCTION_INFO_V1(gbt_var_decompress);
|
PG_FUNCTION_INFO_V1(gbt_var_decompress);
|
||||||
Datum gbt_var_decompress(PG_FUNCTION_ARGS);
|
Datum gbt_var_decompress(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
gbt_var_decompress(PG_FUNCTION_ARGS)
|
gbt_var_decompress(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
||||||
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
|
GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
|
||||||
|
|
||||||
if (key != (GBT_VARKEY *) DatumGetPointer(entry->key))
|
if (key != (GBT_VARKEY *) DatumGetPointer(entry->key))
|
||||||
{
|
{
|
||||||
@ -92,45 +92,47 @@ static int32
|
|||||||
gbt_var_node_cp_len(const GBT_VARKEY * node, const gbtree_vinfo * tinfo)
|
gbt_var_node_cp_len(const GBT_VARKEY * node, const gbtree_vinfo * tinfo)
|
||||||
{
|
{
|
||||||
|
|
||||||
GBT_VARKEY_R r = gbt_var_key_readable(node);
|
GBT_VARKEY_R r = gbt_var_key_readable(node);
|
||||||
int32 i = 0;
|
int32 i = 0;
|
||||||
int32 l = 0;
|
int32 l = 0;
|
||||||
int32 t1len = VARSIZE(r.lower) - VARHDRSZ ;
|
int32 t1len = VARSIZE(r.lower) - VARHDRSZ;
|
||||||
int32 t2len = VARSIZE(r.upper) - VARHDRSZ ;
|
int32 t2len = VARSIZE(r.upper) - VARHDRSZ;
|
||||||
int32 ml = Min(t1len, t2len);
|
int32 ml = Min(t1len, t2len);
|
||||||
|
|
||||||
char *p1 = VARDATA(r.lower);
|
char *p1 = VARDATA(r.lower);
|
||||||
char *p2 = VARDATA(r.upper);
|
char *p2 = VARDATA(r.upper);
|
||||||
|
|
||||||
if ( ml == 0 )
|
if (ml == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while ( i < ml )
|
while (i < ml)
|
||||||
{
|
{
|
||||||
if ( tinfo->eml > 1 && l == 0 )
|
if (tinfo->eml > 1 && l == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( ( l = pg_mblen(p1) ) != pg_mblen(p2) )
|
if ((l = pg_mblen(p1)) != pg_mblen(p2))
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*p1 != *p2)
|
if (*p1 != *p2)
|
||||||
{
|
{
|
||||||
if( tinfo->eml > 1 )
|
if (tinfo->eml > 1)
|
||||||
{
|
{
|
||||||
return (i-l+1);
|
return (i - l + 1);
|
||||||
} else {
|
}
|
||||||
return i;
|
else
|
||||||
}
|
{
|
||||||
}
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p1++;
|
p1++;
|
||||||
p2++;
|
p2++;
|
||||||
l--;
|
l--;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return (ml); /* lower == upper */
|
return (ml); /* lower == upper */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -141,35 +143,37 @@ static bool
|
|||||||
gbt_bytea_pf_match(const bytea *pf, const bytea *query, const gbtree_vinfo * tinfo)
|
gbt_bytea_pf_match(const bytea *pf, const bytea *query, const gbtree_vinfo * tinfo)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool out = FALSE;
|
bool out = FALSE;
|
||||||
int32 k = 0;
|
int32 k = 0;
|
||||||
int32 qlen = VARSIZE(query) - VARHDRSZ ;
|
int32 qlen = VARSIZE(query) - VARHDRSZ;
|
||||||
int32 nlen = VARSIZE(pf) - VARHDRSZ ;
|
int32 nlen = VARSIZE(pf) - VARHDRSZ;
|
||||||
|
|
||||||
if (nlen <= qlen)
|
if (nlen <= qlen)
|
||||||
{
|
{
|
||||||
char *q = VARDATA(query);
|
char *q = VARDATA(query);
|
||||||
char *n = VARDATA(pf);
|
char *n = VARDATA(pf);
|
||||||
|
|
||||||
if ( tinfo->eml > 1 )
|
if (tinfo->eml > 1)
|
||||||
{
|
{
|
||||||
out = ( varstr_cmp(q, nlen, n, nlen) == 0 );
|
out = (varstr_cmp(q, nlen, n, nlen) == 0);
|
||||||
} else {
|
}
|
||||||
out = TRUE;
|
else
|
||||||
for (k = 0; k < nlen; k++)
|
{
|
||||||
{
|
out = TRUE;
|
||||||
if (*n != *q)
|
for (k = 0; k < nlen; k++)
|
||||||
{
|
{
|
||||||
out = FALSE;
|
if (*n != *q)
|
||||||
break;
|
{
|
||||||
}
|
out = FALSE;
|
||||||
if (k < (nlen - 1))
|
break;
|
||||||
{
|
}
|
||||||
q++;
|
if (k < (nlen - 1))
|
||||||
n++;
|
{
|
||||||
}
|
q++;
|
||||||
}
|
n++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
@ -184,10 +188,10 @@ static bool
|
|||||||
gbt_var_node_pf_match(const GBT_VARKEY_R * node, const bytea *query, const gbtree_vinfo * tinfo)
|
gbt_var_node_pf_match(const GBT_VARKEY_R * node, const bytea *query, const gbtree_vinfo * tinfo)
|
||||||
{
|
{
|
||||||
|
|
||||||
return ( tinfo->trnc && (
|
return (tinfo->trnc && (
|
||||||
gbt_bytea_pf_match(node->lower, query, tinfo) ||
|
gbt_bytea_pf_match(node->lower, query, tinfo) ||
|
||||||
gbt_bytea_pf_match(node->upper, query, tinfo)
|
gbt_bytea_pf_match(node->upper, query, tinfo)
|
||||||
) );
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,18 +205,18 @@ gbt_var_node_truncate(const GBT_VARKEY * node, int32 cpf_length, const gbtree_vi
|
|||||||
{
|
{
|
||||||
GBT_VARKEY *out = NULL;
|
GBT_VARKEY *out = NULL;
|
||||||
GBT_VARKEY_R r = gbt_var_key_readable(node);
|
GBT_VARKEY_R r = gbt_var_key_readable(node);
|
||||||
int32 len1 = VARSIZE(r.lower) - VARHDRSZ;
|
int32 len1 = VARSIZE(r.lower) - VARHDRSZ;
|
||||||
int32 len2 = VARSIZE(r.upper) - VARHDRSZ;
|
int32 len2 = VARSIZE(r.upper) - VARHDRSZ;
|
||||||
int32 si = 0;
|
int32 si = 0;
|
||||||
|
|
||||||
len1 = Min(len1,(cpf_length + 1));
|
len1 = Min(len1, (cpf_length + 1));
|
||||||
len2 = Min(len2,(cpf_length + 1));
|
len2 = Min(len2, (cpf_length + 1));
|
||||||
|
|
||||||
si = 2 * VARHDRSZ + INTALIGN(VARHDRSZ + len1) + len2;
|
si = 2 * VARHDRSZ + INTALIGN(VARHDRSZ + len1) + len2;
|
||||||
out = (GBT_VARKEY *) palloc(si);
|
out = (GBT_VARKEY *) palloc(si);
|
||||||
out->vl_len = si;
|
out->vl_len = si;
|
||||||
memcpy((void *) &(((char *) out)[VARHDRSZ]), (void *) r.lower, len1 + VARHDRSZ );
|
memcpy((void *) &(((char *) out)[VARHDRSZ]), (void *) r.lower, len1 + VARHDRSZ);
|
||||||
memcpy((void *) &(((char *) out)[VARHDRSZ + INTALIGN(VARHDRSZ + len1)]), (void *) r.upper, len2 + VARHDRSZ );
|
memcpy((void *) &(((char *) out)[VARHDRSZ + INTALIGN(VARHDRSZ + len1)]), (void *) r.upper, len2 + VARHDRSZ);
|
||||||
|
|
||||||
*((int32 *) &(((char *) out)[VARHDRSZ])) = len1 + VARHDRSZ;
|
*((int32 *) &(((char *) out)[VARHDRSZ])) = len1 + VARHDRSZ;
|
||||||
*((int32 *) &(((char *) out)[VARHDRSZ + INTALIGN(VARHDRSZ + len1)])) = len2 + VARHDRSZ;
|
*((int32 *) &(((char *) out)[VARHDRSZ + INTALIGN(VARHDRSZ + len1)])) = len2 + VARHDRSZ;
|
||||||
@ -568,8 +572,8 @@ gbt_var_consistent(
|
|||||||
else
|
else
|
||||||
retval = (
|
retval = (
|
||||||
(
|
(
|
||||||
(*tinfo->f_cmp) (key->lower, (bytea *) query) <= 0 &&
|
(*tinfo->f_cmp) (key->lower, (bytea *) query) <= 0 &&
|
||||||
(*tinfo->f_cmp) ((bytea *) query, (void *) key->upper) <= 0
|
(*tinfo->f_cmp) ((bytea *) query, (void *) key->upper) <= 0
|
||||||
) || gbt_var_node_pf_match(key, query, tinfo)
|
) || gbt_var_node_pf_match(key, query, tinfo)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -28,7 +28,8 @@ typedef struct
|
|||||||
/* Attribs */
|
/* Attribs */
|
||||||
|
|
||||||
enum gbtree_type t; /* data type */
|
enum gbtree_type t; /* data type */
|
||||||
int32 eml; /* cached pg_database_encoding_max_length (0: undefined) */
|
int32 eml; /* cached pg_database_encoding_max_length (0:
|
||||||
|
* undefined) */
|
||||||
bool trnc; /* truncate (=compress) key */
|
bool trnc; /* truncate (=compress) key */
|
||||||
|
|
||||||
/* Methods */
|
/* Methods */
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* darcy@druid.net
|
* darcy@druid.net
|
||||||
* http://www.druid.net/darcy/
|
* http://www.druid.net/darcy/
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/chkpass/chkpass.c,v 1.13 2005/01/29 22:35:01 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/chkpass/chkpass.c,v 1.14 2005/10/15 02:49:04 momjian Exp $
|
||||||
* best viewed with tabs set to 4
|
* best viewed with tabs set to 4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -90,8 +90,8 @@ chkpass_in(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
mysalt[0] = salt_chars[random() & 0x3f];
|
mysalt[0] = salt_chars[random() & 0x3f];
|
||||||
mysalt[1] = salt_chars[random() & 0x3f];
|
mysalt[1] = salt_chars[random() & 0x3f];
|
||||||
mysalt[2] = 0; /* technically the terminator is not
|
mysalt[2] = 0; /* technically the terminator is not necessary
|
||||||
* necessary but I like to play safe */
|
* but I like to play safe */
|
||||||
strcpy(result->password, crypt(str, mysalt));
|
strcpy(result->password, crypt(str, mysalt));
|
||||||
PG_RETURN_POINTER(result);
|
PG_RETURN_POINTER(result);
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ NDBOX *
|
|||||||
cube(text *str)
|
cube(text *str)
|
||||||
{
|
{
|
||||||
return cube_in(DatumGetCString(DirectFunctionCall1(textout,
|
return cube_in(DatumGetCString(DirectFunctionCall1(textout,
|
||||||
PointerGetDatum(str))));
|
PointerGetDatum(str))));
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
@ -219,7 +219,7 @@ g_cube_union(GistEntryVector *entryvec, int *sizep)
|
|||||||
for (i = 1; i < entryvec->n; i++)
|
for (i = 1; i < entryvec->n; i++)
|
||||||
{
|
{
|
||||||
out = g_cube_binary_union(tmp, (NDBOX *)
|
out = g_cube_binary_union(tmp, (NDBOX *)
|
||||||
DatumGetPointer(entryvec->vector[i].key),
|
DatumGetPointer(entryvec->vector[i].key),
|
||||||
sizep);
|
sizep);
|
||||||
tmp = out;
|
tmp = out;
|
||||||
}
|
}
|
||||||
@ -329,8 +329,7 @@ g_cube_picksplit(GistEntryVector *entryvec,
|
|||||||
size_waste = size_union - size_inter;
|
size_waste = size_union - size_inter;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* are these a more promising split than what we've already
|
* are these a more promising split than what we've already seen?
|
||||||
* seen?
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (size_waste > waste || firsttime)
|
if (size_waste > waste || firsttime)
|
||||||
@ -356,24 +355,24 @@ g_cube_picksplit(GistEntryVector *entryvec,
|
|||||||
rt_cube_size(datum_r, &size_r);
|
rt_cube_size(datum_r, &size_r);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now split up the regions between the two seeds. An important
|
* Now split up the regions between the two seeds. An important property
|
||||||
* property of this split algorithm is that the split vector v has the
|
* of this split algorithm is that the split vector v has the indices of
|
||||||
* indices of items to be split in order in its left and right
|
* items to be split in order in its left and right vectors. We exploit
|
||||||
* vectors. We exploit this property by doing a merge in the code
|
* this property by doing a merge in the code that actually splits the
|
||||||
* that actually splits the page.
|
* page.
|
||||||
*
|
*
|
||||||
* For efficiency, we also place the new index tuple in this loop. This
|
* For efficiency, we also place the new index tuple in this loop. This is
|
||||||
* is handled at the very end, when we have placed all the existing
|
* handled at the very end, when we have placed all the existing tuples
|
||||||
* tuples and i == maxoff + 1.
|
* and i == maxoff + 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
maxoff = OffsetNumberNext(maxoff);
|
maxoff = OffsetNumberNext(maxoff);
|
||||||
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
|
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If we've already decided where to place this item, just put it
|
* If we've already decided where to place this item, just put it on
|
||||||
* on the right list. Otherwise, we need to figure out which page
|
* the right list. Otherwise, we need to figure out which page needs
|
||||||
* needs the least enlargement in order to store the item.
|
* the least enlargement in order to store the item.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (i == seed_1)
|
if (i == seed_1)
|
||||||
@ -542,8 +541,8 @@ cube_union(NDBOX * a, NDBOX * b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* use the potentially smaller of the two boxes (b) to fill in the
|
* use the potentially smaller of the two boxes (b) to fill in the result,
|
||||||
* result, padding absent dimensions with zeroes
|
* padding absent dimensions with zeroes
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < b->dim; i++)
|
for (i = 0; i < b->dim; i++)
|
||||||
{
|
{
|
||||||
@ -562,7 +561,7 @@ cube_union(NDBOX * a, NDBOX * b)
|
|||||||
result->x[i] =
|
result->x[i] =
|
||||||
Min(Min(a->x[i], a->x[i + a->dim]), result->x[i]);
|
Min(Min(a->x[i], a->x[i + a->dim]), result->x[i]);
|
||||||
result->x[i + a->dim] = Max(Max(a->x[i],
|
result->x[i + a->dim] = Max(Max(a->x[i],
|
||||||
a->x[i + a->dim]), result->x[i + a->dim]);
|
a->x[i + a->dim]), result->x[i + a->dim]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
@ -620,12 +619,11 @@ cube_inter(NDBOX * a, NDBOX * b)
|
|||||||
result->x[i] =
|
result->x[i] =
|
||||||
Max(Min(a->x[i], a->x[i + a->dim]), result->x[i]);
|
Max(Min(a->x[i], a->x[i + a->dim]), result->x[i]);
|
||||||
result->x[i + a->dim] = Min(Max(a->x[i],
|
result->x[i + a->dim] = Min(Max(a->x[i],
|
||||||
a->x[i + a->dim]), result->x[i + a->dim]);
|
a->x[i + a->dim]), result->x[i + a->dim]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Is it OK to return a non-null intersection for non-overlapping
|
* Is it OK to return a non-null intersection for non-overlapping boxes?
|
||||||
* boxes?
|
|
||||||
*/
|
*/
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
@ -713,8 +711,8 @@ cube_cmp(NDBOX * a, NDBOX * b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if all common dimensions are equal, the cube with more
|
* if all common dimensions are equal, the cube with more dimensions
|
||||||
* dimensions wins
|
* wins
|
||||||
*/
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -736,8 +734,8 @@ cube_cmp(NDBOX * a, NDBOX * b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if all common dimensions are equal, the cube with more
|
* if all common dimensions are equal, the cube with more dimensions
|
||||||
* dimensions wins
|
* wins
|
||||||
*/
|
*/
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -797,10 +795,9 @@ cube_contains(NDBOX * a, NDBOX * b)
|
|||||||
if (a->dim < b->dim)
|
if (a->dim < b->dim)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* the further comparisons will make sense if the excess
|
* the further comparisons will make sense if the excess dimensions of
|
||||||
* dimensions of (b) were zeroes Since both UL and UR coordinates
|
* (b) were zeroes Since both UL and UR coordinates must be zero, we
|
||||||
* must be zero, we can check them all without worrying about
|
* can check them all without worrying about which is which.
|
||||||
* which is which.
|
|
||||||
*/
|
*/
|
||||||
for (i = a->dim; i < b->dim; i++)
|
for (i = a->dim; i < b->dim; i++)
|
||||||
{
|
{
|
||||||
|
@ -88,10 +88,10 @@ dbf_open(char *file, int flags)
|
|||||||
dbh->db_nfields = (dbh->db_hlen - sizeof(dbf_header)) / sizeof(dbf_field);
|
dbh->db_nfields = (dbh->db_hlen - sizeof(dbf_header)) / sizeof(dbf_field);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dbh->db_hlen - sizeof(dbf_header) isn't the correct size, cos
|
* dbh->db_hlen - sizeof(dbf_header) isn't the correct size, cos dbh->hlen
|
||||||
* dbh->hlen is in fact a little more cos of the 0x0D (and possibly
|
* is in fact a little more cos of the 0x0D (and possibly another byte,
|
||||||
* another byte, 0x4E, I have seen this somewhere). Because of
|
* 0x4E, I have seen this somewhere). Because of rounding everything turns
|
||||||
* rounding everything turns out right :)
|
* out right :)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((fields = (f_descr *) calloc(dbh->db_nfields, sizeof(f_descr)))
|
if ((fields = (f_descr *) calloc(dbh->db_nfields, sizeof(f_descr)))
|
||||||
@ -155,8 +155,7 @@ dbf_write_head(dbhead * dbh)
|
|||||||
now = time((time_t *) NULL);
|
now = time((time_t *) NULL);
|
||||||
dbf_time = localtime(&now);
|
dbf_time = localtime(&now);
|
||||||
head.dbh_year = dbf_time->tm_year;
|
head.dbh_year = dbf_time->tm_year;
|
||||||
head.dbh_month = dbf_time->tm_mon + 1; /* Months since January +
|
head.dbh_month = dbf_time->tm_mon + 1; /* Months since January + 1 */
|
||||||
* 1 */
|
|
||||||
head.dbh_day = dbf_time->tm_mday;
|
head.dbh_day = dbf_time->tm_mday;
|
||||||
|
|
||||||
put_long(head.dbh_records, dbh->db_records);
|
put_long(head.dbh_records, dbh->db_records);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#define _DBF_H
|
#define _DBF_H
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <gmon.h> /* we need it to define u_char type */
|
#include <gmon.h> /* we need it to define u_char type */
|
||||||
#endif
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -64,8 +64,7 @@ typedef struct
|
|||||||
u_char dbf_type; /* field-type */
|
u_char dbf_type; /* field-type */
|
||||||
u_char dbf_reserved[4]; /* some reserved stuff */
|
u_char dbf_reserved[4]; /* some reserved stuff */
|
||||||
u_char dbf_flen; /* field-length */
|
u_char dbf_flen; /* field-length */
|
||||||
u_char dbf_dec; /* number of decimal positions if type is
|
u_char dbf_dec; /* number of decimal positions if type is 'N' */
|
||||||
* 'N' */
|
|
||||||
u_char dbf_stub[14]; /* stuff we don't need */
|
u_char dbf_stub[14]; /* stuff we don't need */
|
||||||
} dbf_field;
|
} dbf_field;
|
||||||
|
|
||||||
@ -89,15 +88,14 @@ typedef struct
|
|||||||
u_char db_year; /* last update as YYMMDD */
|
u_char db_year; /* last update as YYMMDD */
|
||||||
u_char db_month;
|
u_char db_month;
|
||||||
u_char db_day;
|
u_char db_day;
|
||||||
u_long db_hlen; /* length of the diskheader, for
|
u_long db_hlen; /* length of the diskheader, for calculating
|
||||||
* calculating the offsets */
|
* the offsets */
|
||||||
u_long db_records; /* number of records */
|
u_long db_records; /* number of records */
|
||||||
u_long db_currec; /* current record-number starting at 0 */
|
u_long db_currec; /* current record-number starting at 0 */
|
||||||
u_short db_rlen; /* length of the record */
|
u_short db_rlen; /* length of the record */
|
||||||
u_char db_nfields; /* number of fields */
|
u_char db_nfields; /* number of fields */
|
||||||
u_char *db_buff; /* record-buffer to save malloc()'s */
|
u_char *db_buff; /* record-buffer to save malloc()'s */
|
||||||
f_descr *db_fields; /* pointer to an array of field-
|
f_descr *db_fields; /* pointer to an array of field- descriptions */
|
||||||
* descriptions */
|
|
||||||
} dbhead;
|
} dbhead;
|
||||||
|
|
||||||
/* structure that contains everything a user wants from a field, including
|
/* structure that contains everything a user wants from a field, including
|
||||||
|
@ -169,7 +169,7 @@ usage(void)
|
|||||||
{
|
{
|
||||||
printf("dbf2pg\n"
|
printf("dbf2pg\n"
|
||||||
"usage: dbf2pg [-u | -l] [-h hostname] [-W] [-U username]\n"
|
"usage: dbf2pg [-u | -l] [-h hostname] [-W] [-U username]\n"
|
||||||
" [-B transaction_size] [-F charset_from [-T charset_to]]\n"
|
" [-B transaction_size] [-F charset_from [-T charset_to]]\n"
|
||||||
" [-s oldname=[newname][,oldname=[newname][...]]] [-d dbase]\n"
|
" [-s oldname=[newname][,oldname=[newname][...]]] [-d dbase]\n"
|
||||||
" [-t table] [-c | -D] [-f] [-v[v]] dbf-file\n");
|
" [-t table] [-c | -D] [-f] [-v[v]] dbf-file\n");
|
||||||
}
|
}
|
||||||
@ -251,7 +251,7 @@ do_create(PGconn *conn, char *table, dbhead * dbh)
|
|||||||
printf("Building CREATE-clause\n");
|
printf("Building CREATE-clause\n");
|
||||||
|
|
||||||
if (!(query = (char *) malloc(
|
if (!(query = (char *) malloc(
|
||||||
(dbh->db_nfields * 40) + 29 + strlen(table))))
|
(dbh->db_nfields * 40) + 29 + strlen(table))))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Memory allocation error in function do_create\n");
|
fprintf(stderr, "Memory allocation error in function do_create\n");
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
@ -359,9 +359,8 @@ do_inserts(PGconn *conn, char *table, dbhead * dbh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* make sure we can build the COPY query, note that we don't need to
|
* make sure we can build the COPY query, note that we don't need to just
|
||||||
* just add this value, since the COPY query is a separate query (see
|
* add this value, since the COPY query is a separate query (see below)
|
||||||
* below)
|
|
||||||
*/
|
*/
|
||||||
if (h < 17 + strlen(table))
|
if (h < 17 + strlen(table))
|
||||||
h = 17 + strlen(table);
|
h = 17 + strlen(table);
|
||||||
@ -370,7 +369,7 @@ do_inserts(PGconn *conn, char *table, dbhead * dbh)
|
|||||||
{
|
{
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Memory allocation error in function do_inserts (query)\n");
|
"Memory allocation error in function do_inserts (query)\n");
|
||||||
close(dbh->db_fd);
|
close(dbh->db_fd);
|
||||||
free(dbh);
|
free(dbh);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -386,12 +385,10 @@ do_inserts(PGconn *conn, char *table, dbhead * dbh)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end == 0) /* "end" is a user option, if not
|
if (end == 0) /* "end" is a user option, if not specified, */
|
||||||
* specified, */
|
|
||||||
end = dbh->db_records; /* then all records are processed. */
|
end = dbh->db_records; /* then all records are processed. */
|
||||||
|
|
||||||
if (t_block == 0) /* user not specified transaction block
|
if (t_block == 0) /* user not specified transaction block size */
|
||||||
* size */
|
|
||||||
t_block = end - begin; /* then we set it to be the full data */
|
t_block = end - begin; /* then we set it to be the full data */
|
||||||
|
|
||||||
for (i = begin; i < end; i++)
|
for (i = begin; i < end; i++)
|
||||||
@ -426,9 +423,8 @@ do_inserts(PGconn *conn, char *table, dbhead * dbh)
|
|||||||
j = 0; /* counter for fields in the output */
|
j = 0; /* counter for fields in the output */
|
||||||
for (h = 0; h < dbh->db_nfields; h++)
|
for (h = 0; h < dbh->db_nfields; h++)
|
||||||
{
|
{
|
||||||
if (!strlen(fields[h].db_name)) /* When the new fieldname
|
if (!strlen(fields[h].db_name)) /* When the new fieldname is
|
||||||
* is empty, the field is
|
* empty, the field is skipped */
|
||||||
* skipped */
|
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
j++;
|
j++;
|
||||||
@ -639,8 +635,8 @@ main(int argc, char **argv)
|
|||||||
usage();
|
usage();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: Ivan thinks this is bad: printf("unknown
|
* FIXME: Ivan thinks this is bad: printf("unknown argument:
|
||||||
* argument: %s\n", argv[0]);
|
* %s\n", argv[0]);
|
||||||
*/
|
*/
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
|
@ -60,10 +60,9 @@
|
|||||||
|
|
||||||
typedef struct remoteConn
|
typedef struct remoteConn
|
||||||
{
|
{
|
||||||
PGconn *conn; /* Hold the remote connection */
|
PGconn *conn; /* Hold the remote connection */
|
||||||
int autoXactCursors; /* Indicates the number of open cursors,
|
int autoXactCursors;/* Indicates the number of open cursors,
|
||||||
* non-zero means we opened the xact
|
* non-zero means we opened the xact ourselves */
|
||||||
* ourselves */
|
|
||||||
} remoteConn;
|
} remoteConn;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -71,7 +70,7 @@ typedef struct remoteConn
|
|||||||
*/
|
*/
|
||||||
static remoteConn *getConnectionByName(const char *name);
|
static remoteConn *getConnectionByName(const char *name);
|
||||||
static HTAB *createConnHash(void);
|
static HTAB *createConnHash(void);
|
||||||
static void createNewConnection(const char *name, remoteConn *rconn);
|
static void createNewConnection(const char *name, remoteConn * rconn);
|
||||||
static void deleteConnection(const char *name);
|
static void deleteConnection(const char *name);
|
||||||
static char **get_pkey_attnames(Oid relid, int16 *numatts);
|
static char **get_pkey_attnames(Oid relid, int16 *numatts);
|
||||||
static char *get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals);
|
static char *get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals);
|
||||||
@ -224,9 +223,9 @@ dblink_connect(PG_FUNCTION_ARGS)
|
|||||||
pfree(rconn);
|
pfree(rconn);
|
||||||
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
|
(errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
|
||||||
errmsg("could not establish connection"),
|
errmsg("could not establish connection"),
|
||||||
errdetail("%s", msg)));
|
errdetail("%s", msg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connname)
|
if (connname)
|
||||||
@ -514,8 +513,7 @@ dblink_fetch(PG_FUNCTION_ARGS)
|
|||||||
funcctx = SRF_FIRSTCALL_INIT();
|
funcctx = SRF_FIRSTCALL_INIT();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* switch to memory context appropriate for multiple function
|
* switch to memory context appropriate for multiple function calls
|
||||||
* calls
|
|
||||||
*/
|
*/
|
||||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||||
|
|
||||||
@ -664,8 +662,7 @@ dblink_record(PG_FUNCTION_ARGS)
|
|||||||
funcctx = SRF_FIRSTCALL_INIT();
|
funcctx = SRF_FIRSTCALL_INIT();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* switch to memory context appropriate for multiple function
|
* switch to memory context appropriate for multiple function calls
|
||||||
* calls
|
|
||||||
*/
|
*/
|
||||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||||
|
|
||||||
@ -730,8 +727,8 @@ dblink_record(PG_FUNCTION_ARGS)
|
|||||||
TEXTOID, -1, 0);
|
TEXTOID, -1, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* and save a copy of the command status string to return as
|
* and save a copy of the command status string to return as our
|
||||||
* our result tuple
|
* result tuple
|
||||||
*/
|
*/
|
||||||
sql_cmd_status = PQcmdStatus(res);
|
sql_cmd_status = PQcmdStatus(res);
|
||||||
funcctx->max_calls = 1;
|
funcctx->max_calls = 1;
|
||||||
@ -766,8 +763,8 @@ dblink_record(PG_FUNCTION_ARGS)
|
|||||||
/* failed to determine actual type of RECORD */
|
/* failed to determine actual type of RECORD */
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("function returning record called in context "
|
errmsg("function returning record called in context "
|
||||||
"that cannot accept type record")));
|
"that cannot accept type record")));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* result type isn't composite */
|
/* result type isn't composite */
|
||||||
@ -935,8 +932,8 @@ dblink_exec(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
|
(errcode(ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED),
|
||||||
errmsg("statement returning results not allowed")));
|
errmsg("statement returning results not allowed")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if needed, close the connection to the database and cleanup */
|
/* if needed, close the connection to the database and cleanup */
|
||||||
@ -975,8 +972,7 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
|
|||||||
funcctx = SRF_FIRSTCALL_INIT();
|
funcctx = SRF_FIRSTCALL_INIT();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* switch to memory context appropriate for multiple function
|
* switch to memory context appropriate for multiple function calls
|
||||||
* calls
|
|
||||||
*/
|
*/
|
||||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||||
|
|
||||||
@ -989,8 +985,7 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
|
|||||||
GET_STR(PG_GETARG_TEXT_P(0)))));
|
GET_STR(PG_GETARG_TEXT_P(0)))));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* need a tuple descriptor representing one INT and one TEXT
|
* need a tuple descriptor representing one INT and one TEXT column
|
||||||
* column
|
|
||||||
*/
|
*/
|
||||||
tupdesc = CreateTemplateTupleDesc(2, false);
|
tupdesc = CreateTemplateTupleDesc(2, false);
|
||||||
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "position",
|
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "position",
|
||||||
@ -999,8 +994,8 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
|
|||||||
TEXTOID, -1, 0);
|
TEXTOID, -1, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate attribute metadata needed later to produce tuples from
|
* Generate attribute metadata needed later to produce tuples from raw
|
||||||
* raw C strings
|
* C strings
|
||||||
*/
|
*/
|
||||||
attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
||||||
funcctx->attinmeta = attinmeta;
|
funcctx->attinmeta = attinmeta;
|
||||||
@ -1145,8 +1140,8 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
|
|||||||
tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(4);
|
tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(4);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Source array is made up of key values that will be used to locate
|
* Source array is made up of key values that will be used to locate the
|
||||||
* the tuple of interest from the local system.
|
* tuple of interest from the local system.
|
||||||
*/
|
*/
|
||||||
src_ndim = ARR_NDIM(src_pkattvals_arry);
|
src_ndim = ARR_NDIM(src_pkattvals_arry);
|
||||||
src_dim = ARR_DIMS(src_pkattvals_arry);
|
src_dim = ARR_DIMS(src_pkattvals_arry);
|
||||||
@ -1158,8 +1153,8 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
|
|||||||
if (src_nitems != pknumatts)
|
if (src_nitems != pknumatts)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||||
errmsg("source key array length must match number of key " \
|
errmsg("source key array length must match number of key " \
|
||||||
"attributes")));
|
"attributes")));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get array of pointers to c-strings from the input source array
|
* get array of pointers to c-strings from the input source array
|
||||||
@ -1178,8 +1173,8 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Target array is made up of key values that will be used to build
|
* Target array is made up of key values that will be used to build the
|
||||||
* the SQL string for use on the remote system.
|
* SQL string for use on the remote system.
|
||||||
*/
|
*/
|
||||||
tgt_ndim = ARR_NDIM(tgt_pkattvals_arry);
|
tgt_ndim = ARR_NDIM(tgt_pkattvals_arry);
|
||||||
tgt_dim = ARR_DIMS(tgt_pkattvals_arry);
|
tgt_dim = ARR_DIMS(tgt_pkattvals_arry);
|
||||||
@ -1191,8 +1186,8 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
|
|||||||
if (tgt_nitems != pknumatts)
|
if (tgt_nitems != pknumatts)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||||
errmsg("target key array length must match number of key " \
|
errmsg("target key array length must match number of key " \
|
||||||
"attributes")));
|
"attributes")));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get array of pointers to c-strings from the input target array
|
* get array of pointers to c-strings from the input target array
|
||||||
@ -1291,8 +1286,8 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
|
|||||||
tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3);
|
tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Target array is made up of key values that will be used to build
|
* Target array is made up of key values that will be used to build the
|
||||||
* the SQL string for use on the remote system.
|
* SQL string for use on the remote system.
|
||||||
*/
|
*/
|
||||||
tgt_ndim = ARR_NDIM(tgt_pkattvals_arry);
|
tgt_ndim = ARR_NDIM(tgt_pkattvals_arry);
|
||||||
tgt_dim = ARR_DIMS(tgt_pkattvals_arry);
|
tgt_dim = ARR_DIMS(tgt_pkattvals_arry);
|
||||||
@ -1304,8 +1299,8 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
|
|||||||
if (tgt_nitems != pknumatts)
|
if (tgt_nitems != pknumatts)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||||
errmsg("target key array length must match number of key " \
|
errmsg("target key array length must match number of key " \
|
||||||
"attributes")));
|
"attributes")));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get array of pointers to c-strings from the input target array
|
* get array of pointers to c-strings from the input target array
|
||||||
@ -1414,8 +1409,8 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
|
|||||||
tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(4);
|
tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(4);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Source array is made up of key values that will be used to locate
|
* Source array is made up of key values that will be used to locate the
|
||||||
* the tuple of interest from the local system.
|
* tuple of interest from the local system.
|
||||||
*/
|
*/
|
||||||
src_ndim = ARR_NDIM(src_pkattvals_arry);
|
src_ndim = ARR_NDIM(src_pkattvals_arry);
|
||||||
src_dim = ARR_DIMS(src_pkattvals_arry);
|
src_dim = ARR_DIMS(src_pkattvals_arry);
|
||||||
@ -1427,8 +1422,8 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
|
|||||||
if (src_nitems != pknumatts)
|
if (src_nitems != pknumatts)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||||
errmsg("source key array length must match number of key " \
|
errmsg("source key array length must match number of key " \
|
||||||
"attributes")));
|
"attributes")));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get array of pointers to c-strings from the input source array
|
* get array of pointers to c-strings from the input source array
|
||||||
@ -1447,8 +1442,8 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Target array is made up of key values that will be used to build
|
* Target array is made up of key values that will be used to build the
|
||||||
* the SQL string for use on the remote system.
|
* SQL string for use on the remote system.
|
||||||
*/
|
*/
|
||||||
tgt_ndim = ARR_NDIM(tgt_pkattvals_arry);
|
tgt_ndim = ARR_NDIM(tgt_pkattvals_arry);
|
||||||
tgt_dim = ARR_DIMS(tgt_pkattvals_arry);
|
tgt_dim = ARR_DIMS(tgt_pkattvals_arry);
|
||||||
@ -1460,8 +1455,8 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
|
|||||||
if (tgt_nitems != pknumatts)
|
if (tgt_nitems != pknumatts)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||||
errmsg("target key array length must match number of key " \
|
errmsg("target key array length must match number of key " \
|
||||||
"attributes")));
|
"attributes")));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get array of pointers to c-strings from the input target array
|
* get array of pointers to c-strings from the input target array
|
||||||
@ -1610,7 +1605,7 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
|
|||||||
appendStringInfo(str, ",");
|
appendStringInfo(str, ",");
|
||||||
|
|
||||||
appendStringInfo(str, "%s",
|
appendStringInfo(str, "%s",
|
||||||
quote_ident_cstr(NameStr(tupdesc->attrs[i]->attname)));
|
quote_ident_cstr(NameStr(tupdesc->attrs[i]->attname)));
|
||||||
needComma = true;
|
needComma = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1688,7 +1683,7 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
|
|||||||
appendStringInfo(str, " AND ");
|
appendStringInfo(str, " AND ");
|
||||||
|
|
||||||
appendStringInfo(str, "%s",
|
appendStringInfo(str, "%s",
|
||||||
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
|
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
|
||||||
|
|
||||||
if (tgt_pkattvals != NULL)
|
if (tgt_pkattvals != NULL)
|
||||||
val = pstrdup(tgt_pkattvals[i]);
|
val = pstrdup(tgt_pkattvals[i]);
|
||||||
@ -1756,7 +1751,7 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
|
|||||||
appendStringInfo(str, ", ");
|
appendStringInfo(str, ", ");
|
||||||
|
|
||||||
appendStringInfo(str, "%s = ",
|
appendStringInfo(str, "%s = ",
|
||||||
quote_ident_cstr(NameStr(tupdesc->attrs[i]->attname)));
|
quote_ident_cstr(NameStr(tupdesc->attrs[i]->attname)));
|
||||||
|
|
||||||
if (tgt_pkattvals != NULL)
|
if (tgt_pkattvals != NULL)
|
||||||
key = get_attnum_pk_pos(pkattnums, pknumatts, i + 1);
|
key = get_attnum_pk_pos(pkattnums, pknumatts, i + 1);
|
||||||
@ -1788,7 +1783,7 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
|
|||||||
appendStringInfo(str, " AND ");
|
appendStringInfo(str, " AND ");
|
||||||
|
|
||||||
appendStringInfo(str, "%s",
|
appendStringInfo(str, "%s",
|
||||||
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
|
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
|
||||||
|
|
||||||
if (tgt_pkattvals != NULL)
|
if (tgt_pkattvals != NULL)
|
||||||
val = pstrdup(tgt_pkattvals[i]);
|
val = pstrdup(tgt_pkattvals[i]);
|
||||||
@ -1894,8 +1889,8 @@ get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **
|
|||||||
elog(ERROR, "SPI connect failure - returned %d", ret);
|
elog(ERROR, "SPI connect failure - returned %d", ret);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build sql statement to look up tuple of interest Use src_pkattvals
|
* Build sql statement to look up tuple of interest Use src_pkattvals as
|
||||||
* as the criteria.
|
* the criteria.
|
||||||
*/
|
*/
|
||||||
appendStringInfo(str, "SELECT * FROM %s WHERE ", relname);
|
appendStringInfo(str, "SELECT * FROM %s WHERE ", relname);
|
||||||
|
|
||||||
@ -1907,7 +1902,7 @@ get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **
|
|||||||
appendStringInfo(str, " AND ");
|
appendStringInfo(str, " AND ");
|
||||||
|
|
||||||
appendStringInfo(str, "%s",
|
appendStringInfo(str, "%s",
|
||||||
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
|
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
|
||||||
|
|
||||||
val = pstrdup(src_pkattvals[i]);
|
val = pstrdup(src_pkattvals[i]);
|
||||||
if (val != NULL)
|
if (val != NULL)
|
||||||
@ -2045,7 +2040,7 @@ createConnHash(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
createNewConnection(const char *name, remoteConn *rconn)
|
createNewConnection(const char *name, remoteConn * rconn)
|
||||||
{
|
{
|
||||||
remoteConnHashEnt *hentry;
|
remoteConnHashEnt *hentry;
|
||||||
bool found;
|
bool found;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* pending.c
|
* pending.c
|
||||||
* $Id: pending.c,v 1.22 2005/10/02 23:50:05 tgl Exp $
|
* $Id: pending.c,v 1.23 2005/10/15 02:49:04 momjian Exp $
|
||||||
* $PostgreSQL: pgsql/contrib/dbmirror/pending.c,v 1.22 2005/10/02 23:50:05 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/dbmirror/pending.c,v 1.23 2005/10/15 02:49:04 momjian Exp $
|
||||||
*
|
*
|
||||||
* This file contains a trigger for Postgresql-7.x to record changes to tables
|
* This file contains a trigger for Postgresql-7.x to record changes to tables
|
||||||
* to a pending table for mirroring.
|
* to a pending table for mirroring.
|
||||||
@ -115,7 +115,7 @@ recordchange(PG_FUNCTION_ARGS)
|
|||||||
if (SPI_connect() < 0)
|
if (SPI_connect() < 0)
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errcode(ERRCODE_CONNECTION_FAILURE),
|
ereport(ERROR, (errcode(ERRCODE_CONNECTION_FAILURE),
|
||||||
errmsg("dbmirror:recordchange could not connect to SPI")));
|
errmsg("dbmirror:recordchange could not connect to SPI")));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
trigdata = (TriggerData *) fcinfo->context;
|
trigdata = (TriggerData *) fcinfo->context;
|
||||||
@ -155,7 +155,7 @@ recordchange(PG_FUNCTION_ARGS)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
ereport(ERROR, (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||||
errmsg("dbmirror:recordchange Unknown operation")));
|
errmsg("dbmirror:recordchange Unknown operation")));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ storePending(char *cpTableName, HeapTuple tBeforeTuple,
|
|||||||
vpPlan = SPI_prepare(cpQueryBase, 3, taPlanArgTypes);
|
vpPlan = SPI_prepare(cpQueryBase, 3, taPlanArgTypes);
|
||||||
if (vpPlan == NULL)
|
if (vpPlan == NULL)
|
||||||
ereport(ERROR, (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
ereport(ERROR, (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||||
errmsg("dbmirror:storePending error creating plan")));
|
errmsg("dbmirror:storePending error creating plan")));
|
||||||
|
|
||||||
|
|
||||||
saPlanData[0] = PointerGetDatum(cpTableName);
|
saPlanData[0] = PointerGetDatum(cpTableName);
|
||||||
@ -662,7 +662,7 @@ saveSequenceUpdate(Oid relid, int64 nextValue, bool iscalled)
|
|||||||
if (SPI_connect() < 0)
|
if (SPI_connect() < 0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
|
(errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
|
||||||
errmsg("dbmirror:savesequenceupdate could not connect to SPI")));
|
errmsg("dbmirror:savesequenceupdate could not connect to SPI")));
|
||||||
|
|
||||||
insertPlan = SPI_prepare(insertQuery, 2, insertArgTypes);
|
insertPlan = SPI_prepare(insertQuery, 2, insertArgTypes);
|
||||||
insertDataPlan = SPI_prepare(insertDataQuery, 1, insertDataArgTypes);
|
insertDataPlan = SPI_prepare(insertDataQuery, 1, insertDataArgTypes);
|
||||||
|
@ -67,7 +67,7 @@ geo_distance(Point *pt1, Point *pt2)
|
|||||||
longdiff = TWO_PI - longdiff;
|
longdiff = TWO_PI - longdiff;
|
||||||
|
|
||||||
sino = sqrt(sin(fabs(lat1 - lat2) / 2.) * sin(fabs(lat1 - lat2) / 2.) +
|
sino = sqrt(sin(fabs(lat1 - lat2) / 2.) * sin(fabs(lat1 - lat2) / 2.) +
|
||||||
cos(lat1) * cos(lat2) * sin(longdiff / 2.) * sin(longdiff / 2.));
|
cos(lat1) * cos(lat2) * sin(longdiff / 2.) * sin(longdiff / 2.));
|
||||||
if (sino > 1.)
|
if (sino > 1.)
|
||||||
sino = 1.;
|
sino = 1.;
|
||||||
*resultp = 2. * EARTH_RADIUS * asin(sino);
|
*resultp = 2. * EARTH_RADIUS * asin(sino);
|
||||||
|
@ -339,8 +339,8 @@ fti(PG_FUNCTION_ARGS)
|
|||||||
ret = SPI_execp(*(plan->splan), values, NULL, 0);
|
ret = SPI_execp(*(plan->splan), values, NULL, 0);
|
||||||
if (ret != SPI_OK_INSERT)
|
if (ret != SPI_OK_INSERT)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||||
errmsg("error executing insert")));
|
errmsg("error executing insert")));
|
||||||
}
|
}
|
||||||
pfree(buff);
|
pfree(buff);
|
||||||
pfree(data);
|
pfree(data);
|
||||||
@ -367,9 +367,8 @@ breakup(char *string, char *substring)
|
|||||||
while (cur_pos > string) /* don't read before start of 'string' */
|
while (cur_pos > string) /* don't read before start of 'string' */
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* skip pieces at the end of a string that are not alfa-numeric
|
* skip pieces at the end of a string that are not alfa-numeric (ie.
|
||||||
* (ie. 'string$%^&', last_start first points to '&', and after
|
* 'string$%^&', last_start first points to '&', and after this to 'g'
|
||||||
* this to 'g'
|
|
||||||
*/
|
*/
|
||||||
if (!isalnum((unsigned char) *last_start))
|
if (!isalnum((unsigned char) *last_start))
|
||||||
{
|
{
|
||||||
@ -379,8 +378,7 @@ breakup(char *string, char *substring)
|
|||||||
cur_pos = last_start;
|
cur_pos = last_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_pos--; /* substrings are at minimum 2 characters
|
cur_pos--; /* substrings are at minimum 2 characters long */
|
||||||
* long */
|
|
||||||
|
|
||||||
if (isalnum((unsigned char) *cur_pos))
|
if (isalnum((unsigned char) *cur_pos))
|
||||||
{
|
{
|
||||||
|
@ -48,8 +48,8 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Revision: 1.5 $
|
* $Revision: 1.6 $
|
||||||
* $Id: dmetaphone.c,v 1.5 2005/09/30 22:38:44 momjian Exp $
|
* $Id: dmetaphone.c,v 1.6 2005/10/15 02:49:05 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -154,10 +154,10 @@ dmetaphone(PG_FUNCTION_ARGS)
|
|||||||
alen = VARSIZE(arg) - VARHDRSZ;
|
alen = VARSIZE(arg) - VARHDRSZ;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Postgres' string values might not have trailing nuls. The VARSIZE
|
* Postgres' string values might not have trailing nuls. The VARSIZE will
|
||||||
* will not include the nul in any case so we copy things out and add
|
* not include the nul in any case so we copy things out and add a
|
||||||
* a trailing nul. When we copy back we ignore the nul (and we don't
|
* trailing nul. When we copy back we ignore the nul (and we don't make
|
||||||
* make space for it).
|
* space for it).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
aptr = palloc(alen + 1);
|
aptr = palloc(alen + 1);
|
||||||
@ -236,7 +236,6 @@ dmetaphone_alt(PG_FUNCTION_ARGS)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define META_FREE(x) /* pfree((x)) */
|
#define META_FREE(x) /* pfree((x)) */
|
||||||
|
|
||||||
#else /* not defined DMETAPHONE_MAIN */
|
#else /* not defined DMETAPHONE_MAIN */
|
||||||
|
|
||||||
/* use the standard malloc library when not running in PostgreSQL */
|
/* use the standard malloc library when not running in PostgreSQL */
|
||||||
@ -512,8 +511,8 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
&& StringAt(original, (current - 1), 3, "ACH", "")
|
&& StringAt(original, (current - 1), 3, "ACH", "")
|
||||||
&& ((GetAt(original, current + 2) != 'I')
|
&& ((GetAt(original, current + 2) != 'I')
|
||||||
&& ((GetAt(original, current + 2) != 'E')
|
&& ((GetAt(original, current + 2) != 'E')
|
||||||
|| StringAt(original, (current - 2), 6, "BACHER",
|
|| StringAt(original, (current - 2), 6, "BACHER",
|
||||||
"MACHER", ""))))
|
"MACHER", ""))))
|
||||||
{
|
{
|
||||||
MetaphAdd(primary, "K");
|
MetaphAdd(primary, "K");
|
||||||
MetaphAdd(secondary, "K");
|
MetaphAdd(secondary, "K");
|
||||||
@ -582,9 +581,9 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
/*
|
/*
|
||||||
* e.g., 'wachtler', 'wechsler', but not 'tichner'
|
* e.g., 'wachtler', 'wechsler', but not 'tichner'
|
||||||
*/
|
*/
|
||||||
&& StringAt(original, (current + 2), 1, "L", "R",
|
&& StringAt(original, (current + 2), 1, "L", "R",
|
||||||
"N", "M", "B", "H", "F", "V", "W",
|
"N", "M", "B", "H", "F", "V", "W",
|
||||||
" ", "")))
|
" ", "")))
|
||||||
{
|
{
|
||||||
MetaphAdd(primary, "K");
|
MetaphAdd(primary, "K");
|
||||||
MetaphAdd(secondary, "K");
|
MetaphAdd(secondary, "K");
|
||||||
@ -639,14 +638,14 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
{
|
{
|
||||||
/* 'bellocchio' but not 'bacchus' */
|
/* 'bellocchio' but not 'bacchus' */
|
||||||
if (StringAt(original, (current + 2), 1, "I", "E", "H", "")
|
if (StringAt(original, (current + 2), 1, "I", "E", "H", "")
|
||||||
&& !StringAt(original, (current + 2), 2, "HU", ""))
|
&& !StringAt(original, (current + 2), 2, "HU", ""))
|
||||||
{
|
{
|
||||||
/* 'accident', 'accede' 'succeed' */
|
/* 'accident', 'accede' 'succeed' */
|
||||||
if (
|
if (
|
||||||
((current == 1)
|
((current == 1)
|
||||||
&& (GetAt(original, current - 1) == 'A'))
|
&& (GetAt(original, current - 1) == 'A'))
|
||||||
|| StringAt(original, (current - 1), 5, "UCCEE",
|
|| StringAt(original, (current - 1), 5, "UCCEE",
|
||||||
"UCCES", ""))
|
"UCCES", ""))
|
||||||
{
|
{
|
||||||
MetaphAdd(primary, "KS");
|
MetaphAdd(primary, "KS");
|
||||||
MetaphAdd(secondary, "KS");
|
MetaphAdd(secondary, "KS");
|
||||||
@ -787,8 +786,8 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parker's rule (with some further refinements) -
|
* Parker's rule (with some further refinements) - e.g.,
|
||||||
* e.g., 'hugh'
|
* 'hugh'
|
||||||
*/
|
*/
|
||||||
if (
|
if (
|
||||||
((current > 1)
|
((current > 1)
|
||||||
@ -873,9 +872,9 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
/* -ges-,-gep-,-gel-, -gie- at beginning */
|
/* -ges-,-gep-,-gel-, -gie- at beginning */
|
||||||
if ((current == 0)
|
if ((current == 0)
|
||||||
&& ((GetAt(original, current + 1) == 'Y')
|
&& ((GetAt(original, current + 1) == 'Y')
|
||||||
|| StringAt(original, (current + 1), 2, "ES", "EP",
|
|| StringAt(original, (current + 1), 2, "ES", "EP",
|
||||||
"EB", "EL", "EY", "IB", "IL", "IN", "IE",
|
"EB", "EL", "EY", "IB", "IL", "IN", "IE",
|
||||||
"EI", "ER", "")))
|
"EI", "ER", "")))
|
||||||
{
|
{
|
||||||
MetaphAdd(primary, "K");
|
MetaphAdd(primary, "K");
|
||||||
MetaphAdd(secondary, "J");
|
MetaphAdd(secondary, "J");
|
||||||
@ -1002,7 +1001,7 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!StringAt(original, (current + 1), 1, "L", "T",
|
if (!StringAt(original, (current + 1), 1, "L", "T",
|
||||||
"K", "S", "N", "M", "B", "Z", "")
|
"K", "S", "N", "M", "B", "Z", "")
|
||||||
&& !StringAt(original, (current - 1), 1,
|
&& !StringAt(original, (current - 1), 1,
|
||||||
"S", "K", "L", ""))
|
"S", "K", "L", ""))
|
||||||
{
|
{
|
||||||
@ -1035,10 +1034,10 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
if (((current == (length - 3))
|
if (((current == (length - 3))
|
||||||
&& StringAt(original, (current - 1), 4, "ILLO",
|
&& StringAt(original, (current - 1), 4, "ILLO",
|
||||||
"ILLA", "ALLE", ""))
|
"ILLA", "ALLE", ""))
|
||||||
|| ((StringAt(original, (last - 1), 2, "AS", "OS", "")
|
|| ((StringAt(original, (last - 1), 2, "AS", "OS", "")
|
||||||
|| StringAt(original, last, 1, "A", "O", ""))
|
|| StringAt(original, last, 1, "A", "O", ""))
|
||||||
&& StringAt(original, (current - 1), 4,
|
&& StringAt(original, (current - 1), 4,
|
||||||
"ALLE", "")))
|
"ALLE", "")))
|
||||||
{
|
{
|
||||||
MetaphAdd(primary, "L");
|
MetaphAdd(primary, "L");
|
||||||
MetaphAdd(secondary, "");
|
MetaphAdd(secondary, "");
|
||||||
@ -1056,7 +1055,7 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
case 'M':
|
case 'M':
|
||||||
if ((StringAt(original, (current - 1), 3, "UMB", "")
|
if ((StringAt(original, (current - 1), 3, "UMB", "")
|
||||||
&& (((current + 1) == last)
|
&& (((current + 1) == last)
|
||||||
|| StringAt(original, (current + 2), 2, "ER", "")))
|
|| StringAt(original, (current + 2), 2, "ER", "")))
|
||||||
/* 'dumb','thumb' */
|
/* 'dumb','thumb' */
|
||||||
|| (GetAt(original, current + 1) == 'M'))
|
|| (GetAt(original, current + 1) == 'M'))
|
||||||
current += 2;
|
current += 2;
|
||||||
@ -1113,7 +1112,7 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
if ((current == last)
|
if ((current == last)
|
||||||
&& !SlavoGermanic(original)
|
&& !SlavoGermanic(original)
|
||||||
&& StringAt(original, (current - 2), 2, "IE", "")
|
&& StringAt(original, (current - 2), 2, "IE", "")
|
||||||
&& !StringAt(original, (current - 4), 2, "ME", "MA", ""))
|
&& !StringAt(original, (current - 4), 2, "ME", "MA", ""))
|
||||||
{
|
{
|
||||||
MetaphAdd(primary, "");
|
MetaphAdd(primary, "");
|
||||||
MetaphAdd(secondary, "R");
|
MetaphAdd(secondary, "R");
|
||||||
@ -1152,8 +1151,8 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
{
|
{
|
||||||
/* germanic */
|
/* germanic */
|
||||||
if (StringAt
|
if (StringAt
|
||||||
(original, (current + 1), 4, "HEIM", "HOEK", "HOLM",
|
(original, (current + 1), 4, "HEIM", "HOEK", "HOLM",
|
||||||
"HOLZ", ""))
|
"HOLZ", ""))
|
||||||
{
|
{
|
||||||
MetaphAdd(primary, "S");
|
MetaphAdd(primary, "S");
|
||||||
MetaphAdd(secondary, "S");
|
MetaphAdd(secondary, "S");
|
||||||
@ -1187,8 +1186,8 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* german & anglicisations, e.g. 'smith' match 'schmidt',
|
* german & anglicisations, e.g. 'smith' match 'schmidt',
|
||||||
* 'snider' match 'schneider' also, -sz- in slavic
|
* 'snider' match 'schneider' also, -sz- in slavic language
|
||||||
* language although in hungarian it is pronounced 's'
|
* although in hungarian it is pronounced 's'
|
||||||
*/
|
*/
|
||||||
if (((current == 0)
|
if (((current == 0)
|
||||||
&& StringAt(original, (current + 1), 1,
|
&& StringAt(original, (current + 1), 1,
|
||||||
@ -1264,7 +1263,7 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
|
|
||||||
/* french e.g. 'resnais', 'artois' */
|
/* french e.g. 'resnais', 'artois' */
|
||||||
if ((current == last)
|
if ((current == last)
|
||||||
&& StringAt(original, (current - 2), 2, "AI", "OI", ""))
|
&& StringAt(original, (current - 2), 2, "AI", "OI", ""))
|
||||||
{
|
{
|
||||||
MetaphAdd(primary, "");
|
MetaphAdd(primary, "");
|
||||||
MetaphAdd(secondary, "S");
|
MetaphAdd(secondary, "S");
|
||||||
@ -1365,8 +1364,8 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
|
|
||||||
/* Arnow should match Arnoff */
|
/* Arnow should match Arnoff */
|
||||||
if (((current == last) && IsVowel(original, current - 1))
|
if (((current == last) && IsVowel(original, current - 1))
|
||||||
|| StringAt(original, (current - 1), 5, "EWSKI", "EWSKY",
|
|| StringAt(original, (current - 1), 5, "EWSKI", "EWSKY",
|
||||||
"OWSKI", "OWSKY", "")
|
"OWSKI", "OWSKY", "")
|
||||||
|| StringAt(original, 0, 3, "SCH", ""))
|
|| StringAt(original, 0, 3, "SCH", ""))
|
||||||
{
|
{
|
||||||
MetaphAdd(primary, "");
|
MetaphAdd(primary, "");
|
||||||
@ -1442,8 +1441,8 @@ DoubleMetaphone(char *str, char **codes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* printf("PRIMARY: %s\n", primary->str); printf("SECONDARY:
|
* printf("PRIMARY: %s\n", primary->str); printf("SECONDARY: %s\n",
|
||||||
* %s\n", secondary->str);
|
* secondary->str);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,10 +65,10 @@ levenshtein(PG_FUNCTION_ARGS)
|
|||||||
int j;
|
int j;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetch the arguments. str_s is referred to as the "source" cols =
|
* Fetch the arguments. str_s is referred to as the "source" cols = length
|
||||||
* length of source + 1 to allow for the initialization column str_t
|
* of source + 1 to allow for the initialization column str_t is referred
|
||||||
* is referred to as the "target", rows = length of target + 1 rows =
|
* to as the "target", rows = length of target + 1 rows = length of target
|
||||||
* length of target + 1 to allow for the initialization row
|
* + 1 to allow for the initialization row
|
||||||
*/
|
*/
|
||||||
str_s = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0))));
|
str_s = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0))));
|
||||||
str_t = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1))));
|
str_t = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1))));
|
||||||
@ -78,10 +78,9 @@ levenshtein(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Restrict the length of the strings being compared to something
|
* Restrict the length of the strings being compared to something
|
||||||
* reasonable because we will have to perform rows * cols
|
* reasonable because we will have to perform rows * cols calculations. If
|
||||||
* calculations. If longer strings need to be compared, increase
|
* longer strings need to be compared, increase MAX_LEVENSHTEIN_STRLEN to
|
||||||
* MAX_LEVENSHTEIN_STRLEN to suit (but within your tolerance for speed
|
* suit (but within your tolerance for speed and memory usage).
|
||||||
* and memory usage).
|
|
||||||
*/
|
*/
|
||||||
if ((cols > MAX_LEVENSHTEIN_STRLEN + 1) || (rows > MAX_LEVENSHTEIN_STRLEN + 1))
|
if ((cols > MAX_LEVENSHTEIN_STRLEN + 1) || (rows > MAX_LEVENSHTEIN_STRLEN + 1))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -90,9 +89,9 @@ levenshtein(PG_FUNCTION_ARGS)
|
|||||||
MAX_LEVENSHTEIN_STRLEN)));
|
MAX_LEVENSHTEIN_STRLEN)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If either rows or cols is 0, the answer is the other value. This
|
* If either rows or cols is 0, the answer is the other value. This makes
|
||||||
* makes sense since it would take that many insertions the build a
|
* sense since it would take that many insertions the build a matching
|
||||||
* matching string
|
* string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (cols == 0)
|
if (cols == 0)
|
||||||
@ -102,9 +101,8 @@ levenshtein(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_INT32(cols);
|
PG_RETURN_INT32(cols);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate two vectors of integers. One will be used for the "upper"
|
* Allocate two vectors of integers. One will be used for the "upper" row,
|
||||||
* row, the other for the "lower" row. Initialize the "upper" row to
|
* the other for the "lower" row. Initialize the "upper" row to 0..cols
|
||||||
* 0..cols
|
|
||||||
*/
|
*/
|
||||||
u_cells = palloc(sizeof(int) * cols);
|
u_cells = palloc(sizeof(int) * cols);
|
||||||
for (i = 0; i < cols; i++)
|
for (i = 0; i < cols; i++)
|
||||||
@ -119,14 +117,13 @@ levenshtein(PG_FUNCTION_ARGS)
|
|||||||
str_s0 = str_s;
|
str_s0 = str_s;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loop through the rows, starting at row 1. Row 0 is used for the
|
* Loop through the rows, starting at row 1. Row 0 is used for the initial
|
||||||
* initial "upper" row.
|
* "upper" row.
|
||||||
*/
|
*/
|
||||||
for (j = 1; j < rows; j++)
|
for (j = 1; j < rows; j++)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We'll always start with col 1, and initialize lower row col 0
|
* We'll always start with col 1, and initialize lower row col 0 to j
|
||||||
* to j
|
|
||||||
*/
|
*/
|
||||||
l_cells[0] = j;
|
l_cells[0] = j;
|
||||||
|
|
||||||
@ -140,8 +137,7 @@ levenshtein(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* The "cost" value is 0 if the character at the current col
|
* The "cost" value is 0 if the character at the current col
|
||||||
* position in the source string, matches the character at the
|
* position in the source string, matches the character at the
|
||||||
* current row position in the target string; cost is 1
|
* current row position in the target string; cost is 1 otherwise.
|
||||||
* otherwise.
|
|
||||||
*/
|
*/
|
||||||
c = ((CHAREQ(str_s, str_t)) ? 0 : 1);
|
c = ((CHAREQ(str_s, str_t)) ? 0 : 1);
|
||||||
|
|
||||||
@ -172,8 +168,8 @@ levenshtein(PG_FUNCTION_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lower row now becomes the upper row, and the upper row gets
|
* Lower row now becomes the upper row, and the upper row gets reused
|
||||||
* reused as the new lower row.
|
* as the new lower row.
|
||||||
*/
|
*/
|
||||||
tmp = u_cells;
|
tmp = u_cells;
|
||||||
u_cells = l_cells;
|
u_cells = l_cells;
|
||||||
@ -301,8 +297,8 @@ Lookahead(char *word, int how_far)
|
|||||||
for (idx = 0; word[idx] != '\0' && idx < how_far; idx++);
|
for (idx = 0; word[idx] != '\0' && idx < how_far; idx++);
|
||||||
/* Edge forward in the string... */
|
/* Edge forward in the string... */
|
||||||
|
|
||||||
letter_ahead = word[idx]; /* idx will be either == to how_far or at
|
letter_ahead = word[idx]; /* idx will be either == to how_far or at the
|
||||||
* the end of the string */
|
* end of the string */
|
||||||
return letter_ahead;
|
return letter_ahead;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,11 +449,11 @@ _metaphone(
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* THOUGHT: It would be nice if, rather than having things
|
* THOUGHT: It would be nice if, rather than having things like...
|
||||||
* like... well, SCI. For SCI you encode the S, then have to
|
* well, SCI. For SCI you encode the S, then have to remember to skip
|
||||||
* remember to skip the C. So the phonome SCI invades both S and
|
* the C. So the phonome SCI invades both S and C. It would be
|
||||||
* C. It would be better, IMHO, to skip the C from the S part of
|
* better, IMHO, to skip the C from the S part of the encoding. Hell,
|
||||||
* the encoding. Hell, I'm trying it.
|
* I'm trying it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Ignore non-alphas */
|
/* Ignore non-alphas */
|
||||||
@ -478,9 +474,9 @@ _metaphone(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 'sh' if -CIA- or -CH, but not SCH, except SCHW. (SCHW
|
* 'sh' if -CIA- or -CH, but not SCH, except SCHW. (SCHW is
|
||||||
* is handled in S) S if -CI-, -CE- or -CY- dropped if
|
* handled in S) S if -CI-, -CE- or -CY- dropped if -SCI-,
|
||||||
* -SCI-, SCE-, -SCY- (handed in S) else K
|
* SCE-, -SCY- (handed in S) else K
|
||||||
*/
|
*/
|
||||||
case 'C':
|
case 'C':
|
||||||
if (MAKESOFT(Next_Letter))
|
if (MAKESOFT(Next_Letter))
|
||||||
@ -534,8 +530,8 @@ _metaphone(
|
|||||||
/*
|
/*
|
||||||
* F if in -GH and not B--GH, D--GH, -H--GH, -H---GH else
|
* F if in -GH and not B--GH, D--GH, -H--GH, -H---GH else
|
||||||
* dropped if -GNED, -GN, else dropped if -DGE-, -DGI- or
|
* dropped if -GNED, -GN, else dropped if -DGE-, -DGI- or
|
||||||
* -DGY- (handled in D) else J if in -GE-, -GI, -GY and
|
* -DGY- (handled in D) else J if in -GE-, -GI, -GY and not GG
|
||||||
* not GG else K
|
* else K
|
||||||
*/
|
*/
|
||||||
case 'G':
|
case 'G':
|
||||||
if (Next_Letter == 'H')
|
if (Next_Letter == 'H')
|
||||||
@ -761,14 +757,17 @@ PG_FUNCTION_INFO_V1(difference);
|
|||||||
Datum
|
Datum
|
||||||
difference(PG_FUNCTION_ARGS)
|
difference(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
char sndx1[SOUNDEX_LEN+1], sndx2[SOUNDEX_LEN+1];
|
char sndx1[SOUNDEX_LEN + 1],
|
||||||
int i, result;
|
sndx2[SOUNDEX_LEN + 1];
|
||||||
|
int i,
|
||||||
|
result;
|
||||||
|
|
||||||
_soundex(_textout(PG_GETARG_TEXT_P(0)), sndx1);
|
_soundex(_textout(PG_GETARG_TEXT_P(0)), sndx1);
|
||||||
_soundex(_textout(PG_GETARG_TEXT_P(1)), sndx2);
|
_soundex(_textout(PG_GETARG_TEXT_P(1)), sndx2);
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
for (i=0; i<SOUNDEX_LEN; i++) {
|
for (i = 0; i < SOUNDEX_LEN; i++)
|
||||||
|
{
|
||||||
if (sndx1[i] == sndx2[i])
|
if (sndx1[i] == sndx2[i])
|
||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,8 @@ typedef struct callContext
|
|||||||
#define START_NUM 8 /* initial size of arrays */
|
#define START_NUM 8 /* initial size of arrays */
|
||||||
#define PGARRAY_SIZE(n) (sizeof(PGARRAY) + (((n)-1)*sizeof(int4)))
|
#define PGARRAY_SIZE(n) (sizeof(PGARRAY) + (((n)-1)*sizeof(int4)))
|
||||||
|
|
||||||
static PGARRAY *GetPGArray(PGARRAY *p, AggState *aggstate, bool fAdd);
|
static PGARRAY *GetPGArray(PGARRAY * p, AggState *aggstate, bool fAdd);
|
||||||
static PGARRAY *ShrinkPGArray(PGARRAY *p);
|
static PGARRAY *ShrinkPGArray(PGARRAY * p);
|
||||||
|
|
||||||
Datum int_agg_state(PG_FUNCTION_ARGS);
|
Datum int_agg_state(PG_FUNCTION_ARGS);
|
||||||
Datum int_agg_final_array(PG_FUNCTION_ARGS);
|
Datum int_agg_final_array(PG_FUNCTION_ARGS);
|
||||||
@ -77,7 +77,7 @@ PG_FUNCTION_INFO_V1(int_enum);
|
|||||||
* ie the Agg node's aggcontext.
|
* ie the Agg node's aggcontext.
|
||||||
*/
|
*/
|
||||||
static PGARRAY *
|
static PGARRAY *
|
||||||
GetPGArray(PGARRAY *p, AggState *aggstate, bool fAdd)
|
GetPGArray(PGARRAY * p, AggState *aggstate, bool fAdd)
|
||||||
{
|
{
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
@ -97,7 +97,7 @@ GetPGArray(PGARRAY *p, AggState *aggstate, bool fAdd)
|
|||||||
/* Ensure array has space for another item */
|
/* Ensure array has space for another item */
|
||||||
if (p->items >= p->lower)
|
if (p->items >= p->lower)
|
||||||
{
|
{
|
||||||
PGARRAY *pn;
|
PGARRAY *pn;
|
||||||
int n = p->lower * 2;
|
int n = p->lower * 2;
|
||||||
int cbNew = PGARRAY_SIZE(n);
|
int cbNew = PGARRAY_SIZE(n);
|
||||||
|
|
||||||
@ -117,9 +117,10 @@ GetPGArray(PGARRAY *p, AggState *aggstate, bool fAdd)
|
|||||||
* memory allocation context
|
* memory allocation context
|
||||||
*/
|
*/
|
||||||
static PGARRAY *
|
static PGARRAY *
|
||||||
ShrinkPGArray(PGARRAY *p)
|
ShrinkPGArray(PGARRAY * p)
|
||||||
{
|
{
|
||||||
PGARRAY *pnew;
|
PGARRAY *pnew;
|
||||||
|
|
||||||
/* get target size */
|
/* get target size */
|
||||||
int cb = PGARRAY_SIZE(p->items);
|
int cb = PGARRAY_SIZE(p->items);
|
||||||
|
|
||||||
@ -158,11 +159,11 @@ int_agg_state(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
if (!PG_ARGISNULL(1))
|
if (!PG_ARGISNULL(1))
|
||||||
{
|
{
|
||||||
int4 value = PG_GETARG_INT32(1);
|
int4 value = PG_GETARG_INT32(1);
|
||||||
|
|
||||||
if (!p) /* internal error */
|
if (!p) /* internal error */
|
||||||
elog(ERROR, "no aggregate storage");
|
elog(ERROR, "no aggregate storage");
|
||||||
else if (p->items >= p->lower) /* internal error */
|
else if (p->items >= p->lower) /* internal error */
|
||||||
elog(ERROR, "aggregate storage too small");
|
elog(ERROR, "aggregate storage too small");
|
||||||
else
|
else
|
||||||
p->array[p->items++] = value;
|
p->array[p->items++] = value;
|
||||||
@ -212,7 +213,7 @@ int_enum(PG_FUNCTION_ARGS)
|
|||||||
if (!rsi || !IsA(rsi, ReturnSetInfo))
|
if (!rsi || !IsA(rsi, ReturnSetInfo))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("int_enum called in context that cannot accept a set")));
|
errmsg("int_enum called in context that cannot accept a set")));
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
@ -223,7 +224,7 @@ int_enum(PG_FUNCTION_ARGS)
|
|||||||
if (!fcinfo->flinfo->fn_extra)
|
if (!fcinfo->flinfo->fn_extra)
|
||||||
{
|
{
|
||||||
/* Allocate working state */
|
/* Allocate working state */
|
||||||
MemoryContext oldcontext;
|
MemoryContext oldcontext;
|
||||||
|
|
||||||
oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
|
oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
|
||||||
|
|
||||||
@ -250,7 +251,8 @@ int_enum(PG_FUNCTION_ARGS)
|
|||||||
fcinfo->flinfo->fn_extra = (void *) pc;
|
fcinfo->flinfo->fn_extra = (void *) pc;
|
||||||
MemoryContextSwitchTo(oldcontext);
|
MemoryContextSwitchTo(oldcontext);
|
||||||
}
|
}
|
||||||
else /* use existing working state */
|
else
|
||||||
|
/* use existing working state */
|
||||||
pc = (CTX *) fcinfo->flinfo->fn_extra;
|
pc = (CTX *) fcinfo->flinfo->fn_extra;
|
||||||
|
|
||||||
/* Are we done yet? */
|
/* Are we done yet? */
|
||||||
|
@ -38,8 +38,8 @@ g_int_consistent(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
if (strategy == BooleanSearchStrategy)
|
if (strategy == BooleanSearchStrategy)
|
||||||
PG_RETURN_BOOL(execconsistent((QUERYTYPE *) query,
|
PG_RETURN_BOOL(execconsistent((QUERYTYPE *) query,
|
||||||
(ArrayType *) DatumGetPointer(entry->key),
|
(ArrayType *) DatumGetPointer(entry->key),
|
||||||
ISLEAFKEY((ArrayType *) DatumGetPointer(entry->key))));
|
ISLEAFKEY((ArrayType *) DatumGetPointer(entry->key))));
|
||||||
|
|
||||||
/* XXX are we sure it's safe to scribble on the query object here? */
|
/* XXX are we sure it's safe to scribble on the query object here? */
|
||||||
/* XXX what about toasted input? */
|
/* XXX what about toasted input? */
|
||||||
@ -73,7 +73,7 @@ g_int_consistent(PG_FUNCTION_ARGS)
|
|||||||
case RTContainedByStrategyNumber:
|
case RTContainedByStrategyNumber:
|
||||||
if (GIST_LEAF(entry))
|
if (GIST_LEAF(entry))
|
||||||
retval = inner_int_contains(query,
|
retval = inner_int_contains(query,
|
||||||
(ArrayType *) DatumGetPointer(entry->key));
|
(ArrayType *) DatumGetPointer(entry->key));
|
||||||
else
|
else
|
||||||
retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
|
retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
|
||||||
query);
|
query);
|
||||||
@ -134,7 +134,7 @@ g_int_compress(PG_FUNCTION_ARGS)
|
|||||||
r->flags |= LEAFKEY;
|
r->flags |= LEAFKEY;
|
||||||
retval = palloc(sizeof(GISTENTRY));
|
retval = palloc(sizeof(GISTENTRY));
|
||||||
gistentryinit(*retval, PointerGetDatum(r),
|
gistentryinit(*retval, PointerGetDatum(r),
|
||||||
entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
|
entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
|
||||||
|
|
||||||
PG_RETURN_POINTER(retval);
|
PG_RETURN_POINTER(retval);
|
||||||
}
|
}
|
||||||
@ -175,7 +175,7 @@ g_int_compress(PG_FUNCTION_ARGS)
|
|||||||
r = resize_intArrayType(r, len);
|
r = resize_intArrayType(r, len);
|
||||||
retval = palloc(sizeof(GISTENTRY));
|
retval = palloc(sizeof(GISTENTRY));
|
||||||
gistentryinit(*retval, PointerGetDatum(r),
|
gistentryinit(*retval, PointerGetDatum(r),
|
||||||
entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
|
entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
|
||||||
PG_RETURN_POINTER(retval);
|
PG_RETURN_POINTER(retval);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -211,7 +211,7 @@ g_int_decompress(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
retval = palloc(sizeof(GISTENTRY));
|
retval = palloc(sizeof(GISTENTRY));
|
||||||
gistentryinit(*retval, PointerGetDatum(in),
|
gistentryinit(*retval, PointerGetDatum(in),
|
||||||
entry->rel, entry->page, entry->offset, VARSIZE(in), FALSE);
|
entry->rel, entry->page, entry->offset, VARSIZE(in), FALSE);
|
||||||
|
|
||||||
PG_RETURN_POINTER(retval);
|
PG_RETURN_POINTER(retval);
|
||||||
}
|
}
|
||||||
@ -233,7 +233,7 @@ g_int_decompress(PG_FUNCTION_ARGS)
|
|||||||
pfree(in);
|
pfree(in);
|
||||||
retval = palloc(sizeof(GISTENTRY));
|
retval = palloc(sizeof(GISTENTRY));
|
||||||
gistentryinit(*retval, PointerGetDatum(r),
|
gistentryinit(*retval, PointerGetDatum(r),
|
||||||
entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
|
entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
|
||||||
|
|
||||||
PG_RETURN_POINTER(retval);
|
PG_RETURN_POINTER(retval);
|
||||||
}
|
}
|
||||||
@ -378,8 +378,7 @@ g_int_picksplit(PG_FUNCTION_ARGS)
|
|||||||
pfree(inter_d);
|
pfree(inter_d);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* are these a more promising split that what we've already
|
* are these a more promising split that what we've already seen?
|
||||||
* seen?
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (size_waste > waste || firsttime)
|
if (size_waste > waste || firsttime)
|
||||||
@ -430,15 +429,15 @@ g_int_picksplit(PG_FUNCTION_ARGS)
|
|||||||
qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
|
qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now split up the regions between the two seeds. An important
|
* Now split up the regions between the two seeds. An important property
|
||||||
* property of this split algorithm is that the split vector v has the
|
* of this split algorithm is that the split vector v has the indices of
|
||||||
* indices of items to be split in order in its left and right
|
* items to be split in order in its left and right vectors. We exploit
|
||||||
* vectors. We exploit this property by doing a merge in the code
|
* this property by doing a merge in the code that actually splits the
|
||||||
* that actually splits the page.
|
* page.
|
||||||
*
|
*
|
||||||
* For efficiency, we also place the new index tuple in this loop. This
|
* For efficiency, we also place the new index tuple in this loop. This is
|
||||||
* is handled at the very end, when we have placed all the existing
|
* handled at the very end, when we have placed all the existing tuples
|
||||||
* tuples and i == maxoff + 1.
|
* and i == maxoff + 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -447,9 +446,9 @@ g_int_picksplit(PG_FUNCTION_ARGS)
|
|||||||
i = costvector[j].pos;
|
i = costvector[j].pos;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we've already decided where to place this item, just put it
|
* If we've already decided where to place this item, just put it on
|
||||||
* on the right list. Otherwise, we need to figure out which page
|
* the right list. Otherwise, we need to figure out which page needs
|
||||||
* needs the least enlargement in order to store the item.
|
* the least enlargement in order to store the item.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (i == seed_1)
|
if (i == seed_1)
|
||||||
|
@ -24,8 +24,8 @@ _int_contained(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(DatumGetBool(
|
PG_RETURN_BOOL(DatumGetBool(
|
||||||
DirectFunctionCall2(
|
DirectFunctionCall2(
|
||||||
_int_contains,
|
_int_contains,
|
||||||
PointerGetDatum(PG_GETARG_POINTER(1)),
|
PointerGetDatum(PG_GETARG_POINTER(1)),
|
||||||
PointerGetDatum(PG_GETARG_POINTER(0))
|
PointerGetDatum(PG_GETARG_POINTER(0))
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -54,8 +54,8 @@ _int_different(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_BOOL(!DatumGetBool(
|
PG_RETURN_BOOL(!DatumGetBool(
|
||||||
DirectFunctionCall2(
|
DirectFunctionCall2(
|
||||||
_int_same,
|
_int_same,
|
||||||
PointerGetDatum(PG_GETARG_POINTER(0)),
|
PointerGetDatum(PG_GETARG_POINTER(0)),
|
||||||
PointerGetDatum(PG_GETARG_POINTER(1))
|
PointerGetDatum(PG_GETARG_POINTER(1))
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -487,7 +487,7 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
|
|||||||
if (strategy == BooleanSearchStrategy)
|
if (strategy == BooleanSearchStrategy)
|
||||||
{
|
{
|
||||||
PG_RETURN_BOOL(signconsistent((QUERYTYPE *) query,
|
PG_RETURN_BOOL(signconsistent((QUERYTYPE *) query,
|
||||||
GETSIGN(DatumGetPointer(entry->key)),
|
GETSIGN(DatumGetPointer(entry->key)),
|
||||||
false));
|
false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree ** found)
|
|||||||
while (num > 0)
|
while (num > 0)
|
||||||
{
|
{
|
||||||
if (DatumGetBool(DirectFunctionCall2(callback,
|
if (DatumGetBool(DirectFunctionCall2(callback,
|
||||||
PointerGetDatum(item), PointerGetDatum(param))))
|
PointerGetDatum(item), PointerGetDatum(param))))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
|
@ -101,7 +101,7 @@ checkLevel(lquery_level * curq, ltree_level * curt)
|
|||||||
else if (
|
else if (
|
||||||
(
|
(
|
||||||
curvar->len == curt->len ||
|
curvar->len == curt->len ||
|
||||||
(curt->len > curvar->len && (curvar->flag & LVAR_ANYEND))
|
(curt->len > curvar->len && (curvar->flag & LVAR_ANYEND))
|
||||||
) &&
|
) &&
|
||||||
(*cmpptr) (curvar->name, curt->name, curvar->len) == 0)
|
(*cmpptr) (curvar->name, curt->name, curvar->len) == 0)
|
||||||
{
|
{
|
||||||
@ -332,7 +332,7 @@ lt_q_regex(PG_FUNCTION_ARGS)
|
|||||||
while (num > 0)
|
while (num > 0)
|
||||||
{
|
{
|
||||||
if (DatumGetBool(DirectFunctionCall2(ltq_regex,
|
if (DatumGetBool(DirectFunctionCall2(ltq_regex,
|
||||||
PointerGetDatum(tree), PointerGetDatum(query))))
|
PointerGetDatum(tree), PointerGetDatum(query))))
|
||||||
{
|
{
|
||||||
|
|
||||||
res = true;
|
res = true;
|
||||||
|
@ -157,7 +157,7 @@ bool ltree_execute(ITEM * curitem, void *checkval,
|
|||||||
int ltree_compare(const ltree * a, const ltree * b);
|
int ltree_compare(const ltree * a, const ltree * b);
|
||||||
bool inner_isparent(const ltree * c, const ltree * p);
|
bool inner_isparent(const ltree * c, const ltree * p);
|
||||||
bool compare_subnode(ltree_level * t, char *q, int len,
|
bool compare_subnode(ltree_level * t, char *q, int len,
|
||||||
int (*cmpptr) (const char *, const char *, size_t), bool anyend);
|
int (*cmpptr) (const char *, const char *, size_t), bool anyend);
|
||||||
ltree *lca_inner(ltree ** a, int len);
|
ltree *lca_inner(ltree ** a, int len);
|
||||||
|
|
||||||
#define PG_GETARG_LTREE(x) ((ltree*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(x))))
|
#define PG_GETARG_LTREE(x) ((ltree*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(x))))
|
||||||
|
@ -647,9 +647,9 @@ ltree_consistent(PG_FUNCTION_ARGS)
|
|||||||
res = (ltree_compare((ltree *) query, LTG_NODE(key)) == 0);
|
res = (ltree_compare((ltree *) query, LTG_NODE(key)) == 0);
|
||||||
else
|
else
|
||||||
res = (
|
res = (
|
||||||
ltree_compare((ltree *) query, LTG_GETLNODE(key)) >= 0
|
ltree_compare((ltree *) query, LTG_GETLNODE(key)) >= 0
|
||||||
&&
|
&&
|
||||||
ltree_compare((ltree *) query, LTG_GETRNODE(key)) <= 0
|
ltree_compare((ltree *) query, LTG_GETRNODE(key)) <= 0
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case BTGreaterEqualStrategyNumber:
|
case BTGreaterEqualStrategyNumber:
|
||||||
@ -677,8 +677,8 @@ ltree_consistent(PG_FUNCTION_ARGS)
|
|||||||
case 13:
|
case 13:
|
||||||
if (GIST_LEAF(entry))
|
if (GIST_LEAF(entry))
|
||||||
res = DatumGetBool(DirectFunctionCall2(ltq_regex,
|
res = DatumGetBool(DirectFunctionCall2(ltq_regex,
|
||||||
PointerGetDatum(LTG_NODE(key)),
|
PointerGetDatum(LTG_NODE(key)),
|
||||||
PointerGetDatum((lquery *) query)
|
PointerGetDatum((lquery *) query)
|
||||||
));
|
));
|
||||||
else
|
else
|
||||||
res = (gist_qe(key, (lquery *) query) && gist_between(key, (lquery *) query));
|
res = (gist_qe(key, (lquery *) query) && gist_between(key, (lquery *) query));
|
||||||
@ -687,8 +687,8 @@ ltree_consistent(PG_FUNCTION_ARGS)
|
|||||||
case 15:
|
case 15:
|
||||||
if (GIST_LEAF(entry))
|
if (GIST_LEAF(entry))
|
||||||
res = DatumGetBool(DirectFunctionCall2(ltxtq_exec,
|
res = DatumGetBool(DirectFunctionCall2(ltxtq_exec,
|
||||||
PointerGetDatum(LTG_NODE(key)),
|
PointerGetDatum(LTG_NODE(key)),
|
||||||
PointerGetDatum((lquery *) query)
|
PointerGetDatum((lquery *) query)
|
||||||
));
|
));
|
||||||
else
|
else
|
||||||
res = gist_qtxt(key, (ltxtquery *) query);
|
res = gist_qtxt(key, (ltxtquery *) query);
|
||||||
@ -697,8 +697,8 @@ ltree_consistent(PG_FUNCTION_ARGS)
|
|||||||
case 17:
|
case 17:
|
||||||
if (GIST_LEAF(entry))
|
if (GIST_LEAF(entry))
|
||||||
res = DatumGetBool(DirectFunctionCall2(lt_q_regex,
|
res = DatumGetBool(DirectFunctionCall2(lt_q_regex,
|
||||||
PointerGetDatum(LTG_NODE(key)),
|
PointerGetDatum(LTG_NODE(key)),
|
||||||
PointerGetDatum((ArrayType *) query)
|
PointerGetDatum((ArrayType *) query)
|
||||||
));
|
));
|
||||||
else
|
else
|
||||||
res = arrq_cons(key, (ArrayType *) query);
|
res = arrq_cons(key, (ArrayType *) query);
|
||||||
|
@ -82,7 +82,7 @@ ltree_in(PG_FUNCTION_ARGS)
|
|||||||
errmsg("name of level is too long"),
|
errmsg("name of level is too long"),
|
||||||
errdetail("name length is %d, must " \
|
errdetail("name length is %d, must " \
|
||||||
"be < 256, in position %d",
|
"be < 256, in position %d",
|
||||||
lptr->len, (int) (lptr->start - buf))));
|
lptr->len, (int) (lptr->start - buf))));
|
||||||
|
|
||||||
totallen += MAXALIGN(lptr->len + LEVEL_HDRSIZE);
|
totallen += MAXALIGN(lptr->len + LEVEL_HDRSIZE);
|
||||||
lptr++;
|
lptr++;
|
||||||
@ -284,7 +284,7 @@ lquery_in(PG_FUNCTION_ARGS)
|
|||||||
errmsg("name of level is too long"),
|
errmsg("name of level is too long"),
|
||||||
errdetail("name length is %d, must " \
|
errdetail("name length is %d, must " \
|
||||||
"be < 256, in position %d",
|
"be < 256, in position %d",
|
||||||
lptr->len, (int) (lptr->start - buf))));
|
lptr->len, (int) (lptr->start - buf))));
|
||||||
|
|
||||||
state = LQPRS_WAITVAR;
|
state = LQPRS_WAITVAR;
|
||||||
}
|
}
|
||||||
@ -300,7 +300,7 @@ lquery_in(PG_FUNCTION_ARGS)
|
|||||||
errmsg("name of level is too long"),
|
errmsg("name of level is too long"),
|
||||||
errdetail("name length is %d, must " \
|
errdetail("name length is %d, must " \
|
||||||
"be < 256, in position %d",
|
"be < 256, in position %d",
|
||||||
lptr->len, (int) (lptr->start - buf))));
|
lptr->len, (int) (lptr->start - buf))));
|
||||||
|
|
||||||
state = LQPRS_WAITLEVEL;
|
state = LQPRS_WAITLEVEL;
|
||||||
curqlevel = NEXTLEV(curqlevel);
|
curqlevel = NEXTLEV(curqlevel);
|
||||||
|
@ -264,7 +264,7 @@ msqlListTables(int a)
|
|||||||
char tbuf[BUFSIZ];
|
char tbuf[BUFSIZ];
|
||||||
|
|
||||||
snprintf(tbuf, BUFSIZ,
|
snprintf(tbuf, BUFSIZ,
|
||||||
"select relname from pg_class where relkind='r' and relowner=%d",
|
"select relname from pg_class where relkind='r' and relowner=%d",
|
||||||
geteuid());
|
geteuid());
|
||||||
if (msqlQuery(a, tbuf) > 0)
|
if (msqlQuery(a, tbuf) > 0)
|
||||||
{
|
{
|
||||||
@ -288,7 +288,7 @@ msqlListIndex(int a, char *b, char *c)
|
|||||||
char tbuf[BUFSIZ];
|
char tbuf[BUFSIZ];
|
||||||
|
|
||||||
snprintf(tbuf, BUFSIZ,
|
snprintf(tbuf, BUFSIZ,
|
||||||
"select relname from pg_class where relkind='i' and relowner=%d",
|
"select relname from pg_class where relkind='i' and relowner=%d",
|
||||||
geteuid());
|
geteuid());
|
||||||
if (msqlQuery(a, tbuf) > 0)
|
if (msqlQuery(a, tbuf) > 0)
|
||||||
{
|
{
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
/* an extensible array to keep track of elements to show */
|
/* an extensible array to keep track of elements to show */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char **array;
|
char **array;
|
||||||
int num;
|
int num;
|
||||||
int alloc;
|
int alloc;
|
||||||
} eary;
|
} eary;
|
||||||
|
|
||||||
/* these are the opts structures for command line params */
|
/* these are the opts structures for command line params */
|
||||||
struct options
|
struct options
|
||||||
@ -36,19 +36,19 @@ struct options
|
|||||||
bool extended;
|
bool extended;
|
||||||
bool tablespaces;
|
bool tablespaces;
|
||||||
|
|
||||||
char *dbname;
|
char *dbname;
|
||||||
char *hostname;
|
char *hostname;
|
||||||
char *port;
|
char *port;
|
||||||
char *username;
|
char *username;
|
||||||
char *password;
|
char *password;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
void get_opts(int, char **, struct options *);
|
void get_opts(int, char **, struct options *);
|
||||||
void *myalloc(size_t size);
|
void *myalloc(size_t size);
|
||||||
char *mystrdup(const char *str);
|
char *mystrdup(const char *str);
|
||||||
void add_one_elt(char *eltname, eary *eary);
|
void add_one_elt(char *eltname, eary * eary);
|
||||||
char *get_comma_elts(eary *eary);
|
char *get_comma_elts(eary * eary);
|
||||||
PGconn *sql_conn(struct options *);
|
PGconn *sql_conn(struct options *);
|
||||||
int sql_exec(PGconn *, const char *sql, bool quiet);
|
int sql_exec(PGconn *, const char *sql, bool quiet);
|
||||||
void sql_exec_dumpalldbs(PGconn *, struct options *);
|
void sql_exec_dumpalldbs(PGconn *, struct options *);
|
||||||
@ -95,7 +95,7 @@ get_opts(int argc, char **argv, struct options * my_opts)
|
|||||||
add_one_elt(optarg, my_opts->oids);
|
add_one_elt(optarg, my_opts->oids);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* specify one filenode to show*/
|
/* specify one filenode to show */
|
||||||
case 'f':
|
case 'f':
|
||||||
add_one_elt(optarg, my_opts->filenodes);
|
add_one_elt(optarg, my_opts->filenodes);
|
||||||
break;
|
break;
|
||||||
@ -149,23 +149,23 @@ get_opts(int argc, char **argv, struct options * my_opts)
|
|||||||
case '?':
|
case '?':
|
||||||
case 'h':
|
case 'h':
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: oid2name [-s|-d database] [-S][-i][-q][-x] [-t table|-o oid|-f file] ...\n"
|
"Usage: oid2name [-s|-d database] [-S][-i][-q][-x] [-t table|-o oid|-f file] ...\n"
|
||||||
" default action show all database Oids\n"
|
" default action show all database Oids\n"
|
||||||
" -d database database to connect to\n"
|
" -d database database to connect to\n"
|
||||||
" -s show all tablespaces\n"
|
" -s show all tablespaces\n"
|
||||||
" -S show system objects too\n"
|
" -S show system objects too\n"
|
||||||
" -i show indexes and sequences too\n"
|
" -i show indexes and sequences too\n"
|
||||||
" -x extended (show additional columns)\n"
|
" -x extended (show additional columns)\n"
|
||||||
" -q quiet (don't show headers)\n"
|
" -q quiet (don't show headers)\n"
|
||||||
" -t <table> show info for table named <table>\n"
|
" -t <table> show info for table named <table>\n"
|
||||||
" -o <oid> show info for table with Oid <oid>\n"
|
" -o <oid> show info for table with Oid <oid>\n"
|
||||||
" -f <filenode> show info for table with filenode <filenode>\n"
|
" -f <filenode> show info for table with filenode <filenode>\n"
|
||||||
" -H host connect to remote host\n"
|
" -H host connect to remote host\n"
|
||||||
" -p port host port to connect to\n"
|
" -p port host port to connect to\n"
|
||||||
" -U username username to connect with\n"
|
" -U username username to connect with\n"
|
||||||
" -P password password for username\n"
|
" -P password password for username\n"
|
||||||
" (see also $PGPASSWORD and ~/.pgpass)\n"
|
" (see also $PGPASSWORD and ~/.pgpass)\n"
|
||||||
);
|
);
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -175,7 +175,8 @@ get_opts(int argc, char **argv, struct options * my_opts)
|
|||||||
void *
|
void *
|
||||||
myalloc(size_t size)
|
myalloc(size_t size)
|
||||||
{
|
{
|
||||||
void *ptr = malloc(size);
|
void *ptr = malloc(size);
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
@ -187,7 +188,8 @@ myalloc(size_t size)
|
|||||||
char *
|
char *
|
||||||
mystrdup(const char *str)
|
mystrdup(const char *str)
|
||||||
{
|
{
|
||||||
char *result = strdup(str);
|
char *result = strdup(str);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
@ -202,7 +204,7 @@ mystrdup(const char *str)
|
|||||||
* Add one element to a (possibly empty) eary struct.
|
* Add one element to a (possibly empty) eary struct.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
add_one_elt(char *eltname, eary *eary)
|
add_one_elt(char *eltname, eary * eary)
|
||||||
{
|
{
|
||||||
if (eary->alloc == 0)
|
if (eary->alloc == 0)
|
||||||
{
|
{
|
||||||
@ -233,11 +235,12 @@ add_one_elt(char *eltname, eary *eary)
|
|||||||
* SQL statement.
|
* SQL statement.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
get_comma_elts(eary *eary)
|
get_comma_elts(eary * eary)
|
||||||
{
|
{
|
||||||
char *ret,
|
char *ret,
|
||||||
*ptr;
|
*ptr;
|
||||||
int i, length = 0;
|
int i,
|
||||||
|
length = 0;
|
||||||
|
|
||||||
if (eary->num == 0)
|
if (eary->num == 0)
|
||||||
return mystrdup("");
|
return mystrdup("");
|
||||||
@ -272,9 +275,9 @@ sql_conn(struct options * my_opts)
|
|||||||
|
|
||||||
/* login */
|
/* login */
|
||||||
conn = PQsetdbLogin(my_opts->hostname,
|
conn = PQsetdbLogin(my_opts->hostname,
|
||||||
my_opts->port,
|
my_opts->port,
|
||||||
NULL, /* options */
|
NULL, /* options */
|
||||||
NULL, /* tty */
|
NULL, /* tty */
|
||||||
my_opts->dbname,
|
my_opts->dbname,
|
||||||
my_opts->username,
|
my_opts->username,
|
||||||
my_opts->password);
|
my_opts->password);
|
||||||
@ -303,7 +306,9 @@ sql_exec(PGconn *conn, const char *todo, bool quiet)
|
|||||||
|
|
||||||
int nfields;
|
int nfields;
|
||||||
int nrows;
|
int nrows;
|
||||||
int i, j, l;
|
int i,
|
||||||
|
j,
|
||||||
|
l;
|
||||||
int *length;
|
int *length;
|
||||||
char *pad;
|
char *pad;
|
||||||
|
|
||||||
@ -334,7 +339,7 @@ sql_exec(PGconn *conn, const char *todo, bool quiet)
|
|||||||
{
|
{
|
||||||
for (j = 0; j < nfields; j++)
|
for (j = 0; j < nfields; j++)
|
||||||
{
|
{
|
||||||
l = strlen(PQgetvalue(res, i, j));
|
l = strlen(PQgetvalue(res, i, j));
|
||||||
if (l > length[j])
|
if (l > length[j])
|
||||||
length[j] = strlen(PQgetvalue(res, i, j));
|
length[j] = strlen(PQgetvalue(res, i, j));
|
||||||
}
|
}
|
||||||
@ -372,17 +377,17 @@ sql_exec(PGconn *conn, const char *todo, bool quiet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dump all databases. There are no system objects to worry about.
|
* Dump all databases. There are no system objects to worry about.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
sql_exec_dumpalldbs(PGconn *conn, struct options *opts)
|
sql_exec_dumpalldbs(PGconn *conn, struct options * opts)
|
||||||
{
|
{
|
||||||
char todo[1024];
|
char todo[1024];
|
||||||
|
|
||||||
/* get the oid and database name from the system pg_database table */
|
/* get the oid and database name from the system pg_database table */
|
||||||
snprintf(todo, sizeof(todo),
|
snprintf(todo, sizeof(todo),
|
||||||
"SELECT d.oid AS \"Oid\", datname AS \"Database Name\", "
|
"SELECT d.oid AS \"Oid\", datname AS \"Database Name\", "
|
||||||
"spcname AS \"Tablespace\" FROM pg_database d JOIN pg_tablespace t ON "
|
"spcname AS \"Tablespace\" FROM pg_database d JOIN pg_tablespace t ON "
|
||||||
"(dattablespace = t.oid) ORDER BY 2");
|
"(dattablespace = t.oid) ORDER BY 2");
|
||||||
|
|
||||||
sql_exec(conn, todo, opts->quiet);
|
sql_exec(conn, todo, opts->quiet);
|
||||||
@ -392,16 +397,16 @@ sql_exec_dumpalldbs(PGconn *conn, struct options *opts)
|
|||||||
* Dump all tables, indexes and sequences in the current database.
|
* Dump all tables, indexes and sequences in the current database.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
sql_exec_dumpalltables(PGconn *conn, struct options *opts)
|
sql_exec_dumpalltables(PGconn *conn, struct options * opts)
|
||||||
{
|
{
|
||||||
char todo[1024];
|
char todo[1024];
|
||||||
char *addfields = ",c.oid AS \"Oid\", nspname AS \"Schema\", spcname as \"Tablespace\" ";
|
char *addfields = ",c.oid AS \"Oid\", nspname AS \"Schema\", spcname as \"Tablespace\" ";
|
||||||
|
|
||||||
snprintf(todo, sizeof(todo),
|
snprintf(todo, sizeof(todo),
|
||||||
"SELECT relfilenode as \"Filenode\", relname as \"Table Name\" %s "
|
"SELECT relfilenode as \"Filenode\", relname as \"Table Name\" %s "
|
||||||
"FROM pg_class c "
|
"FROM pg_class c "
|
||||||
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace "
|
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace "
|
||||||
" LEFT JOIN pg_catalog.pg_database d ON d.datname = current_database(),"
|
" LEFT JOIN pg_catalog.pg_database d ON d.datname = current_database(),"
|
||||||
" pg_catalog.pg_tablespace t "
|
" pg_catalog.pg_tablespace t "
|
||||||
"WHERE relkind IN ('r'%s) AND "
|
"WHERE relkind IN ('r'%s) AND "
|
||||||
" %s"
|
" %s"
|
||||||
@ -412,7 +417,7 @@ sql_exec_dumpalltables(PGconn *conn, struct options *opts)
|
|||||||
"ORDER BY relname",
|
"ORDER BY relname",
|
||||||
opts->extended ? addfields : "",
|
opts->extended ? addfields : "",
|
||||||
opts->indexes ? ", 'i', 'S', 't'" : "",
|
opts->indexes ? ", 'i', 'S', 't'" : "",
|
||||||
opts->systables ? "" : "n.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema') AND");
|
opts->systables ? "" : "n.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema') AND");
|
||||||
|
|
||||||
sql_exec(conn, todo, opts->quiet);
|
sql_exec(conn, todo, opts->quiet);
|
||||||
}
|
}
|
||||||
@ -422,11 +427,14 @@ sql_exec_dumpalltables(PGconn *conn, struct options *opts)
|
|||||||
* given objects in the current database.
|
* given objects in the current database.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
sql_exec_searchtables(PGconn *conn, struct options *opts)
|
sql_exec_searchtables(PGconn *conn, struct options * opts)
|
||||||
{
|
{
|
||||||
char *todo;
|
char *todo;
|
||||||
char *qualifiers, *ptr;
|
char *qualifiers,
|
||||||
char *comma_oids, *comma_filenodes, *comma_tables;
|
*ptr;
|
||||||
|
char *comma_oids,
|
||||||
|
*comma_filenodes,
|
||||||
|
*comma_tables;
|
||||||
bool written = false;
|
bool written = false;
|
||||||
char *addfields = ",c.oid AS \"Oid\", nspname AS \"Schema\", spcname as \"Tablespace\" ";
|
char *addfields = ",c.oid AS \"Oid\", nspname AS \"Schema\", spcname as \"Tablespace\" ";
|
||||||
|
|
||||||
@ -465,9 +473,9 @@ sql_exec_searchtables(PGconn *conn, struct options *opts)
|
|||||||
/* now build the query */
|
/* now build the query */
|
||||||
todo = (char *) myalloc(650 + strlen(qualifiers));
|
todo = (char *) myalloc(650 + strlen(qualifiers));
|
||||||
snprintf(todo, 650 + strlen(qualifiers),
|
snprintf(todo, 650 + strlen(qualifiers),
|
||||||
"SELECT relfilenode as \"Filenode\", relname as \"Table Name\" %s\n"
|
"SELECT relfilenode as \"Filenode\", relname as \"Table Name\" %s\n"
|
||||||
"FROM pg_class c \n"
|
"FROM pg_class c \n"
|
||||||
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace \n"
|
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace \n"
|
||||||
" LEFT JOIN pg_catalog.pg_database d ON d.datname = current_database(),\n"
|
" LEFT JOIN pg_catalog.pg_database d ON d.datname = current_database(),\n"
|
||||||
" pg_catalog.pg_tablespace t \n"
|
" pg_catalog.pg_tablespace t \n"
|
||||||
"WHERE relkind IN ('r', 'i', 'S', 't') AND \n"
|
"WHERE relkind IN ('r', 'i', 'S', 't') AND \n"
|
||||||
@ -486,9 +494,9 @@ sql_exec_searchtables(PGconn *conn, struct options *opts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sql_exec_dumpalltbspc(PGconn *conn, struct options *opts)
|
sql_exec_dumpalltbspc(PGconn *conn, struct options * opts)
|
||||||
{
|
{
|
||||||
char todo[1024];
|
char todo[1024];
|
||||||
|
|
||||||
snprintf(todo, sizeof(todo),
|
snprintf(todo, sizeof(todo),
|
||||||
"SELECT oid AS \"Oid\", spcname as \"Tablespace Name\"\n"
|
"SELECT oid AS \"Oid\", spcname as \"Tablespace Name\"\n"
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* pg_buffercache_pages.c
|
* pg_buffercache_pages.c
|
||||||
* display some contents of the buffer cache
|
* display some contents of the buffer cache
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pg_buffercache/pg_buffercache_pages.c,v 1.5 2005/10/12 16:45:13 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pg_buffercache/pg_buffercache_pages.c,v 1.6 2005/10/15 02:49:05 momjian Exp $
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -17,11 +17,11 @@
|
|||||||
#define NUM_BUFFERCACHE_PAGES_ELEM 6
|
#define NUM_BUFFERCACHE_PAGES_ELEM 6
|
||||||
|
|
||||||
#if defined(WIN32) || defined(__CYGWIN__)
|
#if defined(WIN32) || defined(__CYGWIN__)
|
||||||
extern DLLIMPORT BufferDesc *BufferDescriptors;
|
extern DLLIMPORT BufferDesc *BufferDescriptors;
|
||||||
extern DLLIMPORT volatile uint32 InterruptHoldoffCount;
|
extern DLLIMPORT volatile uint32 InterruptHoldoffCount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Datum pg_buffercache_pages(PG_FUNCTION_ARGS);
|
Datum pg_buffercache_pages(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -34,11 +34,11 @@ typedef struct
|
|||||||
Oid relfilenode;
|
Oid relfilenode;
|
||||||
Oid reltablespace;
|
Oid reltablespace;
|
||||||
Oid reldatabase;
|
Oid reldatabase;
|
||||||
BlockNumber blocknum;
|
BlockNumber blocknum;
|
||||||
bool isvalid;
|
bool isvalid;
|
||||||
bool isdirty;
|
bool isdirty;
|
||||||
|
|
||||||
} BufferCachePagesRec;
|
} BufferCachePagesRec;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -47,11 +47,11 @@ typedef struct
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
||||||
AttInMetadata *attinmeta;
|
AttInMetadata *attinmeta;
|
||||||
BufferCachePagesRec *record;
|
BufferCachePagesRec *record;
|
||||||
char *values[NUM_BUFFERCACHE_PAGES_ELEM];
|
char *values[NUM_BUFFERCACHE_PAGES_ELEM];
|
||||||
|
|
||||||
} BufferCachePagesContext;
|
} BufferCachePagesContext;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -63,17 +63,17 @@ Datum
|
|||||||
pg_buffercache_pages(PG_FUNCTION_ARGS)
|
pg_buffercache_pages(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
FuncCallContext *funcctx;
|
FuncCallContext *funcctx;
|
||||||
Datum result;
|
Datum result;
|
||||||
MemoryContext oldcontext;
|
MemoryContext oldcontext;
|
||||||
BufferCachePagesContext *fctx; /* User function context. */
|
BufferCachePagesContext *fctx; /* User function context. */
|
||||||
TupleDesc tupledesc;
|
TupleDesc tupledesc;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
if (SRF_IS_FIRSTCALL())
|
if (SRF_IS_FIRSTCALL())
|
||||||
{
|
{
|
||||||
uint32 i;
|
uint32 i;
|
||||||
volatile BufferDesc *bufHdr;
|
volatile BufferDesc *bufHdr;
|
||||||
|
|
||||||
funcctx = SRF_FIRSTCALL_INIT();
|
funcctx = SRF_FIRSTCALL_INIT();
|
||||||
|
|
||||||
@ -83,24 +83,24 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
|
|||||||
/* Construct a tuple to return. */
|
/* Construct a tuple to return. */
|
||||||
tupledesc = CreateTemplateTupleDesc(NUM_BUFFERCACHE_PAGES_ELEM, false);
|
tupledesc = CreateTemplateTupleDesc(NUM_BUFFERCACHE_PAGES_ELEM, false);
|
||||||
TupleDescInitEntry(tupledesc, (AttrNumber) 1, "bufferid",
|
TupleDescInitEntry(tupledesc, (AttrNumber) 1, "bufferid",
|
||||||
INT4OID, -1, 0);
|
INT4OID, -1, 0);
|
||||||
TupleDescInitEntry(tupledesc, (AttrNumber) 2, "relfilenode",
|
TupleDescInitEntry(tupledesc, (AttrNumber) 2, "relfilenode",
|
||||||
OIDOID, -1, 0);
|
OIDOID, -1, 0);
|
||||||
TupleDescInitEntry(tupledesc, (AttrNumber) 3, "reltablespace",
|
TupleDescInitEntry(tupledesc, (AttrNumber) 3, "reltablespace",
|
||||||
OIDOID, -1, 0);
|
OIDOID, -1, 0);
|
||||||
TupleDescInitEntry(tupledesc, (AttrNumber) 4, "reldatabase",
|
TupleDescInitEntry(tupledesc, (AttrNumber) 4, "reldatabase",
|
||||||
OIDOID, -1, 0);
|
OIDOID, -1, 0);
|
||||||
TupleDescInitEntry(tupledesc, (AttrNumber) 5, "relblocknumber",
|
TupleDescInitEntry(tupledesc, (AttrNumber) 5, "relblocknumber",
|
||||||
INT8OID, -1, 0);
|
INT8OID, -1, 0);
|
||||||
TupleDescInitEntry(tupledesc, (AttrNumber) 6, "isdirty",
|
TupleDescInitEntry(tupledesc, (AttrNumber) 6, "isdirty",
|
||||||
BOOLOID, -1, 0);
|
BOOLOID, -1, 0);
|
||||||
|
|
||||||
/* Generate attribute metadata needed later to produce tuples */
|
/* Generate attribute metadata needed later to produce tuples */
|
||||||
funcctx->attinmeta = TupleDescGetAttInMetadata(tupledesc);
|
funcctx->attinmeta = TupleDescGetAttInMetadata(tupledesc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a function context for cross-call persistence
|
* Create a function context for cross-call persistence and initialize
|
||||||
* and initialize the buffer counters.
|
* the buffer counters.
|
||||||
*/
|
*/
|
||||||
fctx = (BufferCachePagesContext *) palloc(sizeof(BufferCachePagesContext));
|
fctx = (BufferCachePagesContext *) palloc(sizeof(BufferCachePagesContext));
|
||||||
funcctx->max_calls = NBuffers;
|
funcctx->max_calls = NBuffers;
|
||||||
@ -166,14 +166,14 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
if (funcctx->call_cntr < funcctx->max_calls)
|
if (funcctx->call_cntr < funcctx->max_calls)
|
||||||
{
|
{
|
||||||
uint32 i = funcctx->call_cntr;
|
uint32 i = funcctx->call_cntr;
|
||||||
char *values[NUM_BUFFERCACHE_PAGES_ELEM];
|
char *values[NUM_BUFFERCACHE_PAGES_ELEM];
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use a temporary values array, initially pointing to
|
* Use a temporary values array, initially pointing to fctx->values,
|
||||||
* fctx->values, so it can be reassigned w/o losing the storage
|
* so it can be reassigned w/o losing the storage for subsequent
|
||||||
* for subsequent calls.
|
* calls.
|
||||||
*/
|
*/
|
||||||
for (j = 0; j < NUM_BUFFERCACHE_PAGES_ELEM; j++)
|
for (j = 0; j < NUM_BUFFERCACHE_PAGES_ELEM; j++)
|
||||||
{
|
{
|
||||||
@ -182,11 +182,11 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set all fields except the bufferid to null if the buffer is
|
* Set all fields except the bufferid to null if the buffer is unused
|
||||||
* unused or not valid.
|
* or not valid.
|
||||||
*/
|
*/
|
||||||
if (fctx->record[i].blocknum == InvalidBlockNumber ||
|
if (fctx->record[i].blocknum == InvalidBlockNumber ||
|
||||||
fctx->record[i].isvalid == false )
|
fctx->record[i].isvalid == false)
|
||||||
{
|
{
|
||||||
|
|
||||||
sprintf(values[0], "%u", fctx->record[i].bufferid);
|
sprintf(values[0], "%u", fctx->record[i].bufferid);
|
||||||
@ -228,4 +228,3 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
|
|||||||
SRF_RETURN_DONE(funcctx);
|
SRF_RETURN_DONE(funcctx);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,8 +300,8 @@ similarity_op(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
float4 res = DatumGetFloat4(DirectFunctionCall2(
|
float4 res = DatumGetFloat4(DirectFunctionCall2(
|
||||||
similarity,
|
similarity,
|
||||||
PG_GETARG_DATUM(0),
|
PG_GETARG_DATUM(0),
|
||||||
PG_GETARG_DATUM(1)
|
PG_GETARG_DATUM(1)
|
||||||
));
|
));
|
||||||
|
|
||||||
PG_RETURN_BOOL(res >= trgm_limit);
|
PG_RETURN_BOOL(res >= trgm_limit);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.42 2005/10/07 15:34:17 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.43 2005/10/15 02:49:06 momjian Exp $
|
||||||
*
|
*
|
||||||
* pgbench: a simple benchmark program for PostgreSQL
|
* pgbench: a simple benchmark program for PostgreSQL
|
||||||
* written by Tatsuo Ishii
|
* written by Tatsuo Ishii
|
||||||
@ -55,8 +55,7 @@ extern int optind;
|
|||||||
#define MAXCLIENTS 1024 /* max number of clients allowed */
|
#define MAXCLIENTS 1024 /* max number of clients allowed */
|
||||||
|
|
||||||
int nclients = 1; /* default number of simulated clients */
|
int nclients = 1; /* default number of simulated clients */
|
||||||
int nxacts = 10; /* default number of transactions per
|
int nxacts = 10; /* default number of transactions per clients */
|
||||||
* clients */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* scaling factor. for example, tps = 10 will make 1000000 tuples of
|
* scaling factor. for example, tps = 10 will make 1000000 tuples of
|
||||||
@ -78,8 +77,7 @@ bool use_log; /* log transaction latencies to a file */
|
|||||||
|
|
||||||
int remains; /* number of remaining clients */
|
int remains; /* number of remaining clients */
|
||||||
|
|
||||||
int is_connect; /* establish connection for each
|
int is_connect; /* establish connection for each transaction */
|
||||||
* transaction */
|
|
||||||
|
|
||||||
char *pghost = "";
|
char *pghost = "";
|
||||||
char *pgport = NULL;
|
char *pgport = NULL;
|
||||||
@ -92,8 +90,8 @@ char *dbName;
|
|||||||
/* variable definitions */
|
/* variable definitions */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *name; /* variable name */
|
char *name; /* variable name */
|
||||||
char *value; /* its value */
|
char *value; /* its value */
|
||||||
} Variable;
|
} Variable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -107,8 +105,8 @@ typedef struct
|
|||||||
int state; /* state No. */
|
int state; /* state No. */
|
||||||
int cnt; /* xacts count */
|
int cnt; /* xacts count */
|
||||||
int ecnt; /* error count */
|
int ecnt; /* error count */
|
||||||
int listen; /* 0 indicates that an async query has
|
int listen; /* 0 indicates that an async query has been
|
||||||
* been sent */
|
* sent */
|
||||||
Variable *variables; /* array of variable definitions */
|
Variable *variables; /* array of variable definitions */
|
||||||
int nvariables;
|
int nvariables;
|
||||||
struct timeval txn_begin; /* used for measuring latencies */
|
struct timeval txn_begin; /* used for measuring latencies */
|
||||||
@ -124,48 +122,48 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int type; /* command type (SQL_COMMAND or META_COMMAND) */
|
int type; /* command type (SQL_COMMAND or META_COMMAND) */
|
||||||
int argc; /* number of commands */
|
int argc; /* number of commands */
|
||||||
char *argv[MAX_ARGS]; /* command list */
|
char *argv[MAX_ARGS]; /* command list */
|
||||||
} Command;
|
} Command;
|
||||||
|
|
||||||
#define MAX_FILES 128 /* max number of SQL script files allowed */
|
#define MAX_FILES 128 /* max number of SQL script files allowed */
|
||||||
|
|
||||||
Command **sql_files[MAX_FILES]; /* SQL script files */
|
Command **sql_files[MAX_FILES]; /* SQL script files */
|
||||||
int num_files; /* its number */
|
int num_files; /* its number */
|
||||||
|
|
||||||
/* default scenario */
|
/* default scenario */
|
||||||
static char *tpc_b = {
|
static char *tpc_b = {
|
||||||
"\\setrandom aid 1 100000\n"
|
"\\setrandom aid 1 100000\n"
|
||||||
"\\setrandom bid 1 1\n"
|
"\\setrandom bid 1 1\n"
|
||||||
"\\setrandom tid 1 10\n"
|
"\\setrandom tid 1 10\n"
|
||||||
"\\setrandom delta 1 10000\n"
|
"\\setrandom delta 1 10000\n"
|
||||||
"BEGIN;\n"
|
"BEGIN;\n"
|
||||||
"UPDATE accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
|
"UPDATE accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
|
||||||
"SELECT abalance FROM accounts WHERE aid = :aid;\n"
|
"SELECT abalance FROM accounts WHERE aid = :aid;\n"
|
||||||
"UPDATE tellers SET tbalance = tbalance + :delta WHERE tid = :tid;\n"
|
"UPDATE tellers SET tbalance = tbalance + :delta WHERE tid = :tid;\n"
|
||||||
"UPDATE branches SET bbalance = bbalance + :delta WHERE bid = :bid;\n"
|
"UPDATE branches SET bbalance = bbalance + :delta WHERE bid = :bid;\n"
|
||||||
"INSERT INTO history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
|
"INSERT INTO history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
|
||||||
"END;\n"
|
"END;\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* -N case */
|
/* -N case */
|
||||||
static char *simple_update = {
|
static char *simple_update = {
|
||||||
"\\setrandom aid 1 100000\n"
|
"\\setrandom aid 1 100000\n"
|
||||||
"\\setrandom bid 1 1\n"
|
"\\setrandom bid 1 1\n"
|
||||||
"\\setrandom tid 1 10\n"
|
"\\setrandom tid 1 10\n"
|
||||||
"\\setrandom delta 1 10000\n"
|
"\\setrandom delta 1 10000\n"
|
||||||
"BEGIN;\n"
|
"BEGIN;\n"
|
||||||
"UPDATE accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
|
"UPDATE accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
|
||||||
"SELECT abalance FROM accounts WHERE aid = :aid;\n"
|
"SELECT abalance FROM accounts WHERE aid = :aid;\n"
|
||||||
"INSERT INTO history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
|
"INSERT INTO history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
|
||||||
"END;\n"
|
"END;\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* -S case */
|
/* -S case */
|
||||||
static char *select_only = {
|
static char *select_only = {
|
||||||
"\\setrandom aid 1 100000\n"
|
"\\setrandom aid 1 100000\n"
|
||||||
"SELECT abalance FROM accounts WHERE aid = :aid;\n"
|
"SELECT abalance FROM accounts WHERE aid = :aid;\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -262,7 +260,7 @@ compareVariables(const void *v1, const void *v2)
|
|||||||
static char *
|
static char *
|
||||||
getVariable(CState * st, char *name)
|
getVariable(CState * st, char *name)
|
||||||
{
|
{
|
||||||
Variable key = { name }, *var;
|
Variable key = {name}, *var;
|
||||||
|
|
||||||
/* On some versions of Solaris, bsearch of zero items dumps core */
|
/* On some versions of Solaris, bsearch of zero items dumps core */
|
||||||
if (st->nvariables <= 0)
|
if (st->nvariables <= 0)
|
||||||
@ -282,7 +280,7 @@ getVariable(CState * st, char *name)
|
|||||||
static int
|
static int
|
||||||
putVariable(CState * st, char *name, char *value)
|
putVariable(CState * st, char *name, char *value)
|
||||||
{
|
{
|
||||||
Variable key = { name }, *var;
|
Variable key = {name}, *var;
|
||||||
|
|
||||||
/* On some versions of Solaris, bsearch of zero items dumps core */
|
/* On some versions of Solaris, bsearch of zero items dumps core */
|
||||||
if (st->nvariables > 0)
|
if (st->nvariables > 0)
|
||||||
@ -300,7 +298,7 @@ putVariable(CState * st, char *name, char *value)
|
|||||||
|
|
||||||
if (st->variables)
|
if (st->variables)
|
||||||
newvars = (Variable *) realloc(st->variables,
|
newvars = (Variable *) realloc(st->variables,
|
||||||
(st->nvariables + 1) * sizeof(Variable));
|
(st->nvariables + 1) * sizeof(Variable));
|
||||||
else
|
else
|
||||||
newvars = (Variable *) malloc(sizeof(Variable));
|
newvars = (Variable *) malloc(sizeof(Variable));
|
||||||
|
|
||||||
@ -341,15 +339,19 @@ putVariable(CState * st, char *name, char *value)
|
|||||||
static char *
|
static char *
|
||||||
assignVariables(CState * st, char *sql)
|
assignVariables(CState * st, char *sql)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i,
|
||||||
char *p, *name, *val;
|
j;
|
||||||
|
char *p,
|
||||||
|
*name,
|
||||||
|
*val;
|
||||||
void *tmp;
|
void *tmp;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((p = strchr(&sql[i], ':')) != NULL)
|
while ((p = strchr(&sql[i], ':')) != NULL)
|
||||||
{
|
{
|
||||||
i = j = p - sql;
|
i = j = p - sql;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
i++;
|
i++;
|
||||||
} while (isalnum((unsigned char) sql[i]) || sql[i] == '_');
|
} while (isalnum((unsigned char) sql[i]) || sql[i] == '_');
|
||||||
if (i == j + 1)
|
if (i == j + 1)
|
||||||
@ -403,7 +405,7 @@ doCustom(CState * state, int n, int debug)
|
|||||||
{
|
{
|
||||||
PGresult *res;
|
PGresult *res;
|
||||||
CState *st = &state[n];
|
CState *st = &state[n];
|
||||||
Command **commands;
|
Command **commands;
|
||||||
|
|
||||||
commands = sql_files[st->use_file];
|
commands = sql_files[st->use_file];
|
||||||
|
|
||||||
@ -414,20 +416,19 @@ doCustom(CState * state, int n, int debug)
|
|||||||
if (debug)
|
if (debug)
|
||||||
fprintf(stderr, "client %d receiving\n", n);
|
fprintf(stderr, "client %d receiving\n", n);
|
||||||
if (!PQconsumeInput(st->con))
|
if (!PQconsumeInput(st->con))
|
||||||
{ /* there's something wrong */
|
{ /* there's something wrong */
|
||||||
fprintf(stderr, "Client %d aborted in state %d. Probably the backend died while processing.\n", n, st->state);
|
fprintf(stderr, "Client %d aborted in state %d. Probably the backend died while processing.\n", n, st->state);
|
||||||
remains--; /* I've aborted */
|
remains--; /* I've aborted */
|
||||||
PQfinish(st->con);
|
PQfinish(st->con);
|
||||||
st->con = NULL;
|
st->con = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (PQisBusy(st->con))
|
if (PQisBusy(st->con))
|
||||||
return; /* don't have the whole result yet */
|
return; /* don't have the whole result yet */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* transaction finished: record the time it took in the
|
* transaction finished: record the time it took in the log
|
||||||
* log
|
|
||||||
*/
|
*/
|
||||||
if (use_log && commands[st->state + 1] == NULL)
|
if (use_log && commands[st->state + 1] == NULL)
|
||||||
{
|
{
|
||||||
@ -468,7 +469,7 @@ doCustom(CState * state, int n, int debug)
|
|||||||
|
|
||||||
if (++st->cnt >= nxacts)
|
if (++st->cnt >= nxacts)
|
||||||
{
|
{
|
||||||
remains--; /* I've done */
|
remains--; /* I've done */
|
||||||
if (st->con != NULL)
|
if (st->con != NULL)
|
||||||
{
|
{
|
||||||
PQfinish(st->con);
|
PQfinish(st->con);
|
||||||
@ -483,7 +484,7 @@ doCustom(CState * state, int n, int debug)
|
|||||||
if (commands[st->state] == NULL)
|
if (commands[st->state] == NULL)
|
||||||
{
|
{
|
||||||
st->state = 0;
|
st->state = 0;
|
||||||
st->use_file = getrand(0, num_files-1);
|
st->use_file = getrand(0, num_files - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,13 +526,14 @@ doCustom(CState * state, int n, int debug)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
st->listen = 1; /* flags that should be listened */
|
st->listen = 1; /* flags that should be listened */
|
||||||
}
|
}
|
||||||
free(sql);
|
free(sql);
|
||||||
}
|
}
|
||||||
else if (commands[st->state]->type == META_COMMAND)
|
else if (commands[st->state]->type == META_COMMAND)
|
||||||
{
|
{
|
||||||
int argc = commands[st->state]->argc, i;
|
int argc = commands[st->state]->argc,
|
||||||
|
i;
|
||||||
char **argv = commands[st->state]->argv;
|
char **argv = commands[st->state]->argv;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -748,28 +750,29 @@ init(void)
|
|||||||
PQfinish(con);
|
PQfinish(con);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Command*
|
static Command *
|
||||||
process_commands(char *buf)
|
process_commands(char *buf)
|
||||||
{
|
{
|
||||||
const char delim[] = " \f\n\r\t\v";
|
const char delim[] = " \f\n\r\t\v";
|
||||||
|
|
||||||
Command *my_commands;
|
Command *my_commands;
|
||||||
int j;
|
int j;
|
||||||
char *p, *tok;
|
char *p,
|
||||||
|
*tok;
|
||||||
|
|
||||||
if ((p = strchr(buf, '\n')) != NULL)
|
if ((p = strchr(buf, '\n')) != NULL)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
p = buf;
|
p = buf;
|
||||||
while (isspace((unsigned char) *p))
|
while (isspace((unsigned char) *p))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
if (*p == '\0' || strncmp(p, "--", 2) == 0)
|
if (*p == '\0' || strncmp(p, "--", 2) == 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
my_commands = (Command *)malloc(sizeof(Command));
|
my_commands = (Command *) malloc(sizeof(Command));
|
||||||
if (my_commands == NULL)
|
if (my_commands == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -797,7 +800,8 @@ process_commands(char *buf)
|
|||||||
|
|
||||||
if (strcasecmp(my_commands->argv[0], "setrandom") == 0)
|
if (strcasecmp(my_commands->argv[0], "setrandom") == 0)
|
||||||
{
|
{
|
||||||
int min, max;
|
int min,
|
||||||
|
max;
|
||||||
|
|
||||||
if (my_commands->argc < 4)
|
if (my_commands->argc < 4)
|
||||||
{
|
{
|
||||||
@ -806,8 +810,8 @@ process_commands(char *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (j = 4; j < my_commands->argc; j++)
|
for (j = 4; j < my_commands->argc; j++)
|
||||||
fprintf(stderr, "%s: extra argument \"%s\" ignored\n",
|
fprintf(stderr, "%s: extra argument \"%s\" ignored\n",
|
||||||
my_commands->argv[0], my_commands->argv[j]);
|
my_commands->argv[0], my_commands->argv[j]);
|
||||||
|
|
||||||
if ((min = atoi(my_commands->argv[2])) < 0)
|
if ((min = atoi(my_commands->argv[2])) < 0)
|
||||||
{
|
{
|
||||||
@ -825,7 +829,7 @@ process_commands(char *buf)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "invalid command %s\n", my_commands->argv[0]);
|
fprintf(stderr, "invalid command %s\n", my_commands->argv[0]);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -847,11 +851,11 @@ process_file(char *filename)
|
|||||||
{
|
{
|
||||||
#define COMMANDS_ALLOC_NUM 128
|
#define COMMANDS_ALLOC_NUM 128
|
||||||
|
|
||||||
Command **my_commands;
|
Command **my_commands;
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
int lineno;
|
int lineno;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
int alloc_num;
|
int alloc_num;
|
||||||
|
|
||||||
if (num_files >= MAX_FILES)
|
if (num_files >= MAX_FILES)
|
||||||
{
|
{
|
||||||
@ -860,7 +864,7 @@ process_file(char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
alloc_num = COMMANDS_ALLOC_NUM;
|
alloc_num = COMMANDS_ALLOC_NUM;
|
||||||
my_commands = (Command **)malloc(sizeof(Command **)*alloc_num);
|
my_commands = (Command **) malloc(sizeof(Command **) * alloc_num);
|
||||||
if (my_commands == NULL)
|
if (my_commands == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -876,7 +880,7 @@ process_file(char *filename)
|
|||||||
|
|
||||||
while (fgets(buf, sizeof(buf), fd) != NULL)
|
while (fgets(buf, sizeof(buf), fd) != NULL)
|
||||||
{
|
{
|
||||||
Command *commands;
|
Command *commands;
|
||||||
|
|
||||||
commands = process_commands(buf);
|
commands = process_commands(buf);
|
||||||
if (commands == NULL)
|
if (commands == NULL)
|
||||||
@ -913,25 +917,25 @@ process_builtin(char *tb)
|
|||||||
{
|
{
|
||||||
#define COMMANDS_ALLOC_NUM 128
|
#define COMMANDS_ALLOC_NUM 128
|
||||||
|
|
||||||
Command **my_commands;
|
Command **my_commands;
|
||||||
int lineno;
|
int lineno;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
int alloc_num;
|
int alloc_num;
|
||||||
|
|
||||||
if (*tb == '\0')
|
if (*tb == '\0')
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
alloc_num = COMMANDS_ALLOC_NUM;
|
alloc_num = COMMANDS_ALLOC_NUM;
|
||||||
my_commands = malloc(sizeof(Command **)*alloc_num);
|
my_commands = malloc(sizeof(Command **) * alloc_num);
|
||||||
if (my_commands == NULL)
|
if (my_commands == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
lineno = 0;
|
lineno = 0;
|
||||||
|
|
||||||
for(;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
Command *commands;
|
Command *commands;
|
||||||
|
|
||||||
p = buf;
|
p = buf;
|
||||||
while (*tb && *tb != '\n')
|
while (*tb && *tb != '\n')
|
||||||
@ -1016,20 +1020,18 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int is_init_mode = 0; /* initialize mode? */
|
int is_init_mode = 0; /* initialize mode? */
|
||||||
int is_no_vacuum = 0; /* no vacuum at all before
|
int is_no_vacuum = 0; /* no vacuum at all before testing? */
|
||||||
* testing? */
|
|
||||||
int is_full_vacuum = 0; /* do full vacuum before testing? */
|
int is_full_vacuum = 0; /* do full vacuum before testing? */
|
||||||
int debug = 0; /* debug flag */
|
int debug = 0; /* debug flag */
|
||||||
int ttype = 0; /* transaction type. 0: TPC-B, 1: SELECT
|
int ttype = 0; /* transaction type. 0: TPC-B, 1: SELECT only,
|
||||||
* only, 2: skip update of branches and
|
* 2: skip update of branches and tellers */
|
||||||
* tellers */
|
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
|
|
||||||
static CState *state; /* status of clients */
|
static CState *state; /* status of clients */
|
||||||
|
|
||||||
struct timeval tv1; /* start up time */
|
struct timeval tv1; /* start up time */
|
||||||
struct timeval tv2; /* after establishing all connections to
|
struct timeval tv2; /* after establishing all connections to the
|
||||||
* the backend */
|
* backend */
|
||||||
struct timeval tv3; /* end time */
|
struct timeval tv3; /* end time */
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
@ -1105,7 +1107,8 @@ main(int argc, char **argv)
|
|||||||
fprintf(stderr, "Use limit/ulimt to increase the limit before using pgbench.\n");
|
fprintf(stderr, "Use limit/ulimt to increase the limit before using pgbench.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#endif /* #if !(defined(__CYGWIN__) || defined(__MINGW32__)) */
|
#endif /* #if !(defined(__CYGWIN__) ||
|
||||||
|
* defined(__MINGW32__)) */
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
is_connect = 1;
|
is_connect = 1;
|
||||||
@ -1305,35 +1308,35 @@ main(int argc, char **argv)
|
|||||||
/* process bultin SQL scripts */
|
/* process bultin SQL scripts */
|
||||||
switch (ttype)
|
switch (ttype)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
sql_files[0] = process_builtin(tpc_b);
|
sql_files[0] = process_builtin(tpc_b);
|
||||||
snprintf(buf, sizeof(buf), "%d", 100000*tps);
|
snprintf(buf, sizeof(buf), "%d", 100000 * tps);
|
||||||
sql_files[0][0]->argv[3] = strdup(buf);
|
sql_files[0][0]->argv[3] = strdup(buf);
|
||||||
snprintf(buf, sizeof(buf), "%d", 1*tps);
|
snprintf(buf, sizeof(buf), "%d", 1 * tps);
|
||||||
sql_files[0][1]->argv[3] = strdup(buf);
|
sql_files[0][1]->argv[3] = strdup(buf);
|
||||||
snprintf(buf, sizeof(buf), "%d", 10*tps);
|
snprintf(buf, sizeof(buf), "%d", 10 * tps);
|
||||||
sql_files[0][2]->argv[3] = strdup(buf);
|
sql_files[0][2]->argv[3] = strdup(buf);
|
||||||
snprintf(buf, sizeof(buf), "%d", 10000*tps);
|
snprintf(buf, sizeof(buf), "%d", 10000 * tps);
|
||||||
sql_files[0][3]->argv[3] = strdup(buf);
|
sql_files[0][3]->argv[3] = strdup(buf);
|
||||||
num_files = 1;
|
num_files = 1;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
sql_files[0] = process_builtin(select_only);
|
sql_files[0] = process_builtin(select_only);
|
||||||
snprintf(buf, sizeof(buf), "%d", 100000*tps);
|
snprintf(buf, sizeof(buf), "%d", 100000 * tps);
|
||||||
sql_files[0][0]->argv[3] = strdup(buf);
|
sql_files[0][0]->argv[3] = strdup(buf);
|
||||||
num_files = 1;
|
num_files = 1;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
sql_files[0] = process_builtin(simple_update);
|
sql_files[0] = process_builtin(simple_update);
|
||||||
snprintf(buf, sizeof(buf), "%d", 100000*tps);
|
snprintf(buf, sizeof(buf), "%d", 100000 * tps);
|
||||||
sql_files[0][0]->argv[3] = strdup(buf);
|
sql_files[0][0]->argv[3] = strdup(buf);
|
||||||
snprintf(buf, sizeof(buf), "%d", 1*tps);
|
snprintf(buf, sizeof(buf), "%d", 1 * tps);
|
||||||
sql_files[0][1]->argv[3] = strdup(buf);
|
sql_files[0][1]->argv[3] = strdup(buf);
|
||||||
snprintf(buf, sizeof(buf), "%d", 10*tps);
|
snprintf(buf, sizeof(buf), "%d", 10 * tps);
|
||||||
sql_files[0][2]->argv[3] = strdup(buf);
|
sql_files[0][2]->argv[3] = strdup(buf);
|
||||||
snprintf(buf, sizeof(buf), "%d", 10000*tps);
|
snprintf(buf, sizeof(buf), "%d", 10000 * tps);
|
||||||
sql_files[0][3]->argv[3] = strdup(buf);
|
sql_files[0][3]->argv[3] = strdup(buf);
|
||||||
num_files = 1;
|
num_files = 1;
|
||||||
break;
|
break;
|
||||||
@ -1344,7 +1347,7 @@ main(int argc, char **argv)
|
|||||||
/* send start up queries in async manner */
|
/* send start up queries in async manner */
|
||||||
for (i = 0; i < nclients; i++)
|
for (i = 0; i < nclients; i++)
|
||||||
{
|
{
|
||||||
state[i].use_file = getrand(0, num_files-1);
|
state[i].use_file = getrand(0, num_files - 1);
|
||||||
doCustom(state, i, debug);
|
doCustom(state, i, debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1366,9 +1369,9 @@ main(int argc, char **argv)
|
|||||||
maxsock = -1;
|
maxsock = -1;
|
||||||
for (i = 0; i < nclients; i++)
|
for (i = 0; i < nclients; i++)
|
||||||
{
|
{
|
||||||
Command **commands = sql_files[state[i].use_file];
|
Command **commands = sql_files[state[i].use_file];
|
||||||
|
|
||||||
if (state[i].con && commands[state[i].state]->type != META_COMMAND)
|
if (state[i].con && commands[state[i].state]->type != META_COMMAND)
|
||||||
{
|
{
|
||||||
int sock = PQsocket(state[i].con);
|
int sock = PQsocket(state[i].con);
|
||||||
|
|
||||||
@ -1396,7 +1399,7 @@ main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
else if (nsocks == 0)
|
else if (nsocks == 0)
|
||||||
{ /* timeout */
|
{ /* timeout */
|
||||||
fprintf(stderr, "select timeout\n");
|
fprintf(stderr, "select timeout\n");
|
||||||
for (i = 0; i < nclients; i++)
|
for (i = 0; i < nclients; i++)
|
||||||
{
|
{
|
||||||
@ -1410,10 +1413,10 @@ main(int argc, char **argv)
|
|||||||
/* ok, backend returns reply */
|
/* ok, backend returns reply */
|
||||||
for (i = 0; i < nclients; i++)
|
for (i = 0; i < nclients; i++)
|
||||||
{
|
{
|
||||||
Command **commands = sql_files[state[i].use_file];
|
Command **commands = sql_files[state[i].use_file];
|
||||||
|
|
||||||
if (state[i].con && (FD_ISSET(PQsocket(state[i].con), &input_mask)
|
if (state[i].con && (FD_ISSET(PQsocket(state[i].con), &input_mask)
|
||||||
|| commands[state[i].state]->type == META_COMMAND))
|
|| commands[state[i].state]->type == META_COMMAND))
|
||||||
{
|
{
|
||||||
doCustom(state, i, debug);
|
doCustom(state, i, debug);
|
||||||
}
|
}
|
||||||
|
@ -520,7 +520,6 @@ extern void _BF_body_r(BF_ctx * ctx);
|
|||||||
|
|
||||||
#define BF_body() \
|
#define BF_body() \
|
||||||
_BF_body_r(&data.ctx);
|
_BF_body_r(&data.ctx);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define BF_body() \
|
#define BF_body() \
|
||||||
@ -712,7 +711,7 @@ _crypt_blowfish_rn(const char *key, const char *setting,
|
|||||||
|
|
||||||
memcpy(output, setting, 7 + 22 - 1);
|
memcpy(output, setting, 7 + 22 - 1);
|
||||||
output[7 + 22 - 1] = BF_itoa64[(int)
|
output[7 + 22 - 1] = BF_itoa64[(int)
|
||||||
BF_atoi64[(int) setting[7 + 22 - 1] - 0x20] & 0x30];
|
BF_atoi64[(int) setting[7 + 22 - 1] - 0x20] & 0x30];
|
||||||
|
|
||||||
/* This has to be bug-compatible with the original implementation, so
|
/* This has to be bug-compatible with the original implementation, so
|
||||||
* only encode 23 of the 24 bytes. :-) */
|
* only encode 23 of the 24 bytes. :-) */
|
||||||
|
@ -246,8 +246,8 @@ des_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert the inverted S-boxes into 4 arrays of 8 bits. Each will
|
* Convert the inverted S-boxes into 4 arrays of 8 bits. Each will handle
|
||||||
* handle 12 bits of the S-box input.
|
* 12 bits of the S-box input.
|
||||||
*/
|
*/
|
||||||
for (b = 0; b < 4; b++)
|
for (b = 0; b < 4; b++)
|
||||||
for (i = 0; i < 64; i++)
|
for (i = 0; i < 64; i++)
|
||||||
@ -267,8 +267,8 @@ des_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Invert the key permutation and initialise the inverted key
|
* Invert the key permutation and initialise the inverted key compression
|
||||||
* compression permutation.
|
* permutation.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < 56; i++)
|
for (i = 0; i < 56; i++)
|
||||||
{
|
{
|
||||||
@ -284,8 +284,8 @@ des_init(void)
|
|||||||
inv_comp_perm[comp_perm[i] - 1] = i;
|
inv_comp_perm[comp_perm[i] - 1] = i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the OR-mask arrays for the initial and final permutations,
|
* Set up the OR-mask arrays for the initial and final permutations, and
|
||||||
* and for the key initial and compression permutations.
|
* for the key initial and compression permutations.
|
||||||
*/
|
*/
|
||||||
for (k = 0; k < 8; k++)
|
for (k = 0; k < 8; k++)
|
||||||
{
|
{
|
||||||
@ -347,8 +347,8 @@ des_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Invert the P-box permutation, and convert into OR-masks for
|
* Invert the P-box permutation, and convert into OR-masks for handling
|
||||||
* handling the output of the S-box arrays setup above.
|
* the output of the S-box arrays setup above.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
un_pbox[pbox[i] - 1] = i;
|
un_pbox[pbox[i] - 1] = i;
|
||||||
@ -411,9 +411,9 @@ des_setkey(const char *key)
|
|||||||
&& rawkey1 == old_rawkey1)
|
&& rawkey1 == old_rawkey1)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Already setup for this key. This optimisation fails on a zero
|
* Already setup for this key. This optimisation fails on a zero key
|
||||||
* key (which is weak and has bad parity anyway) in order to
|
* (which is weak and has bad parity anyway) in order to simplify the
|
||||||
* simplify the starting conditions.
|
* starting conditions.
|
||||||
*/
|
*/
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -560,16 +560,16 @@ do_des(uint32 l_in, uint32 r_in, uint32 *l_out, uint32 *r_out, int count)
|
|||||||
| ((r & 0x80000000) >> 31);
|
| ((r & 0x80000000) >> 31);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do salting for crypt() and friends, and XOR with the
|
* Do salting for crypt() and friends, and XOR with the permuted
|
||||||
* permuted key.
|
* key.
|
||||||
*/
|
*/
|
||||||
f = (r48l ^ r48r) & saltbits;
|
f = (r48l ^ r48r) & saltbits;
|
||||||
r48l ^= f ^ *kl++;
|
r48l ^= f ^ *kl++;
|
||||||
r48r ^= f ^ *kr++;
|
r48r ^= f ^ *kr++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do sbox lookups (which shrink it back to 32 bits) and do
|
* Do sbox lookups (which shrink it back to 32 bits) and do the
|
||||||
* the pbox permutation at the same time.
|
* pbox permutation at the same time.
|
||||||
*/
|
*/
|
||||||
f = psbox[0][m_sbox[0][r48l >> 12]]
|
f = psbox[0][m_sbox[0][r48l >> 12]]
|
||||||
| psbox[1][m_sbox[1][r48l & 0xfff]]
|
| psbox[1][m_sbox[1][r48l & 0xfff]]
|
||||||
@ -660,8 +660,8 @@ px_crypt_des(const char *key, const char *setting)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the key, shifting each character up by one bit and padding
|
* Copy the key, shifting each character up by one bit and padding with
|
||||||
* with zeros.
|
* zeros.
|
||||||
*/
|
*/
|
||||||
q = (uint8 *) keybuf;
|
q = (uint8 *) keybuf;
|
||||||
while (q - (uint8 *) keybuf - 8)
|
while (q - (uint8 *) keybuf - 8)
|
||||||
@ -706,10 +706,10 @@ px_crypt_des(const char *key, const char *setting)
|
|||||||
strncpy(output, setting, 9);
|
strncpy(output, setting, 9);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Double check that we weren't given a short setting. If we were,
|
* Double check that we weren't given a short setting. If we were, the
|
||||||
* the above code will probably have created wierd values for
|
* above code will probably have created wierd values for count and
|
||||||
* count and salt, but we don't really care. Just make sure the
|
* salt, but we don't really care. Just make sure the output string
|
||||||
* output string doesn't have an extra NUL in it.
|
* doesn't have an extra NUL in it.
|
||||||
*/
|
*/
|
||||||
output[9] = '\0';
|
output[9] = '\0';
|
||||||
p = output + strlen(output);
|
p = output + strlen(output);
|
||||||
@ -728,9 +728,9 @@ px_crypt_des(const char *key, const char *setting)
|
|||||||
output[0] = setting[0];
|
output[0] = setting[0];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the encrypted password that the salt was extracted from is
|
* If the encrypted password that the salt was extracted from is only
|
||||||
* only 1 character long, the salt will be corrupted. We need to
|
* 1 character long, the salt will be corrupted. We need to ensure
|
||||||
* ensure that the output string doesn't have an extra NUL in it!
|
* that the output string doesn't have an extra NUL in it!
|
||||||
*/
|
*/
|
||||||
output[1] = setting[1] ? setting[1] : output[0];
|
output[1] = setting[1] ? setting[1] : output[0];
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ unsigned char _crypt_itoa64[64 + 1] =
|
|||||||
|
|
||||||
char *
|
char *
|
||||||
_crypt_gensalt_traditional_rn(unsigned long count,
|
_crypt_gensalt_traditional_rn(unsigned long count,
|
||||||
const char *input, int size, char *output, int output_size)
|
const char *input, int size, char *output, int output_size)
|
||||||
{
|
{
|
||||||
if (size < 2 || output_size < 2 + 1 || (count && count != 25))
|
if (size < 2 || output_size < 2 + 1 || (count && count != 25))
|
||||||
{
|
{
|
||||||
@ -40,7 +40,7 @@ _crypt_gensalt_traditional_rn(unsigned long count,
|
|||||||
|
|
||||||
char *
|
char *
|
||||||
_crypt_gensalt_extended_rn(unsigned long count,
|
_crypt_gensalt_extended_rn(unsigned long count,
|
||||||
const char *input, int size, char *output, int output_size)
|
const char *input, int size, char *output, int output_size)
|
||||||
{
|
{
|
||||||
unsigned long value;
|
unsigned long value;
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ _crypt_gensalt_extended_rn(unsigned long count,
|
|||||||
|
|
||||||
char *
|
char *
|
||||||
_crypt_gensalt_md5_rn(unsigned long count,
|
_crypt_gensalt_md5_rn(unsigned long count,
|
||||||
const char *input, int size, char *output, int output_size)
|
const char *input, int size, char *output, int output_size)
|
||||||
{
|
{
|
||||||
unsigned long value;
|
unsigned long value;
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ BF_encode(char *dst, const BF_word * src, int size)
|
|||||||
|
|
||||||
char *
|
char *
|
||||||
_crypt_gensalt_blowfish_rn(unsigned long count,
|
_crypt_gensalt_blowfish_rn(unsigned long count,
|
||||||
const char *input, int size, char *output, int output_size)
|
const char *input, int size, char *output, int output_size)
|
||||||
{
|
{
|
||||||
if (size < 16 || output_size < 7 + 22 + 1 ||
|
if (size < 16 || output_size < 7 + 22 + 1 ||
|
||||||
(count && (count < 4 || count > 31)))
|
(count && (count < 4 || count > 31)))
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* $FreeBSD: src/lib/libcrypt/crypt-md5.c,v 1.5 1999/12/17 20:21:45 peter Exp $
|
* $FreeBSD: src/lib/libcrypt/crypt-md5.c,v 1.5 1999/12/17 20:21:45 peter Exp $
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/crypt-md5.c,v 1.5 2005/09/24 19:14:04 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/crypt-md5.c,v 1.6 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -24,9 +24,9 @@
|
|||||||
char *
|
char *
|
||||||
px_crypt_md5(const char *pw, const char *salt, char *passwd, unsigned dstlen)
|
px_crypt_md5(const char *pw, const char *salt, char *passwd, unsigned dstlen)
|
||||||
{
|
{
|
||||||
static char *magic = "$1$"; /* This string is magic for this
|
static char *magic = "$1$"; /* This string is magic for this algorithm.
|
||||||
* algorithm. Having it this way, we can
|
* Having it this way, we can get get better
|
||||||
* get get better later on */
|
* later on */
|
||||||
static char *p;
|
static char *p;
|
||||||
static const char *sp,
|
static const char *sp,
|
||||||
*ep;
|
*ep;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.4 2005/07/18 17:12:54 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.5 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -45,14 +45,14 @@
|
|||||||
* following references:
|
* following references:
|
||||||
*
|
*
|
||||||
* http://en.wikipedia.org/wiki/Fortuna_(PRNG)
|
* http://en.wikipedia.org/wiki/Fortuna_(PRNG)
|
||||||
* - Wikipedia article
|
* - Wikipedia article
|
||||||
* http://jlcooke.ca/random/
|
* http://jlcooke.ca/random/
|
||||||
* - Jean-Luc Cooke Fortuna-based /dev/random driver for Linux.
|
* - Jean-Luc Cooke Fortuna-based /dev/random driver for Linux.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There is some confusion about whether and how to carry forward
|
* There is some confusion about whether and how to carry forward
|
||||||
* the state of the pools. Seems like original Fortuna does not
|
* the state of the pools. Seems like original Fortuna does not
|
||||||
* do it, resetting hash after each request. I guess expecting
|
* do it, resetting hash after each request. I guess expecting
|
||||||
* feeding to happen more often that requesting. This is absolutely
|
* feeding to happen more often that requesting. This is absolutely
|
||||||
* unsuitable for pgcrypto, as nothing asynchronous happens here.
|
* unsuitable for pgcrypto, as nothing asynchronous happens here.
|
||||||
@ -76,7 +76,7 @@
|
|||||||
* How many pools.
|
* How many pools.
|
||||||
*
|
*
|
||||||
* Original Fortuna uses 32 pools, that means 32'th pool is
|
* Original Fortuna uses 32 pools, that means 32'th pool is
|
||||||
* used not earlier than in 13th year. This is a waste in
|
* used not earlier than in 13th year. This is a waste in
|
||||||
* pgcrypto, as we have very low-frequancy seeding. Here
|
* pgcrypto, as we have very low-frequancy seeding. Here
|
||||||
* is preferable to have all entropy usable in reasonable time.
|
* is preferable to have all entropy usable in reasonable time.
|
||||||
*
|
*
|
||||||
@ -89,7 +89,7 @@
|
|||||||
#define NUM_POOLS 23
|
#define NUM_POOLS 23
|
||||||
|
|
||||||
/* in microseconds */
|
/* in microseconds */
|
||||||
#define RESEED_INTERVAL 100000 /* 0.1 sec */
|
#define RESEED_INTERVAL 100000 /* 0.1 sec */
|
||||||
|
|
||||||
/* for one big request, reseed after this many bytes */
|
/* for one big request, reseed after this many bytes */
|
||||||
#define RESEED_BYTES (1024*1024)
|
#define RESEED_BYTES (1024*1024)
|
||||||
@ -114,17 +114,18 @@
|
|||||||
#define MD_CTX SHA256_CTX
|
#define MD_CTX SHA256_CTX
|
||||||
#define CIPH_CTX rijndael_ctx
|
#define CIPH_CTX rijndael_ctx
|
||||||
|
|
||||||
struct fortuna_state {
|
struct fortuna_state
|
||||||
uint8 counter[CIPH_BLOCK];
|
{
|
||||||
uint8 result[CIPH_BLOCK];
|
uint8 counter[CIPH_BLOCK];
|
||||||
uint8 key[BLOCK];
|
uint8 result[CIPH_BLOCK];
|
||||||
MD_CTX pool[NUM_POOLS];
|
uint8 key[BLOCK];
|
||||||
CIPH_CTX ciph;
|
MD_CTX pool[NUM_POOLS];
|
||||||
unsigned reseed_count;
|
CIPH_CTX ciph;
|
||||||
struct timeval last_reseed_time;
|
unsigned reseed_count;
|
||||||
unsigned pool0_bytes;
|
struct timeval last_reseed_time;
|
||||||
unsigned rnd_pos;
|
unsigned pool0_bytes;
|
||||||
int counter_init;
|
unsigned rnd_pos;
|
||||||
|
int counter_init;
|
||||||
};
|
};
|
||||||
typedef struct fortuna_state FState;
|
typedef struct fortuna_state FState;
|
||||||
|
|
||||||
@ -137,29 +138,35 @@ typedef struct fortuna_state FState;
|
|||||||
* - No memory allocations.
|
* - No memory allocations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void ciph_init(CIPH_CTX *ctx, const uint8 *key, int klen)
|
static void
|
||||||
|
ciph_init(CIPH_CTX * ctx, const uint8 *key, int klen)
|
||||||
{
|
{
|
||||||
rijndael_set_key(ctx, (const uint32 *)key, klen, 1);
|
rijndael_set_key(ctx, (const uint32 *) key, klen, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ciph_encrypt(CIPH_CTX *ctx, const uint8 *in, uint8 *out)
|
static void
|
||||||
|
ciph_encrypt(CIPH_CTX * ctx, const uint8 *in, uint8 *out)
|
||||||
{
|
{
|
||||||
rijndael_encrypt(ctx, (const uint32 *)in, (uint32 *)out);
|
rijndael_encrypt(ctx, (const uint32 *) in, (uint32 *) out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void md_init(MD_CTX *ctx)
|
static void
|
||||||
|
md_init(MD_CTX * ctx)
|
||||||
{
|
{
|
||||||
SHA256_Init(ctx);
|
SHA256_Init(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void md_update(MD_CTX *ctx, const uint8 *data, int len)
|
static void
|
||||||
|
md_update(MD_CTX * ctx, const uint8 *data, int len)
|
||||||
{
|
{
|
||||||
SHA256_Update(ctx, data, len);
|
SHA256_Update(ctx, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void md_result(MD_CTX *ctx, uint8 *dst)
|
static void
|
||||||
|
md_result(MD_CTX * ctx, uint8 *dst)
|
||||||
{
|
{
|
||||||
SHA256_CTX tmp;
|
SHA256_CTX tmp;
|
||||||
|
|
||||||
memcpy(&tmp, ctx, sizeof(*ctx));
|
memcpy(&tmp, ctx, sizeof(*ctx));
|
||||||
SHA256_Final(dst, &tmp);
|
SHA256_Final(dst, &tmp);
|
||||||
memset(&tmp, 0, sizeof(tmp));
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
@ -168,9 +175,11 @@ static void md_result(MD_CTX *ctx, uint8 *dst)
|
|||||||
/*
|
/*
|
||||||
* initialize state
|
* initialize state
|
||||||
*/
|
*/
|
||||||
static void init_state(FState *st)
|
static void
|
||||||
|
init_state(FState * st)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset(st, 0, sizeof(*st));
|
memset(st, 0, sizeof(*st));
|
||||||
for (i = 0; i < NUM_POOLS; i++)
|
for (i = 0; i < NUM_POOLS; i++)
|
||||||
md_init(&st->pool[i]);
|
md_init(&st->pool[i]);
|
||||||
@ -180,9 +189,11 @@ static void init_state(FState *st)
|
|||||||
* Endianess does not matter.
|
* Endianess does not matter.
|
||||||
* It just needs to change without repeating.
|
* It just needs to change without repeating.
|
||||||
*/
|
*/
|
||||||
static void inc_counter(FState *st)
|
static void
|
||||||
|
inc_counter(FState * st)
|
||||||
{
|
{
|
||||||
uint32 *val = (uint32*)st->counter;
|
uint32 *val = (uint32 *) st->counter;
|
||||||
|
|
||||||
if (++val[0])
|
if (++val[0])
|
||||||
return;
|
return;
|
||||||
if (++val[1])
|
if (++val[1])
|
||||||
@ -195,7 +206,8 @@ static void inc_counter(FState *st)
|
|||||||
/*
|
/*
|
||||||
* This is called 'cipher in counter mode'.
|
* This is called 'cipher in counter mode'.
|
||||||
*/
|
*/
|
||||||
static void encrypt_counter(FState *st, uint8 *dst)
|
static void
|
||||||
|
encrypt_counter(FState * st, uint8 *dst)
|
||||||
{
|
{
|
||||||
ciph_encrypt(&st->ciph, st->counter, dst);
|
ciph_encrypt(&st->ciph, st->counter, dst);
|
||||||
inc_counter(st);
|
inc_counter(st);
|
||||||
@ -206,9 +218,10 @@ static void encrypt_counter(FState *st, uint8 *dst)
|
|||||||
* The time between reseed must be at least RESEED_INTERVAL
|
* The time between reseed must be at least RESEED_INTERVAL
|
||||||
* microseconds.
|
* microseconds.
|
||||||
*/
|
*/
|
||||||
static int too_often(FState *st)
|
static int
|
||||||
|
too_often(FState * st)
|
||||||
{
|
{
|
||||||
int ok;
|
int ok;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timeval *last = &st->last_reseed_time;
|
struct timeval *last = &st->last_reseed_time;
|
||||||
|
|
||||||
@ -229,19 +242,19 @@ static int too_often(FState *st)
|
|||||||
/*
|
/*
|
||||||
* generate new key from all the pools
|
* generate new key from all the pools
|
||||||
*/
|
*/
|
||||||
static void reseed(FState *st)
|
static void
|
||||||
|
reseed(FState * st)
|
||||||
{
|
{
|
||||||
unsigned k;
|
unsigned k;
|
||||||
unsigned n;
|
unsigned n;
|
||||||
MD_CTX key_md;
|
MD_CTX key_md;
|
||||||
uint8 buf[BLOCK];
|
uint8 buf[BLOCK];
|
||||||
|
|
||||||
/* set pool as empty */
|
/* set pool as empty */
|
||||||
st->pool0_bytes = 0;
|
st->pool0_bytes = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Both #0 and #1 reseed would use only pool 0.
|
* Both #0 and #1 reseed would use only pool 0. Just skip #0 then.
|
||||||
* Just skip #0 then.
|
|
||||||
*/
|
*/
|
||||||
n = ++st->reseed_count;
|
n = ++st->reseed_count;
|
||||||
|
|
||||||
@ -249,7 +262,8 @@ static void reseed(FState *st)
|
|||||||
* The goal: use k-th pool only 1/(2^k) of the time.
|
* The goal: use k-th pool only 1/(2^k) of the time.
|
||||||
*/
|
*/
|
||||||
md_init(&key_md);
|
md_init(&key_md);
|
||||||
for (k = 0; k < NUM_POOLS; k++) {
|
for (k = 0; k < NUM_POOLS; k++)
|
||||||
|
{
|
||||||
md_result(&st->pool[k], buf);
|
md_result(&st->pool[k], buf);
|
||||||
md_update(&key_md, buf, BLOCK);
|
md_update(&key_md, buf, BLOCK);
|
||||||
|
|
||||||
@ -272,11 +286,12 @@ static void reseed(FState *st)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pick a random pool. This uses key bytes as random source.
|
* Pick a random pool. This uses key bytes as random source.
|
||||||
*/
|
*/
|
||||||
static unsigned get_rand_pool(FState *st)
|
static unsigned
|
||||||
|
get_rand_pool(FState * st)
|
||||||
{
|
{
|
||||||
unsigned rnd;
|
unsigned rnd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This slightly prefers lower pools - thats OK.
|
* This slightly prefers lower pools - thats OK.
|
||||||
@ -293,11 +308,12 @@ static unsigned get_rand_pool(FState *st)
|
|||||||
/*
|
/*
|
||||||
* update pools
|
* update pools
|
||||||
*/
|
*/
|
||||||
static void add_entropy(FState *st, const uint8 *data, unsigned len)
|
static void
|
||||||
|
add_entropy(FState * st, const uint8 *data, unsigned len)
|
||||||
{
|
{
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
uint8 hash[BLOCK];
|
uint8 hash[BLOCK];
|
||||||
MD_CTX md;
|
MD_CTX md;
|
||||||
|
|
||||||
/* hash given data */
|
/* hash given data */
|
||||||
md_init(&md);
|
md_init(&md);
|
||||||
@ -305,14 +321,13 @@ static void add_entropy(FState *st, const uint8 *data, unsigned len)
|
|||||||
md_result(&md, hash);
|
md_result(&md, hash);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure the pool 0 is initialized,
|
* Make sure the pool 0 is initialized, then update randomly.
|
||||||
* then update randomly.
|
|
||||||
*/
|
*/
|
||||||
if (st->reseed_count == 0 && st->pool0_bytes < POOL0_FILL)
|
if (st->reseed_count == 0 && st->pool0_bytes < POOL0_FILL)
|
||||||
pos = 0;
|
pos = 0;
|
||||||
else
|
else
|
||||||
pos = get_rand_pool(st);
|
pos = get_rand_pool(st);
|
||||||
md_update( &st->pool[pos], hash, BLOCK);
|
md_update(&st->pool[pos], hash, BLOCK);
|
||||||
|
|
||||||
if (pos == 0)
|
if (pos == 0)
|
||||||
st->pool0_bytes += len;
|
st->pool0_bytes += len;
|
||||||
@ -324,7 +339,8 @@ static void add_entropy(FState *st, const uint8 *data, unsigned len)
|
|||||||
/*
|
/*
|
||||||
* Just take 2 next blocks as new key
|
* Just take 2 next blocks as new key
|
||||||
*/
|
*/
|
||||||
static void rekey(FState *st)
|
static void
|
||||||
|
rekey(FState * st)
|
||||||
{
|
{
|
||||||
encrypt_counter(st, st->key);
|
encrypt_counter(st, st->key);
|
||||||
encrypt_counter(st, st->key + CIPH_BLOCK);
|
encrypt_counter(st, st->key + CIPH_BLOCK);
|
||||||
@ -336,7 +352,8 @@ static void rekey(FState *st)
|
|||||||
* In case it does not, slow down the attacker by initialising
|
* In case it does not, slow down the attacker by initialising
|
||||||
* the couter to random value.
|
* the couter to random value.
|
||||||
*/
|
*/
|
||||||
static void init_counter(FState *st)
|
static void
|
||||||
|
init_counter(FState * st)
|
||||||
{
|
{
|
||||||
/* Use next block as counter. */
|
/* Use next block as counter. */
|
||||||
encrypt_counter(st, st->counter);
|
encrypt_counter(st, st->counter);
|
||||||
@ -348,10 +365,11 @@ static void init_counter(FState *st)
|
|||||||
st->counter_init = 1;
|
st->counter_init = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void extract_data(FState *st, unsigned count, uint8 *dst)
|
static void
|
||||||
|
extract_data(FState * st, unsigned count, uint8 *dst)
|
||||||
{
|
{
|
||||||
unsigned n;
|
unsigned n;
|
||||||
unsigned block_nr = 0;
|
unsigned block_nr = 0;
|
||||||
|
|
||||||
/* Can we reseed? */
|
/* Can we reseed? */
|
||||||
if (st->pool0_bytes >= POOL0_FILL && !too_often(st))
|
if (st->pool0_bytes >= POOL0_FILL && !too_often(st))
|
||||||
@ -361,7 +379,8 @@ static void extract_data(FState *st, unsigned count, uint8 *dst)
|
|||||||
if (!st->counter_init)
|
if (!st->counter_init)
|
||||||
init_counter(st);
|
init_counter(st);
|
||||||
|
|
||||||
while (count > 0) {
|
while (count > 0)
|
||||||
|
{
|
||||||
/* produce bytes */
|
/* produce bytes */
|
||||||
encrypt_counter(st, st->result);
|
encrypt_counter(st, st->result);
|
||||||
|
|
||||||
@ -391,9 +410,10 @@ static void extract_data(FState *st, unsigned count, uint8 *dst)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static FState main_state;
|
static FState main_state;
|
||||||
static int init_done = 0;
|
static int init_done = 0;
|
||||||
|
|
||||||
void fortuna_add_entropy(const uint8 *data, unsigned len)
|
void
|
||||||
|
fortuna_add_entropy(const uint8 *data, unsigned len)
|
||||||
{
|
{
|
||||||
if (!init_done)
|
if (!init_done)
|
||||||
{
|
{
|
||||||
@ -405,7 +425,8 @@ void fortuna_add_entropy(const uint8 *data, unsigned len)
|
|||||||
add_entropy(&main_state, data, len);
|
add_entropy(&main_state, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fortuna_get_bytes(unsigned len, uint8 *dst)
|
void
|
||||||
|
fortuna_get_bytes(unsigned len, uint8 *dst)
|
||||||
{
|
{
|
||||||
if (!init_done)
|
if (!init_done)
|
||||||
{
|
{
|
||||||
@ -416,4 +437,3 @@ void fortuna_get_bytes(unsigned len, uint8 *dst)
|
|||||||
return;
|
return;
|
||||||
extract_data(&main_state, len, dst);
|
extract_data(&main_state, len, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,14 +26,13 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.h,v 1.2 2005/07/18 17:12:54 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.h,v 1.3 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __FORTUNA_H
|
#ifndef __FORTUNA_H
|
||||||
#define __FORTUNA_H
|
#define __FORTUNA_H
|
||||||
|
|
||||||
void fortuna_get_bytes(unsigned len, uint8 *dst);
|
void fortuna_get_bytes(unsigned len, uint8 *dst);
|
||||||
void fortuna_add_entropy(const uint8 *data, unsigned len);
|
void fortuna_add_entropy(const uint8 *data, unsigned len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.22 2005/07/18 17:12:54 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.23 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -52,7 +52,7 @@
|
|||||||
/*
|
/*
|
||||||
* The chance is x/256 that the reseed happens.
|
* The chance is x/256 that the reseed happens.
|
||||||
*/
|
*/
|
||||||
#define SYSTEM_RESEED_CHANCE (4) /* 256/4 * 10min ~ 10h */
|
#define SYSTEM_RESEED_CHANCE (4) /* 256/4 * 10min ~ 10h */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this much time has passed, force reseed.
|
* If this much time has passed, force reseed.
|
||||||
@ -88,13 +88,13 @@ struct int_digest
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct int_digest
|
static const struct int_digest
|
||||||
int_digest_list[] = {
|
int_digest_list[] = {
|
||||||
{ "md5", init_md5 },
|
{"md5", init_md5},
|
||||||
{ "sha1", init_sha1 },
|
{"sha1", init_sha1},
|
||||||
{ "sha256", init_sha256 },
|
{"sha256", init_sha256},
|
||||||
{ "sha384", init_sha384 },
|
{"sha384", init_sha384},
|
||||||
{ "sha512", init_sha512 },
|
{"sha512", init_sha512},
|
||||||
{ NULL, NULL }
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* MD5 */
|
/* MD5 */
|
||||||
@ -210,7 +210,7 @@ int_sha256_block_len(PX_MD * h)
|
|||||||
static void
|
static void
|
||||||
int_sha256_update(PX_MD * h, const uint8 *data, unsigned dlen)
|
int_sha256_update(PX_MD * h, const uint8 *data, unsigned dlen)
|
||||||
{
|
{
|
||||||
SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
|
SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
|
||||||
|
|
||||||
SHA256_Update(ctx, data, dlen);
|
SHA256_Update(ctx, data, dlen);
|
||||||
}
|
}
|
||||||
@ -218,7 +218,7 @@ int_sha256_update(PX_MD * h, const uint8 *data, unsigned dlen)
|
|||||||
static void
|
static void
|
||||||
int_sha256_reset(PX_MD * h)
|
int_sha256_reset(PX_MD * h)
|
||||||
{
|
{
|
||||||
SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
|
SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
|
||||||
|
|
||||||
SHA256_Init(ctx);
|
SHA256_Init(ctx);
|
||||||
}
|
}
|
||||||
@ -226,7 +226,7 @@ int_sha256_reset(PX_MD * h)
|
|||||||
static void
|
static void
|
||||||
int_sha256_finish(PX_MD * h, uint8 *dst)
|
int_sha256_finish(PX_MD * h, uint8 *dst)
|
||||||
{
|
{
|
||||||
SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
|
SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
|
||||||
|
|
||||||
SHA256_Final(dst, ctx);
|
SHA256_Final(dst, ctx);
|
||||||
}
|
}
|
||||||
@ -234,12 +234,13 @@ int_sha256_finish(PX_MD * h, uint8 *dst)
|
|||||||
static void
|
static void
|
||||||
int_sha256_free(PX_MD * h)
|
int_sha256_free(PX_MD * h)
|
||||||
{
|
{
|
||||||
SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
|
SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
|
||||||
|
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
px_free(ctx);
|
px_free(ctx);
|
||||||
px_free(h);
|
px_free(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SHA384 */
|
/* SHA384 */
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
@ -257,7 +258,7 @@ int_sha384_block_len(PX_MD * h)
|
|||||||
static void
|
static void
|
||||||
int_sha384_update(PX_MD * h, const uint8 *data, unsigned dlen)
|
int_sha384_update(PX_MD * h, const uint8 *data, unsigned dlen)
|
||||||
{
|
{
|
||||||
SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
|
SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
|
||||||
|
|
||||||
SHA384_Update(ctx, data, dlen);
|
SHA384_Update(ctx, data, dlen);
|
||||||
}
|
}
|
||||||
@ -265,7 +266,7 @@ int_sha384_update(PX_MD * h, const uint8 *data, unsigned dlen)
|
|||||||
static void
|
static void
|
||||||
int_sha384_reset(PX_MD * h)
|
int_sha384_reset(PX_MD * h)
|
||||||
{
|
{
|
||||||
SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
|
SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
|
||||||
|
|
||||||
SHA384_Init(ctx);
|
SHA384_Init(ctx);
|
||||||
}
|
}
|
||||||
@ -273,7 +274,7 @@ int_sha384_reset(PX_MD * h)
|
|||||||
static void
|
static void
|
||||||
int_sha384_finish(PX_MD * h, uint8 *dst)
|
int_sha384_finish(PX_MD * h, uint8 *dst)
|
||||||
{
|
{
|
||||||
SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
|
SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
|
||||||
|
|
||||||
SHA384_Final(dst, ctx);
|
SHA384_Final(dst, ctx);
|
||||||
}
|
}
|
||||||
@ -281,7 +282,7 @@ int_sha384_finish(PX_MD * h, uint8 *dst)
|
|||||||
static void
|
static void
|
||||||
int_sha384_free(PX_MD * h)
|
int_sha384_free(PX_MD * h)
|
||||||
{
|
{
|
||||||
SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
|
SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
|
||||||
|
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
px_free(ctx);
|
px_free(ctx);
|
||||||
@ -305,7 +306,7 @@ int_sha512_block_len(PX_MD * h)
|
|||||||
static void
|
static void
|
||||||
int_sha512_update(PX_MD * h, const uint8 *data, unsigned dlen)
|
int_sha512_update(PX_MD * h, const uint8 *data, unsigned dlen)
|
||||||
{
|
{
|
||||||
SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
|
SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
|
||||||
|
|
||||||
SHA512_Update(ctx, data, dlen);
|
SHA512_Update(ctx, data, dlen);
|
||||||
}
|
}
|
||||||
@ -313,7 +314,7 @@ int_sha512_update(PX_MD * h, const uint8 *data, unsigned dlen)
|
|||||||
static void
|
static void
|
||||||
int_sha512_reset(PX_MD * h)
|
int_sha512_reset(PX_MD * h)
|
||||||
{
|
{
|
||||||
SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
|
SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
|
||||||
|
|
||||||
SHA512_Init(ctx);
|
SHA512_Init(ctx);
|
||||||
}
|
}
|
||||||
@ -321,7 +322,7 @@ int_sha512_reset(PX_MD * h)
|
|||||||
static void
|
static void
|
||||||
int_sha512_finish(PX_MD * h, uint8 *dst)
|
int_sha512_finish(PX_MD * h, uint8 *dst)
|
||||||
{
|
{
|
||||||
SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
|
SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
|
||||||
|
|
||||||
SHA512_Final(dst, ctx);
|
SHA512_Final(dst, ctx);
|
||||||
}
|
}
|
||||||
@ -329,7 +330,7 @@ int_sha512_finish(PX_MD * h, uint8 *dst)
|
|||||||
static void
|
static void
|
||||||
int_sha512_free(PX_MD * h)
|
int_sha512_free(PX_MD * h)
|
||||||
{
|
{
|
||||||
SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
|
SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
|
||||||
|
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
px_free(ctx);
|
px_free(ctx);
|
||||||
@ -381,7 +382,7 @@ init_sha1(PX_MD * md)
|
|||||||
static void
|
static void
|
||||||
init_sha256(PX_MD * md)
|
init_sha256(PX_MD * md)
|
||||||
{
|
{
|
||||||
SHA256_CTX *ctx;
|
SHA256_CTX *ctx;
|
||||||
|
|
||||||
ctx = px_alloc(sizeof(*ctx));
|
ctx = px_alloc(sizeof(*ctx));
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
@ -401,7 +402,7 @@ init_sha256(PX_MD * md)
|
|||||||
static void
|
static void
|
||||||
init_sha384(PX_MD * md)
|
init_sha384(PX_MD * md)
|
||||||
{
|
{
|
||||||
SHA384_CTX *ctx;
|
SHA384_CTX *ctx;
|
||||||
|
|
||||||
ctx = px_alloc(sizeof(*ctx));
|
ctx = px_alloc(sizeof(*ctx));
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
@ -421,7 +422,7 @@ init_sha384(PX_MD * md)
|
|||||||
static void
|
static void
|
||||||
init_sha512(PX_MD * md)
|
init_sha512(PX_MD * md)
|
||||||
{
|
{
|
||||||
SHA512_CTX *ctx;
|
SHA512_CTX *ctx;
|
||||||
|
|
||||||
ctx = px_alloc(sizeof(*ctx));
|
ctx = px_alloc(sizeof(*ctx));
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
@ -752,12 +753,12 @@ struct int_cipher
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct int_cipher
|
static const struct int_cipher
|
||||||
int_ciphers[] = {
|
int_ciphers[] = {
|
||||||
{ "bf-cbc", bf_cbc_load },
|
{"bf-cbc", bf_cbc_load},
|
||||||
{ "bf-ecb", bf_ecb_load },
|
{"bf-ecb", bf_ecb_load},
|
||||||
{ "aes-128-cbc", rj_128_cbc },
|
{"aes-128-cbc", rj_128_cbc},
|
||||||
{ "aes-128-ecb", rj_128_ecb },
|
{"aes-128-ecb", rj_128_ecb},
|
||||||
{ NULL, NULL }
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const PX_Alias int_aliases[] = {
|
static const PX_Alias int_aliases[] = {
|
||||||
@ -828,7 +829,7 @@ px_find_cipher(const char *name, PX_Cipher ** res)
|
|||||||
int
|
int
|
||||||
px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
|
px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
*dst++ = random();
|
*dst++ = random();
|
||||||
@ -838,12 +839,13 @@ px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
|
|||||||
static time_t seed_time = 0;
|
static time_t seed_time = 0;
|
||||||
static time_t check_time = 0;
|
static time_t check_time = 0;
|
||||||
|
|
||||||
static void system_reseed(void)
|
static void
|
||||||
|
system_reseed(void)
|
||||||
{
|
{
|
||||||
uint8 buf[1024];
|
uint8 buf[1024];
|
||||||
int n;
|
int n;
|
||||||
time_t t;
|
time_t t;
|
||||||
int skip = 1;
|
int skip = 1;
|
||||||
|
|
||||||
t = time(NULL);
|
t = time(NULL);
|
||||||
|
|
||||||
@ -890,4 +892,3 @@ px_add_entropy(const uint8 *data, unsigned count)
|
|||||||
fortuna_add_entropy(data, count);
|
fortuna_add_entropy(data, count);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/mbuf.c,v 1.2 2005/07/11 15:07:59 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/mbuf.c,v 1.3 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -166,7 +166,8 @@ mbuf_grab(MBuf * mbuf, int len, uint8 **data_p)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbuf_rewind(MBuf *mbuf)
|
int
|
||||||
|
mbuf_rewind(MBuf * mbuf)
|
||||||
{
|
{
|
||||||
mbuf->read_pos = mbuf->data;
|
mbuf->read_pos = mbuf->data;
|
||||||
return 0;
|
return 0;
|
||||||
@ -175,7 +176,7 @@ int mbuf_rewind(MBuf *mbuf)
|
|||||||
int
|
int
|
||||||
mbuf_steal_data(MBuf * mbuf, uint8 **data_p)
|
mbuf_steal_data(MBuf * mbuf, uint8 **data_p)
|
||||||
{
|
{
|
||||||
int len = mbuf_size(mbuf);
|
int len = mbuf_size(mbuf);
|
||||||
|
|
||||||
mbuf->no_write = 1;
|
mbuf->no_write = 1;
|
||||||
mbuf->own_data = 0;
|
mbuf->own_data = 0;
|
||||||
@ -193,7 +194,7 @@ mbuf_steal_data(MBuf * mbuf, uint8 **data_p)
|
|||||||
|
|
||||||
struct PullFilter
|
struct PullFilter
|
||||||
{
|
{
|
||||||
PullFilter *src;
|
PullFilter *src;
|
||||||
const PullFilterOps *op;
|
const PullFilterOps *op;
|
||||||
int buflen;
|
int buflen;
|
||||||
uint8 *buf;
|
uint8 *buf;
|
||||||
@ -204,7 +205,7 @@ struct PullFilter
|
|||||||
int
|
int
|
||||||
pullf_create(PullFilter ** pf_p, const PullFilterOps * op, void *init_arg, PullFilter * src)
|
pullf_create(PullFilter ** pf_p, const PullFilterOps * op, void *init_arg, PullFilter * src)
|
||||||
{
|
{
|
||||||
PullFilter *pf;
|
PullFilter *pf;
|
||||||
void *priv;
|
void *priv;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
@ -260,13 +261,14 @@ pullf_free(PullFilter * pf)
|
|||||||
int
|
int
|
||||||
pullf_read(PullFilter * pf, int len, uint8 **data_p)
|
pullf_read(PullFilter * pf, int len, uint8 **data_p)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (pf->op->pull)
|
if (pf->op->pull)
|
||||||
{
|
{
|
||||||
if (pf->buflen && len > pf->buflen)
|
if (pf->buflen && len > pf->buflen)
|
||||||
len = pf->buflen;
|
len = pf->buflen;
|
||||||
res = pf->op->pull(pf->priv, pf->src, len, data_p,
|
res = pf->op->pull(pf->priv, pf->src, len, data_p,
|
||||||
pf->buf, pf->buflen);
|
pf->buf, pf->buflen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res = pullf_read(pf->src, len, data_p);
|
res = pullf_read(pf->src, len, data_p);
|
||||||
@ -276,8 +278,9 @@ pullf_read(PullFilter * pf, int len, uint8 **data_p)
|
|||||||
int
|
int
|
||||||
pullf_read_max(PullFilter * pf, int len, uint8 **data_p, uint8 *tmpbuf)
|
pullf_read_max(PullFilter * pf, int len, uint8 **data_p, uint8 *tmpbuf)
|
||||||
{
|
{
|
||||||
int res, total;
|
int res,
|
||||||
uint8 *tmp;
|
total;
|
||||||
|
uint8 *tmp;
|
||||||
|
|
||||||
res = pullf_read(pf, len, data_p);
|
res = pullf_read(pf, len, data_p);
|
||||||
if (res <= 0 || res == len)
|
if (res <= 0 || res == len)
|
||||||
@ -289,7 +292,8 @@ pullf_read_max(PullFilter * pf, int len, uint8 **data_p, uint8 *tmpbuf)
|
|||||||
len -= res;
|
len -= res;
|
||||||
total = res;
|
total = res;
|
||||||
|
|
||||||
while (len > 0) {
|
while (len > 0)
|
||||||
|
{
|
||||||
res = pullf_read(pf, len, &tmp);
|
res = pullf_read(pf, len, &tmp);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
@ -308,10 +312,12 @@ pullf_read_max(PullFilter * pf, int len, uint8 **data_p, uint8 *tmpbuf)
|
|||||||
/*
|
/*
|
||||||
* caller wants exatly len bytes and dont bother with references
|
* caller wants exatly len bytes and dont bother with references
|
||||||
*/
|
*/
|
||||||
int pullf_read_fixed(PullFilter *src, int len, uint8 *dst)
|
int
|
||||||
|
pullf_read_fixed(PullFilter * src, int len, uint8 *dst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
uint8 *p;
|
uint8 *p;
|
||||||
|
|
||||||
res = pullf_read_max(src, len, &p, dst);
|
res = pullf_read_max(src, len, &p, dst);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
@ -330,9 +336,10 @@ int pullf_read_fixed(PullFilter *src, int len, uint8 *dst)
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
pull_from_mbuf(void *arg, PullFilter * src, int len,
|
pull_from_mbuf(void *arg, PullFilter * src, int len,
|
||||||
uint8 **data_p, uint8 *buf, int buflen)
|
uint8 **data_p, uint8 *buf, int buflen)
|
||||||
{
|
{
|
||||||
MBuf *mbuf = arg;
|
MBuf *mbuf = arg;
|
||||||
|
|
||||||
return mbuf_grab(mbuf, len, data_p);
|
return mbuf_grab(mbuf, len, data_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +371,7 @@ struct PushFilter
|
|||||||
int
|
int
|
||||||
pushf_create(PushFilter ** mp_p, const PushFilterOps * op, void *init_arg, PushFilter * next)
|
pushf_create(PushFilter ** mp_p, const PushFilterOps * op, void *init_arg, PushFilter * next)
|
||||||
{
|
{
|
||||||
PushFilter *mp;
|
PushFilter *mp;
|
||||||
void *priv;
|
void *priv;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
@ -419,7 +426,7 @@ pushf_free(PushFilter * mp)
|
|||||||
void
|
void
|
||||||
pushf_free_all(PushFilter * mp)
|
pushf_free_all(PushFilter * mp)
|
||||||
{
|
{
|
||||||
PushFilter *tmp;
|
PushFilter *tmp;
|
||||||
|
|
||||||
while (mp)
|
while (mp)
|
||||||
{
|
{
|
||||||
@ -549,8 +556,8 @@ static const struct PushFilterOps mbuf_filter = {
|
|||||||
NULL, push_into_mbuf, NULL, NULL
|
NULL, push_into_mbuf, NULL, NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
int pushf_create_mbuf_writer(PushFilter **res, MBuf *dst)
|
int
|
||||||
|
pushf_create_mbuf_writer(PushFilter ** res, MBuf * dst)
|
||||||
{
|
{
|
||||||
return pushf_create(res, &mbuf_filter, dst, NULL);
|
return pushf_create(res, &mbuf_filter, dst, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/mbuf.h,v 1.1 2005/07/10 13:46:28 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/mbuf.h,v 1.2 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __PX_MBUF_H
|
#ifndef __PX_MBUF_H
|
||||||
@ -40,32 +40,36 @@ typedef struct PullFilterOps PullFilterOps;
|
|||||||
|
|
||||||
struct PushFilterOps
|
struct PushFilterOps
|
||||||
{
|
{
|
||||||
/* should return needed buffer size, 0- no buffering, <0 on error
|
/*
|
||||||
* if NULL, no buffering, and priv=init_arg
|
* should return needed buffer size, 0- no buffering, <0 on error if NULL,
|
||||||
|
* no buffering, and priv=init_arg
|
||||||
*/
|
*/
|
||||||
int (*init) (PushFilter * next, void *init_arg, void **priv_p);
|
int (*init) (PushFilter * next, void *init_arg, void **priv_p);
|
||||||
/* send data to next. should consume all?
|
|
||||||
* if null, it will be simply copied (in-place)
|
/*
|
||||||
* returns 0 on error
|
* send data to next. should consume all? if null, it will be simply
|
||||||
|
* copied (in-place) returns 0 on error
|
||||||
*/
|
*/
|
||||||
int (*push) (PushFilter * next, void *priv,
|
int (*push) (PushFilter * next, void *priv,
|
||||||
const uint8 *src, int len);
|
const uint8 *src, int len);
|
||||||
int (*flush) (PushFilter * next, void *priv);
|
int (*flush) (PushFilter * next, void *priv);
|
||||||
void (*free) (void *priv);
|
void (*free) (void *priv);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PullFilterOps
|
struct PullFilterOps
|
||||||
{
|
{
|
||||||
/* should return needed buffer size, 0- no buffering, <0 on error
|
/*
|
||||||
* if NULL, no buffering, and priv=init_arg
|
* should return needed buffer size, 0- no buffering, <0 on error if NULL,
|
||||||
|
* no buffering, and priv=init_arg
|
||||||
*/
|
*/
|
||||||
int (*init) (void **priv_p, void *init_arg, PullFilter * src);
|
int (*init) (void **priv_p, void *init_arg, PullFilter * src);
|
||||||
/* request data from src, put result ptr to data_p
|
|
||||||
* can use ptr from src or use buf as work area
|
/*
|
||||||
* if NULL in-place copy
|
* request data from src, put result ptr to data_p can use ptr from src or
|
||||||
|
* use buf as work area if NULL in-place copy
|
||||||
*/
|
*/
|
||||||
int (*pull) (void *priv, PullFilter * src, int len,
|
int (*pull) (void *priv, PullFilter * src, int len,
|
||||||
uint8 **data_p, uint8 *buf, int buflen);
|
uint8 **data_p, uint8 *buf, int buflen);
|
||||||
void (*free) (void *priv);
|
void (*free) (void *priv);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,8 +90,8 @@ int mbuf_free(MBuf * mbuf);
|
|||||||
/*
|
/*
|
||||||
* Push filter
|
* Push filter
|
||||||
*/
|
*/
|
||||||
int pushf_create(PushFilter ** res, const PushFilterOps * ops, void *init_arg,
|
int pushf_create(PushFilter ** res, const PushFilterOps * ops, void *init_arg,
|
||||||
PushFilter * next);
|
PushFilter * next);
|
||||||
int pushf_write(PushFilter * mp, const uint8 *data, int len);
|
int pushf_write(PushFilter * mp, const uint8 *data, int len);
|
||||||
void pushf_free_all(PushFilter * mp);
|
void pushf_free_all(PushFilter * mp);
|
||||||
void pushf_free(PushFilter * mp);
|
void pushf_free(PushFilter * mp);
|
||||||
@ -98,13 +102,13 @@ int pushf_create_mbuf_writer(PushFilter ** mp_p, MBuf * mbuf);
|
|||||||
/*
|
/*
|
||||||
* Pull filter
|
* Pull filter
|
||||||
*/
|
*/
|
||||||
int pullf_create(PullFilter ** res, const PullFilterOps * ops,
|
int pullf_create(PullFilter ** res, const PullFilterOps * ops,
|
||||||
void *init_arg, PullFilter * src);
|
void *init_arg, PullFilter * src);
|
||||||
int pullf_read(PullFilter * mp, int len, uint8 **data_p);
|
int pullf_read(PullFilter * mp, int len, uint8 **data_p);
|
||||||
int pullf_read_max(PullFilter * mp, int len,
|
int pullf_read_max(PullFilter * mp, int len,
|
||||||
uint8 **data_p, uint8 *tmpbuf);
|
uint8 **data_p, uint8 *tmpbuf);
|
||||||
void pullf_free(PullFilter * mp);
|
void pullf_free(PullFilter * mp);
|
||||||
int pullf_read_fixed(PullFilter *src, int len, uint8 *dst);
|
int pullf_read_fixed(PullFilter * src, int len, uint8 *dst);
|
||||||
|
|
||||||
int pullf_create_mbuf_reader(PullFilter ** pf_p, MBuf * mbuf);
|
int pullf_create_mbuf_reader(PullFilter ** pf_p, MBuf * mbuf);
|
||||||
|
|
||||||
@ -118,4 +122,3 @@ int pullf_create_mbuf_reader(PullFilter ** pf_p, MBuf * mbuf);
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#endif /* __PX_MBUF_H */
|
#endif /* __PX_MBUF_H */
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $PostgreSQL: pgsql/contrib/pgcrypto/md5.h,v 1.8 2003/11/29 22:39:28 pgsql Exp $ */
|
/* $PostgreSQL: pgsql/contrib/pgcrypto/md5.h,v 1.9 2005/10/15 02:49:06 momjian Exp $ */
|
||||||
/* $KAME: md5.h,v 1.3 2000/02/22 14:01:18 itojun Exp $ */
|
/* $KAME: md5.h,v 1.3 2000/02/22 14:01:18 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/openssl.c,v 1.25 2005/07/12 20:27:42 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/openssl.c,v 1.26 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -53,8 +53,7 @@
|
|||||||
|
|
||||||
/* Yes, it does. */
|
/* Yes, it does. */
|
||||||
#include <openssl/aes.h>
|
#include <openssl/aes.h>
|
||||||
|
#else /* old OPENSSL */
|
||||||
#else /* old OPENSSL */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No, it does not. So use included rijndael code to emulate it.
|
* No, it does not. So use included rijndael code to emulate it.
|
||||||
@ -91,8 +90,7 @@
|
|||||||
memcpy(iv, (src) + (len) - 16, 16); \
|
memcpy(iv, (src) + (len) - 16, 16); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#endif /* old OPENSSL */
|
||||||
#endif /* old OPENSSL */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compatibility with older OpenSSL API for DES.
|
* Compatibility with older OpenSSL API for DES.
|
||||||
@ -157,8 +155,8 @@ digest_finish(PX_MD * h, uint8 *dst)
|
|||||||
EVP_DigestFinal(ctx, dst, NULL);
|
EVP_DigestFinal(ctx, dst, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some builds of 0.9.7x clear all of ctx in EVP_DigestFinal.
|
* Some builds of 0.9.7x clear all of ctx in EVP_DigestFinal. Fix it by
|
||||||
* Fix it by reinitializing ctx.
|
* reinitializing ctx.
|
||||||
*/
|
*/
|
||||||
EVP_DigestInit(ctx, md);
|
EVP_DigestInit(ctx, md);
|
||||||
}
|
}
|
||||||
@ -246,7 +244,9 @@ typedef struct
|
|||||||
} des;
|
} des;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
DES_key_schedule k1, k2, k3;
|
DES_key_schedule k1,
|
||||||
|
k2,
|
||||||
|
k3;
|
||||||
} des3;
|
} des3;
|
||||||
CAST_KEY cast_key;
|
CAST_KEY cast_key;
|
||||||
AES_KEY aes_key;
|
AES_KEY aes_key;
|
||||||
@ -597,12 +597,12 @@ ossl_aes_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv)
|
|||||||
ossldata *od = c->ptr;
|
ossldata *od = c->ptr;
|
||||||
unsigned bs = gen_ossl_block_size(c);
|
unsigned bs = gen_ossl_block_size(c);
|
||||||
|
|
||||||
if (klen <= 128/8)
|
if (klen <= 128 / 8)
|
||||||
od->klen = 128/8;
|
od->klen = 128 / 8;
|
||||||
else if (klen <= 192/8)
|
else if (klen <= 192 / 8)
|
||||||
od->klen = 192/8;
|
od->klen = 192 / 8;
|
||||||
else if (klen <= 256/8)
|
else if (klen <= 256 / 8)
|
||||||
od->klen = 256/8;
|
od->klen = 256 / 8;
|
||||||
else
|
else
|
||||||
return PXE_KEY_TOO_BIG;
|
return PXE_KEY_TOO_BIG;
|
||||||
|
|
||||||
@ -825,7 +825,8 @@ static int openssl_random_init = 0;
|
|||||||
* OpenSSL random should re-feeded occasionally. From /dev/urandom
|
* OpenSSL random should re-feeded occasionally. From /dev/urandom
|
||||||
* preferably.
|
* preferably.
|
||||||
*/
|
*/
|
||||||
static void init_openssl_rand(void)
|
static void
|
||||||
|
init_openssl_rand(void)
|
||||||
{
|
{
|
||||||
if (RAND_get_rand_method() == NULL)
|
if (RAND_get_rand_method() == NULL)
|
||||||
RAND_set_rand_method(RAND_SSLeay());
|
RAND_set_rand_method(RAND_SSLeay());
|
||||||
@ -871,4 +872,3 @@ px_add_entropy(const uint8 *data, unsigned count)
|
|||||||
RAND_add(data, count, 0);
|
RAND_add(data, count, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgcrypto.c,v 1.19 2005/09/24 19:14:04 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgcrypto.c,v 1.20 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -244,7 +244,7 @@ pg_gen_salt_rounds(PG_FUNCTION_ARGS)
|
|||||||
if (len < 0)
|
if (len < 0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("gen_salt: %s", px_strerror(len))));
|
errmsg("gen_salt: %s", px_strerror(len))));
|
||||||
|
|
||||||
res = (text *) palloc(len + VARHDRSZ);
|
res = (text *) palloc(len + VARHDRSZ);
|
||||||
VARATT_SIZEP(res) = len + VARHDRSZ;
|
VARATT_SIZEP(res) = len + VARHDRSZ;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-armor.c,v 1.2 2005/07/11 15:07:59 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-armor.c,v 1.3 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -40,7 +40,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static const unsigned char _base64[] =
|
static const unsigned char _base64[] =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
static int
|
static int
|
||||||
b64_encode(const uint8 *src, unsigned len, uint8 *dst)
|
b64_encode(const uint8 *src, unsigned len, uint8 *dst)
|
||||||
@ -96,13 +96,13 @@ static int
|
|||||||
b64_decode(const uint8 *src, unsigned len, uint8 *dst)
|
b64_decode(const uint8 *src, unsigned len, uint8 *dst)
|
||||||
{
|
{
|
||||||
const uint8 *srcend = src + len,
|
const uint8 *srcend = src + len,
|
||||||
*s = src;
|
*s = src;
|
||||||
uint8 *p = dst;
|
uint8 *p = dst;
|
||||||
char c;
|
char c;
|
||||||
unsigned b = 0;
|
unsigned b = 0;
|
||||||
unsigned long buf = 0;
|
unsigned long buf = 0;
|
||||||
int pos = 0,
|
int pos = 0,
|
||||||
end = 0;
|
end = 0;
|
||||||
|
|
||||||
while (s < srcend)
|
while (s < srcend)
|
||||||
{
|
{
|
||||||
@ -242,11 +242,13 @@ static const uint8 *
|
|||||||
find_str(const uint8 *data, const uint8 *data_end, const char *str, int strlen)
|
find_str(const uint8 *data, const uint8 *data_end, const char *str, int strlen)
|
||||||
{
|
{
|
||||||
const uint8 *p = data;
|
const uint8 *p = data;
|
||||||
|
|
||||||
if (!strlen)
|
if (!strlen)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (data_end - data < strlen)
|
if (data_end - data < strlen)
|
||||||
return NULL;
|
return NULL;
|
||||||
while (p < data_end) {
|
while (p < data_end)
|
||||||
|
{
|
||||||
p = memchr(p, str[0], data_end - p);
|
p = memchr(p, str[0], data_end - p);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -261,7 +263,7 @@ find_str(const uint8 *data, const uint8 *data_end, const char *str, int strlen)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
find_header(const uint8 *data, const uint8 *datend,
|
find_header(const uint8 *data, const uint8 *datend,
|
||||||
const uint8 **start_p, int is_end)
|
const uint8 **start_p, int is_end)
|
||||||
{
|
{
|
||||||
const uint8 *p = data;
|
const uint8 *p = data;
|
||||||
static const char *start_sep = "-----BEGIN";
|
static const char *start_sep = "-----BEGIN";
|
||||||
@ -285,7 +287,7 @@ find_header(const uint8 *data, const uint8 *datend,
|
|||||||
/* check if header text ok */
|
/* check if header text ok */
|
||||||
for (; p < datend && *p != '-'; p++)
|
for (; p < datend && *p != '-'; p++)
|
||||||
{
|
{
|
||||||
/* various junk can be there, but definitely not line-feed */
|
/* various junk can be there, but definitely not line-feed */
|
||||||
if (*p >= ' ')
|
if (*p >= ' ')
|
||||||
continue;
|
continue;
|
||||||
return PXE_PGP_CORRUPT_ARMOR;
|
return PXE_PGP_CORRUPT_ARMOR;
|
||||||
@ -313,7 +315,8 @@ pgp_armor_decode(const uint8 *src, unsigned len, uint8 *dst)
|
|||||||
const uint8 *p = src;
|
const uint8 *p = src;
|
||||||
const uint8 *data_end = src + len;
|
const uint8 *data_end = src + len;
|
||||||
long crc;
|
long crc;
|
||||||
const uint8 *base64_start, *armor_end;
|
const uint8 *base64_start,
|
||||||
|
*armor_end;
|
||||||
const uint8 *base64_end = NULL;
|
const uint8 *base64_end = NULL;
|
||||||
uint8 buf[4];
|
uint8 buf[4];
|
||||||
int hlen;
|
int hlen;
|
||||||
@ -355,7 +358,7 @@ pgp_armor_decode(const uint8 *src, unsigned len, uint8 *dst)
|
|||||||
/* decode crc */
|
/* decode crc */
|
||||||
if (b64_decode(p + 1, 4, buf) != 3)
|
if (b64_decode(p + 1, 4, buf) != 3)
|
||||||
goto out;
|
goto out;
|
||||||
crc = (((long)buf[0]) << 16) + (((long)buf[1]) << 8) + (long)buf[2];
|
crc = (((long) buf[0]) << 16) + (((long) buf[1]) << 8) + (long) buf[2];
|
||||||
|
|
||||||
/* decode data */
|
/* decode data */
|
||||||
res = b64_decode(base64_start, base64_end - base64_start, dst);
|
res = b64_decode(base64_start, base64_end - base64_start, dst);
|
||||||
@ -378,4 +381,3 @@ pgp_armor_dec_len(unsigned len)
|
|||||||
{
|
{
|
||||||
return b64_dec_len(len);
|
return b64_dec_len(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-cfb.c,v 1.2 2005/07/11 15:07:59 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-cfb.c,v 1.3 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -35,7 +35,7 @@
|
|||||||
#include "px.h"
|
#include "px.h"
|
||||||
#include "pgp.h"
|
#include "pgp.h"
|
||||||
|
|
||||||
typedef int (*mix_data_t)(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst);
|
typedef int (*mix_data_t) (PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst);
|
||||||
|
|
||||||
struct PGP_CFB
|
struct PGP_CFB
|
||||||
{
|
{
|
||||||
@ -50,12 +50,12 @@ struct PGP_CFB
|
|||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len,
|
pgp_cfb_create(PGP_CFB ** ctx_p, int algo, const uint8 *key, int key_len,
|
||||||
int resync, uint8 *iv)
|
int resync, uint8 *iv)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PX_Cipher *ciph;
|
PX_Cipher *ciph;
|
||||||
PGP_CFB *ctx;
|
PGP_CFB *ctx;
|
||||||
|
|
||||||
res = pgp_load_cipher(algo, &ciph);
|
res = pgp_load_cipher(algo, &ciph);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -82,7 +82,7 @@ pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pgp_cfb_free(PGP_CFB *ctx)
|
pgp_cfb_free(PGP_CFB * ctx)
|
||||||
{
|
{
|
||||||
px_cipher_free(ctx->ciph);
|
px_cipher_free(ctx->ciph);
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
@ -90,12 +90,13 @@ pgp_cfb_free(PGP_CFB *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Data processing for normal CFB. (PGP_PKT_SYMENCRYPTED_DATA_MDC)
|
* Data processing for normal CFB. (PGP_PKT_SYMENCRYPTED_DATA_MDC)
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
mix_encrypt_normal(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
mix_encrypt_normal(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = ctx->pos; i < ctx->pos + len; i++)
|
for (i = ctx->pos; i < ctx->pos + len; i++)
|
||||||
*dst++ = ctx->encbuf[i] = ctx->fre[i] ^ (*data++);
|
*dst++ = ctx->encbuf[i] = ctx->fre[i] ^ (*data++);
|
||||||
ctx->pos += len;
|
ctx->pos += len;
|
||||||
@ -103,9 +104,10 @@ mix_encrypt_normal(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mix_decrypt_normal(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
mix_decrypt_normal(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = ctx->pos; i < ctx->pos + len; i++)
|
for (i = ctx->pos; i < ctx->pos + len; i++)
|
||||||
{
|
{
|
||||||
ctx->encbuf[i] = *data++;
|
ctx->encbuf[i] = *data++;
|
||||||
@ -122,9 +124,11 @@ mix_decrypt_normal(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
|||||||
* thus its all concentrated here.
|
* thus its all concentrated here.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
mix_encrypt_resync(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
mix_encrypt_resync(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
|
||||||
{
|
{
|
||||||
int i,n;
|
int i,
|
||||||
|
n;
|
||||||
|
|
||||||
/* block #2 is 2 bytes long */
|
/* block #2 is 2 bytes long */
|
||||||
if (ctx->block_no == 2)
|
if (ctx->block_no == 2)
|
||||||
{
|
{
|
||||||
@ -152,9 +156,11 @@ mix_encrypt_resync(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mix_decrypt_resync(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
mix_decrypt_resync(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
|
||||||
{
|
{
|
||||||
int i,n;
|
int i,
|
||||||
|
n;
|
||||||
|
|
||||||
/* block #2 is 2 bytes long */
|
/* block #2 is 2 bytes long */
|
||||||
if (ctx->block_no == 2)
|
if (ctx->block_no == 2)
|
||||||
{
|
{
|
||||||
@ -190,11 +196,11 @@ mix_decrypt_resync(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
|||||||
* common code for both encrypt and decrypt.
|
* common code for both encrypt and decrypt.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
cfb_process(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst,
|
cfb_process(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst,
|
||||||
mix_data_t mix_data)
|
mix_data_t mix_data)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
while (len > 0 && ctx->pos > 0)
|
while (len > 0 && ctx->pos > 0)
|
||||||
{
|
{
|
||||||
@ -243,16 +249,17 @@ cfb_process(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_cfb_encrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
pgp_cfb_encrypt(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
|
||||||
{
|
{
|
||||||
mix_data_t mix = ctx->resync ? mix_encrypt_resync : mix_encrypt_normal;
|
mix_data_t mix = ctx->resync ? mix_encrypt_resync : mix_encrypt_normal;
|
||||||
|
|
||||||
return cfb_process(ctx, data, len, dst, mix);
|
return cfb_process(ctx, data, len, dst, mix);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
|
pgp_cfb_decrypt(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
|
||||||
{
|
{
|
||||||
mix_data_t mix = ctx->resync ? mix_decrypt_resync : mix_decrypt_normal;
|
mix_data_t mix = ctx->resync ? mix_decrypt_resync : mix_decrypt_normal;
|
||||||
|
|
||||||
return cfb_process(ctx, data, len, dst, mix);
|
return cfb_process(ctx, data, len, dst, mix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-compress.c,v 1.4 2005/07/18 17:09:01 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-compress.c,v 1.5 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -180,12 +180,12 @@ compress_free(void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const PushFilterOps
|
static const PushFilterOps
|
||||||
compress_filter = {
|
compress_filter = {
|
||||||
compress_init, compress_process, compress_flush, compress_free
|
compress_init, compress_process, compress_flush, compress_free
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst)
|
pgp_compress_filter(PushFilter ** res, PGP_Context * ctx, PushFilter * dst)
|
||||||
{
|
{
|
||||||
return pushf_create(res, &compress_filter, ctx, dst);
|
return pushf_create(res, &compress_filter, ctx, dst);
|
||||||
}
|
}
|
||||||
@ -195,8 +195,8 @@ pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst)
|
|||||||
*/
|
*/
|
||||||
struct DecomprData
|
struct DecomprData
|
||||||
{
|
{
|
||||||
int buf_len; /* = ZIP_OUT_BUF */
|
int buf_len; /* = ZIP_OUT_BUF */
|
||||||
int buf_data; /* available data */
|
int buf_data; /* available data */
|
||||||
uint8 *pos;
|
uint8 *pos;
|
||||||
z_stream stream;
|
z_stream stream;
|
||||||
int eof;
|
int eof;
|
||||||
@ -204,14 +204,14 @@ struct DecomprData
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
decompress_init(void **priv_p, void *arg, PullFilter *src)
|
decompress_init(void **priv_p, void *arg, PullFilter * src)
|
||||||
{
|
{
|
||||||
PGP_Context *ctx = arg;
|
PGP_Context *ctx = arg;
|
||||||
struct DecomprData *dec;
|
struct DecomprData *dec;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (ctx->compress_algo != PGP_COMPR_ZLIB
|
if (ctx->compress_algo != PGP_COMPR_ZLIB
|
||||||
&& ctx->compress_algo != PGP_COMPR_ZIP)
|
&& ctx->compress_algo != PGP_COMPR_ZIP)
|
||||||
return PXE_PGP_UNSUPPORTED_COMPR;
|
return PXE_PGP_UNSUPPORTED_COMPR;
|
||||||
|
|
||||||
dec = px_alloc(sizeof(*dec));
|
dec = px_alloc(sizeof(*dec));
|
||||||
@ -236,11 +236,12 @@ decompress_init(void **priv_p, void *arg, PullFilter *src)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decompress_read(void *priv, PullFilter *src, int len,
|
static int
|
||||||
uint8 **data_p, uint8 *buf, int buflen)
|
decompress_read(void *priv, PullFilter * src, int len,
|
||||||
|
uint8 **data_p, uint8 *buf, int buflen)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
int flush;
|
int flush;
|
||||||
struct DecomprData *dec = priv;
|
struct DecomprData *dec = priv;
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
@ -257,8 +258,10 @@ restart:
|
|||||||
if (dec->eof)
|
if (dec->eof)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (dec->stream.avail_in == 0) {
|
if (dec->stream.avail_in == 0)
|
||||||
uint8 *tmp;
|
{
|
||||||
|
uint8 *tmp;
|
||||||
|
|
||||||
res = pullf_read(src, 8192, &tmp);
|
res = pullf_read(src, 8192, &tmp);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
@ -271,9 +274,9 @@ restart:
|
|||||||
dec->pos = dec->buf;
|
dec->pos = dec->buf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Z_SYNC_FLUSH is tell zlib to output as much as possible.
|
* Z_SYNC_FLUSH is tell zlib to output as much as possible. It should do
|
||||||
* It should do it anyway (Z_NO_FLUSH), but seems to reserve
|
* it anyway (Z_NO_FLUSH), but seems to reserve the right not to. So lets
|
||||||
* the right not to. So lets follow the API.
|
* follow the API.
|
||||||
*/
|
*/
|
||||||
flush = dec->stream.avail_in ? Z_SYNC_FLUSH : Z_FINISH;
|
flush = dec->stream.avail_in ? Z_SYNC_FLUSH : Z_FINISH;
|
||||||
res = inflate(&dec->stream, flush);
|
res = inflate(&dec->stream, flush);
|
||||||
@ -289,39 +292,38 @@ restart:
|
|||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decompress_free(void *priv)
|
static void
|
||||||
|
decompress_free(void *priv)
|
||||||
{
|
{
|
||||||
struct DecomprData *dec = priv;
|
struct DecomprData *dec = priv;
|
||||||
|
|
||||||
inflateEnd(&dec->stream);
|
inflateEnd(&dec->stream);
|
||||||
memset(dec, 0, sizeof(*dec));
|
memset(dec, 0, sizeof(*dec));
|
||||||
px_free(dec);
|
px_free(dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const PullFilterOps
|
static const PullFilterOps
|
||||||
decompress_filter = {
|
decompress_filter = {
|
||||||
decompress_init, decompress_read, decompress_free
|
decompress_init, decompress_read, decompress_free
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
|
pgp_decompress_filter(PullFilter ** res, PGP_Context * ctx, PullFilter * src)
|
||||||
{
|
{
|
||||||
return pullf_create(res, &decompress_filter, ctx, src);
|
return pullf_create(res, &decompress_filter, ctx, src);
|
||||||
}
|
}
|
||||||
|
#else /* DISABLE_ZLIB */
|
||||||
#else /* DISABLE_ZLIB */
|
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst)
|
pgp_compress_filter(PushFilter ** res, PGP_Context * ctx, PushFilter * dst)
|
||||||
{
|
{
|
||||||
return PXE_PGP_UNSUPPORTED_COMPR;
|
return PXE_PGP_UNSUPPORTED_COMPR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
|
pgp_decompress_filter(PullFilter ** res, PGP_Context * ctx, PullFilter * src)
|
||||||
{
|
{
|
||||||
return PXE_PGP_UNSUPPORTED_COMPR;
|
return PXE_PGP_UNSUPPORTED_COMPR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-decrypt.c,v 1.5 2005/09/24 19:14:04 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-decrypt.c,v 1.6 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -130,7 +130,7 @@ pgp_parse_pkt_hdr(PullFilter * src, uint8 *tag, int *len_p, int allow_ctx)
|
|||||||
{
|
{
|
||||||
int lentype;
|
int lentype;
|
||||||
int res;
|
int res;
|
||||||
uint8 *p;
|
uint8 *p;
|
||||||
|
|
||||||
/* EOF is normal here, thus we dont use GETBYTE */
|
/* EOF is normal here, thus we dont use GETBYTE */
|
||||||
res = pullf_read(src, 1, &p);
|
res = pullf_read(src, 1, &p);
|
||||||
@ -165,15 +165,17 @@ pgp_parse_pkt_hdr(PullFilter * src, uint8 *tag, int *len_p, int allow_ctx)
|
|||||||
/*
|
/*
|
||||||
* Packet reader
|
* Packet reader
|
||||||
*/
|
*/
|
||||||
struct PktData {
|
struct PktData
|
||||||
int type;
|
{
|
||||||
int len;
|
int type;
|
||||||
|
int len;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pktreader_pull(void *priv, PullFilter *src, int len,
|
static int
|
||||||
uint8 **data_p, uint8 *buf, int buflen)
|
pktreader_pull(void *priv, PullFilter * src, int len,
|
||||||
|
uint8 **data_p, uint8 *buf, int buflen)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
struct PktData *pkt = priv;
|
struct PktData *pkt = priv;
|
||||||
|
|
||||||
/* PKT_CONTEXT means: whatever there is */
|
/* PKT_CONTEXT means: whatever there is */
|
||||||
@ -207,6 +209,7 @@ static void
|
|||||||
pktreader_free(void *priv)
|
pktreader_free(void *priv)
|
||||||
{
|
{
|
||||||
struct PktData *pkt = priv;
|
struct PktData *pkt = priv;
|
||||||
|
|
||||||
memset(pkt, 0, sizeof(*pkt));
|
memset(pkt, 0, sizeof(*pkt));
|
||||||
px_free(pkt);
|
px_free(pkt);
|
||||||
}
|
}
|
||||||
@ -217,11 +220,12 @@ static struct PullFilterOps pktreader_filter = {
|
|||||||
|
|
||||||
/* needs helper function to pass several parameters */
|
/* needs helper function to pass several parameters */
|
||||||
int
|
int
|
||||||
pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
|
pgp_create_pkt_reader(PullFilter ** pf_p, PullFilter * src, int len,
|
||||||
int pkttype, PGP_Context *ctx)
|
int pkttype, PGP_Context * ctx)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
struct PktData *pkt = px_alloc(sizeof(*pkt));
|
struct PktData *pkt = px_alloc(sizeof(*pkt));
|
||||||
|
|
||||||
pkt->type = pkttype;
|
pkt->type = pkttype;
|
||||||
pkt->len = len;
|
pkt->len = len;
|
||||||
res = pullf_create(pf_p, &pktreader_filter, pkt, src);
|
res = pullf_create(pf_p, &pktreader_filter, pkt, src);
|
||||||
@ -234,13 +238,14 @@ pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
|
|||||||
* Prefix check filter
|
* Prefix check filter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int prefix_init(void **priv_p, void *arg, PullFilter *src)
|
static int
|
||||||
|
prefix_init(void **priv_p, void *arg, PullFilter * src)
|
||||||
{
|
{
|
||||||
PGP_Context *ctx = arg;
|
PGP_Context *ctx = arg;
|
||||||
int len;
|
int len;
|
||||||
int res;
|
int res;
|
||||||
uint8 *buf;
|
uint8 *buf;
|
||||||
uint8 tmpbuf[PGP_MAX_BLOCK + 2];
|
uint8 tmpbuf[PGP_MAX_BLOCK + 2];
|
||||||
|
|
||||||
len = pgp_get_cipher_block_size(ctx->cipher_algo);
|
len = pgp_get_cipher_block_size(ctx->cipher_algo);
|
||||||
if (len > sizeof(tmpbuf))
|
if (len > sizeof(tmpbuf))
|
||||||
@ -259,20 +264,19 @@ static int prefix_init(void **priv_p, void *arg, PullFilter *src)
|
|||||||
if (buf[len - 2] != buf[len] || buf[len - 1] != buf[len + 1])
|
if (buf[len - 2] != buf[len] || buf[len - 1] != buf[len + 1])
|
||||||
{
|
{
|
||||||
px_debug("prefix_init: corrupt prefix");
|
px_debug("prefix_init: corrupt prefix");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The original purpose of the 2-byte check was
|
* The original purpose of the 2-byte check was to show user a
|
||||||
* to show user a friendly "wrong key" message.
|
* friendly "wrong key" message. This made following possible:
|
||||||
* This made following possible:
|
|
||||||
*
|
*
|
||||||
* "An Attack on CFB Mode Encryption As Used By OpenPGP"
|
* "An Attack on CFB Mode Encryption As Used By OpenPGP" by Serge Mister
|
||||||
* by Serge Mister and Robert Zuccherato
|
* and Robert Zuccherato
|
||||||
*
|
*
|
||||||
* To avoid being 'oracle', we delay reporting, which
|
* To avoid being 'oracle', we delay reporting, which basically means we
|
||||||
* basically means we prefer to run into corrupt packet
|
* prefer to run into corrupt packet header.
|
||||||
* header.
|
|
||||||
*
|
*
|
||||||
* We _could_ throw PXE_PGP_CORRUPT_DATA here, but
|
* We _could_ throw PXE_PGP_CORRUPT_DATA here, but there is possibility
|
||||||
* there is possibility of attack via timing, so we don't.
|
* of attack via timing, so we don't.
|
||||||
*/
|
*/
|
||||||
ctx->corrupt_prefix = 1;
|
ctx->corrupt_prefix = 1;
|
||||||
}
|
}
|
||||||
@ -289,9 +293,10 @@ static struct PullFilterOps prefix_filter = {
|
|||||||
* Decrypt filter
|
* Decrypt filter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int decrypt_init(void **priv_p, void *arg, PullFilter *src)
|
static int
|
||||||
|
decrypt_init(void **priv_p, void *arg, PullFilter * src)
|
||||||
{
|
{
|
||||||
PGP_CFB *cfb = arg;
|
PGP_CFB *cfb = arg;
|
||||||
|
|
||||||
*priv_p = cfb;
|
*priv_p = cfb;
|
||||||
|
|
||||||
@ -299,15 +304,17 @@ static int decrypt_init(void **priv_p, void *arg, PullFilter *src)
|
|||||||
return 4096;
|
return 4096;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decrypt_read(void *priv, PullFilter *src, int len,
|
static int
|
||||||
uint8 **data_p, uint8 *buf, int buflen)
|
decrypt_read(void *priv, PullFilter * src, int len,
|
||||||
|
uint8 **data_p, uint8 *buf, int buflen)
|
||||||
{
|
{
|
||||||
PGP_CFB *cfb = priv;
|
PGP_CFB *cfb = priv;
|
||||||
uint8 *tmp;
|
uint8 *tmp;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
res = pullf_read(src, len, &tmp);
|
res = pullf_read(src, len, &tmp);
|
||||||
if (res > 0) {
|
if (res > 0)
|
||||||
|
{
|
||||||
pgp_cfb_decrypt(cfb, tmp, res, buf);
|
pgp_cfb_decrypt(cfb, tmp, res, buf);
|
||||||
*data_p = buf;
|
*data_p = buf;
|
||||||
}
|
}
|
||||||
@ -323,28 +330,33 @@ struct PullFilterOps pgp_decrypt_filter = {
|
|||||||
* MDC hasher filter
|
* MDC hasher filter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int mdc_init(void **priv_p, void *arg, PullFilter *src)
|
static int
|
||||||
|
mdc_init(void **priv_p, void *arg, PullFilter * src)
|
||||||
{
|
{
|
||||||
PGP_Context *ctx = arg;
|
PGP_Context *ctx = arg;
|
||||||
|
|
||||||
*priv_p = ctx;
|
*priv_p = ctx;
|
||||||
return pgp_load_digest(PGP_DIGEST_SHA1, &ctx->mdc_ctx);
|
return pgp_load_digest(PGP_DIGEST_SHA1, &ctx->mdc_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mdc_free(void *priv)
|
static void
|
||||||
|
mdc_free(void *priv)
|
||||||
{
|
{
|
||||||
PGP_Context *ctx = priv;
|
PGP_Context *ctx = priv;
|
||||||
|
|
||||||
if (ctx->use_mdcbuf_filter)
|
if (ctx->use_mdcbuf_filter)
|
||||||
return;
|
return;
|
||||||
px_md_free(ctx->mdc_ctx);
|
px_md_free(ctx->mdc_ctx);
|
||||||
ctx->mdc_ctx = NULL;
|
ctx->mdc_ctx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mdc_finish(PGP_Context *ctx, PullFilter *src,
|
static int
|
||||||
int len, uint8 **data_p)
|
mdc_finish(PGP_Context * ctx, PullFilter * src,
|
||||||
|
int len, uint8 **data_p)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
uint8 hash[20];
|
uint8 hash[20];
|
||||||
uint8 tmpbuf[22];
|
uint8 tmpbuf[22];
|
||||||
|
|
||||||
if (len + 1 > sizeof(tmpbuf))
|
if (len + 1 > sizeof(tmpbuf))
|
||||||
return PXE_BUG;
|
return PXE_BUG;
|
||||||
@ -394,10 +406,11 @@ static int mdc_finish(PGP_Context *ctx, PullFilter *src,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mdc_read(void *priv, PullFilter *src, int len,
|
static int
|
||||||
uint8 **data_p, uint8 *buf, int buflen)
|
mdc_read(void *priv, PullFilter * src, int len,
|
||||||
|
uint8 **data_p, uint8 *buf, int buflen)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_Context *ctx = priv;
|
PGP_Context *ctx = priv;
|
||||||
|
|
||||||
/* skip this filter? */
|
/* skip this filter? */
|
||||||
@ -434,18 +447,20 @@ static struct PullFilterOps mdc_filter = {
|
|||||||
* packet, which is silly.
|
* packet, which is silly.
|
||||||
*/
|
*/
|
||||||
#define MDCBUF_LEN 8192
|
#define MDCBUF_LEN 8192
|
||||||
struct MDCBufData {
|
struct MDCBufData
|
||||||
|
{
|
||||||
PGP_Context *ctx;
|
PGP_Context *ctx;
|
||||||
int eof;
|
int eof;
|
||||||
int buflen;
|
int buflen;
|
||||||
int avail;
|
int avail;
|
||||||
uint8 *pos;
|
uint8 *pos;
|
||||||
int mdc_avail;
|
int mdc_avail;
|
||||||
uint8 mdc_buf[22];
|
uint8 mdc_buf[22];
|
||||||
uint8 buf[MDCBUF_LEN];
|
uint8 buf[MDCBUF_LEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
|
static int
|
||||||
|
mdcbuf_init(void **priv_p, void *arg, PullFilter * src)
|
||||||
{
|
{
|
||||||
PGP_Context *ctx = arg;
|
PGP_Context *ctx = arg;
|
||||||
struct MDCBufData *st;
|
struct MDCBufData *st;
|
||||||
@ -462,10 +477,11 @@ static int mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mdcbuf_finish(struct MDCBufData *st)
|
static int
|
||||||
|
mdcbuf_finish(struct MDCBufData * st)
|
||||||
{
|
{
|
||||||
uint8 hash[20];
|
uint8 hash[20];
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
st->eof = 1;
|
st->eof = 1;
|
||||||
|
|
||||||
@ -486,25 +502,29 @@ static int mdcbuf_finish(struct MDCBufData *st)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mdcbuf_load_data(struct MDCBufData *st, uint8 *src, int len)
|
static void
|
||||||
|
mdcbuf_load_data(struct MDCBufData * st, uint8 *src, int len)
|
||||||
{
|
{
|
||||||
uint8 *dst = st->pos + st->avail;
|
uint8 *dst = st->pos + st->avail;
|
||||||
|
|
||||||
memcpy(dst, src, len);
|
memcpy(dst, src, len);
|
||||||
px_md_update(st->ctx->mdc_ctx, src, len);
|
px_md_update(st->ctx->mdc_ctx, src, len);
|
||||||
st->avail += len;
|
st->avail += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mdcbuf_load_mdc(struct MDCBufData *st, uint8 *src, int len)
|
static void
|
||||||
|
mdcbuf_load_mdc(struct MDCBufData * st, uint8 *src, int len)
|
||||||
{
|
{
|
||||||
memmove(st->mdc_buf + st->mdc_avail, src, len);
|
memmove(st->mdc_buf + st->mdc_avail, src, len);
|
||||||
st->mdc_avail += len;
|
st->mdc_avail += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mdcbuf_refill(struct MDCBufData *st, PullFilter *src)
|
static int
|
||||||
|
mdcbuf_refill(struct MDCBufData * st, PullFilter * src)
|
||||||
{
|
{
|
||||||
uint8 *data;
|
uint8 *data;
|
||||||
int res;
|
int res;
|
||||||
int need;
|
int need;
|
||||||
|
|
||||||
/* put avail data in start */
|
/* put avail data in start */
|
||||||
if (st->avail > 0 && st->pos != st->buf)
|
if (st->avail > 0 && st->pos != st->buf)
|
||||||
@ -530,7 +550,8 @@ static int mdcbuf_refill(struct MDCBufData *st, PullFilter *src)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int canmove = st->mdc_avail + res - 22;
|
int canmove = st->mdc_avail + res - 22;
|
||||||
|
|
||||||
if (canmove > 0)
|
if (canmove > 0)
|
||||||
{
|
{
|
||||||
mdcbuf_load_data(st, st->mdc_buf, canmove);
|
mdcbuf_load_data(st, st->mdc_buf, canmove);
|
||||||
@ -542,11 +563,12 @@ static int mdcbuf_refill(struct MDCBufData *st, PullFilter *src)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mdcbuf_read(void *priv, PullFilter *src, int len,
|
static int
|
||||||
uint8 **data_p, uint8 *buf, int buflen)
|
mdcbuf_read(void *priv, PullFilter * src, int len,
|
||||||
|
uint8 **data_p, uint8 *buf, int buflen)
|
||||||
{
|
{
|
||||||
struct MDCBufData *st = priv;
|
struct MDCBufData *st = priv;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (!st->eof && len > st->avail)
|
if (!st->eof && len > st->avail)
|
||||||
{
|
{
|
||||||
@ -568,6 +590,7 @@ static void
|
|||||||
mdcbuf_free(void *priv)
|
mdcbuf_free(void *priv)
|
||||||
{
|
{
|
||||||
struct MDCBufData *st = priv;
|
struct MDCBufData *st = priv;
|
||||||
|
|
||||||
px_md_free(st->ctx->mdc_ctx);
|
px_md_free(st->ctx->mdc_ctx);
|
||||||
st->ctx->mdc_ctx = NULL;
|
st->ctx->mdc_ctx = NULL;
|
||||||
memset(st, 0, sizeof(*st));
|
memset(st, 0, sizeof(*st));
|
||||||
@ -583,29 +606,30 @@ static struct PullFilterOps mdcbuf_filter = {
|
|||||||
* Decrypt separate session key
|
* Decrypt separate session key
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
|
decrypt_key(PGP_Context * ctx, const uint8 *src, int len)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
uint8 algo;
|
uint8 algo;
|
||||||
PGP_CFB *cfb;
|
PGP_CFB *cfb;
|
||||||
|
|
||||||
res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
|
res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
|
||||||
ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
|
ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
pgp_cfb_decrypt(cfb, src, 1, &algo);
|
pgp_cfb_decrypt(cfb, src, 1, &algo);
|
||||||
src ++;
|
src++;
|
||||||
len --;
|
len--;
|
||||||
|
|
||||||
pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
|
pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
|
||||||
pgp_cfb_free(cfb);
|
pgp_cfb_free(cfb);
|
||||||
ctx->sess_key_len = len;
|
ctx->sess_key_len = len;
|
||||||
ctx->cipher_algo = algo;
|
ctx->cipher_algo = algo;
|
||||||
|
|
||||||
if (pgp_get_cipher_key_size(algo) != len) {
|
if (pgp_get_cipher_key_size(algo) != len)
|
||||||
|
{
|
||||||
px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",
|
px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",
|
||||||
algo, pgp_get_cipher_key_size(algo), len);
|
algo, pgp_get_cipher_key_size(algo), len);
|
||||||
return PXE_PGP_CORRUPT_DATA;
|
return PXE_PGP_CORRUPT_DATA;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -643,7 +667,7 @@ parse_symenc_sesskey(PGP_Context * ctx, PullFilter * src)
|
|||||||
* generate key from password
|
* generate key from password
|
||||||
*/
|
*/
|
||||||
res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
|
res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
|
||||||
ctx->sym_key, ctx->sym_key_len);
|
ctx->sym_key, ctx->sym_key_len);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
@ -684,21 +708,23 @@ parse_symenc_sesskey(PGP_Context * ctx, PullFilter * src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
copy_crlf(MBuf *dst, uint8 *data, int len, int *got_cr)
|
copy_crlf(MBuf * dst, uint8 *data, int len, int *got_cr)
|
||||||
{
|
{
|
||||||
uint8 *data_end = data + len;
|
uint8 *data_end = data + len;
|
||||||
uint8 tmpbuf[1024];
|
uint8 tmpbuf[1024];
|
||||||
uint8 *tmp_end = tmpbuf + sizeof(tmpbuf);
|
uint8 *tmp_end = tmpbuf + sizeof(tmpbuf);
|
||||||
uint8 *p;
|
uint8 *p;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
p = tmpbuf;
|
p = tmpbuf;
|
||||||
if (*got_cr) {
|
if (*got_cr)
|
||||||
|
{
|
||||||
if (*data != '\n')
|
if (*data != '\n')
|
||||||
*p++ = '\r';
|
*p++ = '\r';
|
||||||
*got_cr = 0;
|
*got_cr = 0;
|
||||||
}
|
}
|
||||||
while (data < data_end) {
|
while (data < data_end)
|
||||||
|
{
|
||||||
if (*data == '\r')
|
if (*data == '\r')
|
||||||
{
|
{
|
||||||
if (data + 1 < data_end)
|
if (data + 1 < data_end)
|
||||||
@ -779,8 +805,9 @@ parse_literal_data(PGP_Context * ctx, MBuf * dst, PullFilter * pkt)
|
|||||||
ctx->unicode_mode = (type == 'u') ? 1 : 0;
|
ctx->unicode_mode = (type == 'u') ? 1 : 0;
|
||||||
|
|
||||||
/* read data */
|
/* read data */
|
||||||
while (1) {
|
while (1)
|
||||||
res = pullf_read(pkt, 32*1024, &buf);
|
{
|
||||||
|
res = pullf_read(pkt, 32 * 1024, &buf);
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -797,8 +824,8 @@ parse_literal_data(PGP_Context * ctx, MBuf * dst, PullFilter * pkt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* process_data_packets and parse_compressed_data call each other */
|
/* process_data_packets and parse_compressed_data call each other */
|
||||||
static int process_data_packets(PGP_Context * ctx, MBuf * dst,
|
static int process_data_packets(PGP_Context * ctx, MBuf * dst,
|
||||||
PullFilter * src, int allow_compr, int need_mdc);
|
PullFilter * src, int allow_compr, int need_mdc);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_compressed_data(PGP_Context * ctx, MBuf * dst, PullFilter * pkt)
|
parse_compressed_data(PGP_Context * ctx, MBuf * dst, PullFilter * pkt)
|
||||||
@ -822,7 +849,7 @@ parse_compressed_data(PGP_Context * ctx, MBuf * dst, PullFilter * pkt)
|
|||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
{
|
{
|
||||||
res = process_data_packets(ctx, dst, pf_decompr,
|
res = process_data_packets(ctx, dst, pf_decompr,
|
||||||
NO_COMPR, NO_MDC);
|
NO_COMPR, NO_MDC);
|
||||||
pullf_free(pf_decompr);
|
pullf_free(pf_decompr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -850,7 +877,7 @@ process_data_packets(PGP_Context * ctx, MBuf * dst, PullFilter * src,
|
|||||||
int got_data = 0;
|
int got_data = 0;
|
||||||
int got_mdc = 0;
|
int got_mdc = 0;
|
||||||
PullFilter *pkt = NULL;
|
PullFilter *pkt = NULL;
|
||||||
uint8 *tmp;
|
uint8 *tmp;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -951,12 +978,12 @@ static int
|
|||||||
parse_symenc_data(PGP_Context * ctx, PullFilter * pkt, MBuf * dst)
|
parse_symenc_data(PGP_Context * ctx, PullFilter * pkt, MBuf * dst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_CFB *cfb = NULL;
|
PGP_CFB *cfb = NULL;
|
||||||
PullFilter *pf_decrypt = NULL;
|
PullFilter *pf_decrypt = NULL;
|
||||||
PullFilter *pf_prefix = NULL;
|
PullFilter *pf_prefix = NULL;
|
||||||
|
|
||||||
res = pgp_cfb_create(&cfb, ctx->cipher_algo,
|
res = pgp_cfb_create(&cfb, ctx->cipher_algo,
|
||||||
ctx->sess_key, ctx->sess_key_len, 1, NULL);
|
ctx->sess_key, ctx->sess_key_len, 1, NULL);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -985,11 +1012,11 @@ static int
|
|||||||
parse_symenc_mdc_data(PGP_Context * ctx, PullFilter * pkt, MBuf * dst)
|
parse_symenc_mdc_data(PGP_Context * ctx, PullFilter * pkt, MBuf * dst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_CFB *cfb = NULL;
|
PGP_CFB *cfb = NULL;
|
||||||
PullFilter *pf_decrypt = NULL;
|
PullFilter *pf_decrypt = NULL;
|
||||||
PullFilter *pf_prefix = NULL;
|
PullFilter *pf_prefix = NULL;
|
||||||
PullFilter *pf_mdc = NULL;
|
PullFilter *pf_mdc = NULL;
|
||||||
uint8 ver;
|
uint8 ver;
|
||||||
|
|
||||||
GETBYTE(pkt, ver);
|
GETBYTE(pkt, ver);
|
||||||
if (ver != 1)
|
if (ver != 1)
|
||||||
@ -999,7 +1026,7 @@ parse_symenc_mdc_data(PGP_Context * ctx, PullFilter * pkt, MBuf * dst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
res = pgp_cfb_create(&cfb, ctx->cipher_algo,
|
res = pgp_cfb_create(&cfb, ctx->cipher_algo,
|
||||||
ctx->sess_key, ctx->sess_key_len, 0, NULL);
|
ctx->sess_key, ctx->sess_key_len, 0, NULL);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -1034,12 +1061,13 @@ out:
|
|||||||
* skip over packet contents
|
* skip over packet contents
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pgp_skip_packet(PullFilter *pkt)
|
pgp_skip_packet(PullFilter * pkt)
|
||||||
{
|
{
|
||||||
int res = 1;
|
int res = 1;
|
||||||
uint8 *tmp;
|
uint8 *tmp;
|
||||||
while (res > 0)
|
|
||||||
res = pullf_read(pkt, 32*1024, &tmp);
|
while (res > 0)
|
||||||
|
res = pullf_read(pkt, 32 * 1024, &tmp);
|
||||||
return res < 0 ? res : 0;
|
return res < 0 ? res : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1047,13 +1075,14 @@ pgp_skip_packet(PullFilter *pkt)
|
|||||||
* expect to be at packet end, any data is error
|
* expect to be at packet end, any data is error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pgp_expect_packet_end(PullFilter *pkt)
|
pgp_expect_packet_end(PullFilter * pkt)
|
||||||
{
|
{
|
||||||
int res = 1;
|
int res = 1;
|
||||||
uint8 *tmp;
|
uint8 *tmp;
|
||||||
while (res > 0)
|
|
||||||
|
while (res > 0)
|
||||||
{
|
{
|
||||||
res = pullf_read(pkt, 32*1024, &tmp);
|
res = pullf_read(pkt, 32 * 1024, &tmp);
|
||||||
if (res > 0)
|
if (res > 0)
|
||||||
{
|
{
|
||||||
px_debug("pgp_expect_packet_end: got data");
|
px_debug("pgp_expect_packet_end: got data");
|
||||||
@ -1066,17 +1095,18 @@ pgp_expect_packet_end(PullFilter *pkt)
|
|||||||
int
|
int
|
||||||
pgp_decrypt(PGP_Context * ctx, MBuf * msrc, MBuf * mdst)
|
pgp_decrypt(PGP_Context * ctx, MBuf * msrc, MBuf * mdst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PullFilter *src = NULL;
|
PullFilter *src = NULL;
|
||||||
PullFilter *pkt = NULL;
|
PullFilter *pkt = NULL;
|
||||||
uint8 tag;
|
uint8 tag;
|
||||||
int len;
|
int len;
|
||||||
int got_key = 0;
|
int got_key = 0;
|
||||||
int got_data = 0;
|
int got_data = 0;
|
||||||
|
|
||||||
res = pullf_create_mbuf_reader(&src, msrc);
|
res = pullf_create_mbuf_reader(&src, msrc);
|
||||||
|
|
||||||
while (res >= 0) {
|
while (res >= 0)
|
||||||
|
{
|
||||||
res = pgp_parse_pkt_hdr(src, &tag, &len, NO_CTX_SIZE);
|
res = pgp_parse_pkt_hdr(src, &tag, &len, NO_CTX_SIZE);
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
break;
|
break;
|
||||||
@ -1086,7 +1116,8 @@ pgp_decrypt(PGP_Context * ctx, MBuf * msrc, MBuf * mdst)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
res = PXE_PGP_CORRUPT_DATA;
|
res = PXE_PGP_CORRUPT_DATA;
|
||||||
switch (tag) {
|
switch (tag)
|
||||||
|
{
|
||||||
case PGP_PKT_MARKER:
|
case PGP_PKT_MARKER:
|
||||||
res = pgp_skip_packet(pkt);
|
res = pgp_skip_packet(pkt);
|
||||||
break;
|
break;
|
||||||
@ -1097,10 +1128,11 @@ pgp_decrypt(PGP_Context * ctx, MBuf * msrc, MBuf * mdst)
|
|||||||
break;
|
break;
|
||||||
case PGP_PKT_SYMENCRYPTED_SESSKEY:
|
case PGP_PKT_SYMENCRYPTED_SESSKEY:
|
||||||
if (got_key)
|
if (got_key)
|
||||||
/* Theoretically, there could be several keys,
|
|
||||||
* both public and symmetric, all of which
|
/*
|
||||||
* encrypt same session key. Decrypt should try
|
* Theoretically, there could be several keys, both public
|
||||||
* with each one, before failing.
|
* and symmetric, all of which encrypt same session key.
|
||||||
|
* Decrypt should try with each one, before failing.
|
||||||
*/
|
*/
|
||||||
px_debug("pgp_decrypt: using first of several keys");
|
px_debug("pgp_decrypt: using first of several keys");
|
||||||
else
|
else
|
||||||
@ -1154,4 +1186,3 @@ pgp_decrypt(PGP_Context * ctx, MBuf * msrc, MBuf * mdst)
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-encrypt.c,v 1.2 2005/07/11 15:07:59 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-encrypt.c,v 1.3 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -65,9 +65,11 @@ render_newlen(uint8 *h, int len)
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_tag_only(PushFilter *dst, int tag)
|
static int
|
||||||
|
write_tag_only(PushFilter * dst, int tag)
|
||||||
{
|
{
|
||||||
uint8 hdr = 0xC0 | tag;
|
uint8 hdr = 0xC0 | tag;
|
||||||
|
|
||||||
return pushf_write(dst, &hdr, 1);
|
return pushf_write(dst, &hdr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +123,7 @@ mdc_flush(PushFilter * dst, void *priv)
|
|||||||
* create mdc pkt
|
* create mdc pkt
|
||||||
*/
|
*/
|
||||||
pkt[0] = 0xD3;
|
pkt[0] = 0xD3;
|
||||||
pkt[1] = 0x14; /* MDC_DIGEST_LEN */
|
pkt[1] = 0x14; /* MDC_DIGEST_LEN */
|
||||||
px_md_update(md, pkt, 2);
|
px_md_update(md, pkt, 2);
|
||||||
px_md_finish(md, pkt + 2);
|
px_md_finish(md, pkt + 2);
|
||||||
|
|
||||||
@ -150,7 +152,7 @@ static const PushFilterOps mdc_filter = {
|
|||||||
struct EncStat
|
struct EncStat
|
||||||
{
|
{
|
||||||
PGP_CFB *ciph;
|
PGP_CFB *ciph;
|
||||||
uint8 buf[ENCBUF];
|
uint8 buf[ENCBUF];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -158,21 +160,22 @@ encrypt_init(PushFilter * next, void *init_arg, void **priv_p)
|
|||||||
{
|
{
|
||||||
struct EncStat *st;
|
struct EncStat *st;
|
||||||
PGP_Context *ctx = init_arg;
|
PGP_Context *ctx = init_arg;
|
||||||
PGP_CFB *ciph;
|
PGP_CFB *ciph;
|
||||||
int resync = 1;
|
int resync = 1;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/* should we use newer packet format? */
|
/* should we use newer packet format? */
|
||||||
if (ctx->disable_mdc == 0)
|
if (ctx->disable_mdc == 0)
|
||||||
{
|
{
|
||||||
uint8 ver = 1;
|
uint8 ver = 1;
|
||||||
|
|
||||||
resync = 0;
|
resync = 0;
|
||||||
res = pushf_write(next, &ver, 1);
|
res = pushf_write(next, &ver, 1);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
res = pgp_cfb_create(&ciph, ctx->cipher_algo,
|
res = pgp_cfb_create(&ciph, ctx->cipher_algo,
|
||||||
ctx->sess_key, ctx->sess_key_len, resync, NULL);
|
ctx->sess_key, ctx->sess_key_len, resync, NULL);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
@ -189,11 +192,12 @@ encrypt_process(PushFilter * next, void *priv, const uint8 *data, int len)
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
struct EncStat *st = priv;
|
struct EncStat *st = priv;
|
||||||
int avail = len;
|
int avail = len;
|
||||||
|
|
||||||
while (avail > 0)
|
while (avail > 0)
|
||||||
{
|
{
|
||||||
int tmplen = avail > ENCBUF ? ENCBUF : avail;
|
int tmplen = avail > ENCBUF ? ENCBUF : avail;
|
||||||
|
|
||||||
res = pgp_cfb_encrypt(st->ciph, data, tmplen, st->buf);
|
res = pgp_cfb_encrypt(st->ciph, data, tmplen, st->buf);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
@ -303,9 +307,11 @@ static const PushFilterOps pkt_stream_filter = {
|
|||||||
pkt_stream_init, pkt_stream_process, pkt_stream_flush, pkt_stream_free
|
pkt_stream_init, pkt_stream_process, pkt_stream_flush, pkt_stream_free
|
||||||
};
|
};
|
||||||
|
|
||||||
int pgp_create_pkt_writer(PushFilter *dst, int tag, PushFilter **res_p)
|
int
|
||||||
|
pgp_create_pkt_writer(PushFilter * dst, int tag, PushFilter ** res_p)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
res = write_tag_only(dst, tag);
|
res = write_tag_only(dst, tag);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
@ -320,11 +326,13 @@ int pgp_create_pkt_writer(PushFilter *dst, int tag, PushFilter **res_p)
|
|||||||
static int
|
static int
|
||||||
crlf_process(PushFilter * dst, void *priv, const uint8 *data, int len)
|
crlf_process(PushFilter * dst, void *priv, const uint8 *data, int len)
|
||||||
{
|
{
|
||||||
const uint8 * data_end = data + len;
|
const uint8 *data_end = data + len;
|
||||||
const uint8 * p2, * p1 = data;
|
const uint8 *p2,
|
||||||
int line_len;
|
*p1 = data;
|
||||||
static const uint8 crlf[] = { '\r', '\n' };
|
int line_len;
|
||||||
int res = 0;
|
static const uint8 crlf[] = {'\r', '\n'};
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
while (p1 < data_end)
|
while (p1 < data_end)
|
||||||
{
|
{
|
||||||
p2 = memchr(p1, '\n', data_end - p1);
|
p2 = memchr(p1, '\n', data_end - p1);
|
||||||
@ -363,13 +371,13 @@ static const PushFilterOps crlf_filter = {
|
|||||||
* Initialize literal data packet
|
* Initialize literal data packet
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
init_litdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
|
init_litdata_packet(PushFilter ** pf_res, PGP_Context * ctx, PushFilter * dst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
int hdrlen;
|
int hdrlen;
|
||||||
uint8 hdr[6];
|
uint8 hdr[6];
|
||||||
uint32 t;
|
uint32 t;
|
||||||
PushFilter *pkt;
|
PushFilter *pkt;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -382,10 +390,10 @@ init_litdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
|
|||||||
type = 'b';
|
type = 'b';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store the creation time into packet.
|
* Store the creation time into packet. The goal is to have as few known
|
||||||
* The goal is to have as few known bytes as possible.
|
* bytes as possible.
|
||||||
*/
|
*/
|
||||||
t = (uint32)time(NULL);
|
t = (uint32) time(NULL);
|
||||||
|
|
||||||
hdr[0] = type;
|
hdr[0] = type;
|
||||||
hdr[1] = 0;
|
hdr[1] = 0;
|
||||||
@ -418,10 +426,10 @@ init_litdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
|
|||||||
* Initialize compression filter
|
* Initialize compression filter
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
init_compress(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
|
init_compress(PushFilter ** pf_res, PGP_Context * ctx, PushFilter * dst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
uint8 type = ctx->compress_algo;
|
uint8 type = ctx->compress_algo;
|
||||||
PushFilter *pkt;
|
PushFilter *pkt;
|
||||||
|
|
||||||
res = write_tag_only(dst, PGP_PKT_COMPRESSED_DATA);
|
res = write_tag_only(dst, PGP_PKT_COMPRESSED_DATA);
|
||||||
@ -446,7 +454,7 @@ init_compress(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
|
|||||||
* Initialize encdata packet
|
* Initialize encdata packet
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
init_encdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
|
init_encdata_packet(PushFilter ** pf_res, PGP_Context * ctx, PushFilter * dst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
int tag;
|
int tag;
|
||||||
@ -467,7 +475,7 @@ init_encdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
|
|||||||
* write prefix
|
* write prefix
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
write_prefix(PGP_Context *ctx, PushFilter * dst)
|
write_prefix(PGP_Context * ctx, PushFilter * dst)
|
||||||
{
|
{
|
||||||
uint8 prefix[PGP_MAX_BLOCK + 2];
|
uint8 prefix[PGP_MAX_BLOCK + 2];
|
||||||
int res,
|
int res,
|
||||||
@ -491,14 +499,14 @@ write_prefix(PGP_Context *ctx, PushFilter * dst)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
symencrypt_sesskey(PGP_Context *ctx, uint8 *dst)
|
symencrypt_sesskey(PGP_Context * ctx, uint8 *dst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_CFB *cfb;
|
PGP_CFB *cfb;
|
||||||
uint8 algo = ctx->cipher_algo;
|
uint8 algo = ctx->cipher_algo;
|
||||||
|
|
||||||
res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
|
res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
|
||||||
ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
|
ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
@ -511,12 +519,12 @@ symencrypt_sesskey(PGP_Context *ctx, uint8 *dst)
|
|||||||
|
|
||||||
/* 5.3: Symmetric-Key Encrypted Session-Key */
|
/* 5.3: Symmetric-Key Encrypted Session-Key */
|
||||||
static int
|
static int
|
||||||
write_symenc_sesskey(PGP_Context *ctx, PushFilter *dst)
|
write_symenc_sesskey(PGP_Context * ctx, PushFilter * dst)
|
||||||
{
|
{
|
||||||
uint8 pkt[256];
|
uint8 pkt[256];
|
||||||
int pktlen;
|
int pktlen;
|
||||||
int res;
|
int res;
|
||||||
uint8 *p = pkt;
|
uint8 *p = pkt;
|
||||||
|
|
||||||
*p++ = 4; /* 5.3 - version number */
|
*p++ = 4; /* 5.3 - version number */
|
||||||
*p++ = ctx->s2k_cipher_algo;
|
*p++ = ctx->s2k_cipher_algo;
|
||||||
@ -564,13 +572,14 @@ init_s2k_key(PGP_Context * ctx)
|
|||||||
return res;
|
return res;
|
||||||
|
|
||||||
return pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
|
return pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
|
||||||
ctx->sym_key, ctx->sym_key_len);
|
ctx->sym_key, ctx->sym_key_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
init_sess_key(PGP_Context *ctx)
|
init_sess_key(PGP_Context * ctx)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (ctx->use_sess_key || ctx->pub_key)
|
if (ctx->use_sess_key || ctx->pub_key)
|
||||||
{
|
{
|
||||||
ctx->sess_key_len = pgp_get_cipher_key_size(ctx->cipher_algo);
|
ctx->sess_key_len = pgp_get_cipher_key_size(ctx->cipher_algo);
|
||||||
@ -596,7 +605,8 @@ pgp_encrypt(PGP_Context * ctx, MBuf * src, MBuf * dst)
|
|||||||
int res;
|
int res;
|
||||||
int len;
|
int len;
|
||||||
uint8 *buf;
|
uint8 *buf;
|
||||||
PushFilter *pf, *pf_tmp;
|
PushFilter *pf,
|
||||||
|
*pf_tmp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* do we have any key
|
* do we have any key
|
||||||
@ -696,4 +706,3 @@ out:
|
|||||||
pushf_free_all(pf);
|
pushf_free_all(pf);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-info.c,v 1.3 2005/08/13 02:06:20 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-info.c,v 1.4 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
@ -34,9 +34,10 @@
|
|||||||
#include "mbuf.h"
|
#include "mbuf.h"
|
||||||
#include "pgp.h"
|
#include "pgp.h"
|
||||||
|
|
||||||
static int read_pubkey_keyid(PullFilter *pkt, uint8 *keyid_buf)
|
static int
|
||||||
|
read_pubkey_keyid(PullFilter * pkt, uint8 *keyid_buf)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_PubKey *pk = NULL;
|
PGP_PubKey *pk = NULL;
|
||||||
|
|
||||||
res = _pgp_read_public_key(pkt, &pk);
|
res = _pgp_read_public_key(pkt, &pk);
|
||||||
@ -66,10 +67,11 @@ err:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_pubenc_keyid(PullFilter *pkt, uint8 *keyid_buf)
|
static int
|
||||||
|
read_pubenc_keyid(PullFilter * pkt, uint8 *keyid_buf)
|
||||||
{
|
{
|
||||||
uint8 ver;
|
uint8 ver;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
GETBYTE(pkt, ver);
|
GETBYTE(pkt, ver);
|
||||||
if (ver != 3)
|
if (ver != 3)
|
||||||
@ -87,42 +89,47 @@ static const char hextbl[] = "0123456789ABCDEF";
|
|||||||
static int
|
static int
|
||||||
print_key(uint8 *keyid, char *dst)
|
print_key(uint8 *keyid, char *dst)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned c;
|
unsigned c;
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
c = keyid[i];
|
c = keyid[i];
|
||||||
*dst++ = hextbl[(c >> 4) & 0x0F];
|
*dst++ = hextbl[(c >> 4) & 0x0F];
|
||||||
*dst++ = hextbl[c & 0x0F];
|
*dst++ = hextbl[c & 0x0F];
|
||||||
}
|
}
|
||||||
*dst = 0;
|
*dst = 0;
|
||||||
return 8*2;
|
return 8 * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint8 any_key[] =
|
static const uint8 any_key[] =
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0 };
|
{0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dst should have room for 17 bytes
|
* dst should have room for 17 bytes
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pgp_get_keyid(MBuf *pgp_data, char *dst)
|
pgp_get_keyid(MBuf * pgp_data, char *dst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PullFilter *src;
|
PullFilter *src;
|
||||||
PullFilter *pkt = NULL;
|
PullFilter *pkt = NULL;
|
||||||
int len;
|
int len;
|
||||||
uint8 tag;
|
uint8 tag;
|
||||||
int got_pub_key=0, got_symenc_key=0, got_pubenc_key=0;
|
int got_pub_key = 0,
|
||||||
int got_data=0;
|
got_symenc_key = 0,
|
||||||
uint8 keyid_buf[8];
|
got_pubenc_key = 0;
|
||||||
int got_main_key=0;
|
int got_data = 0;
|
||||||
|
uint8 keyid_buf[8];
|
||||||
|
int got_main_key = 0;
|
||||||
|
|
||||||
|
|
||||||
res = pullf_create_mbuf_reader(&src, pgp_data);
|
res = pullf_create_mbuf_reader(&src, pgp_data);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
while (1) {
|
while (1)
|
||||||
|
{
|
||||||
res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
|
res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
break;
|
break;
|
||||||
@ -226,4 +233,3 @@ pgp_get_keyid(MBuf *pgp_data, char *dst)
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-internal.c,v 1.3 2005/08/13 02:06:20 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-internal.c,v 1.4 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
@ -35,27 +35,27 @@
|
|||||||
#include "pgp.h"
|
#include "pgp.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
|
pgp_elgamal_encrypt(PGP_PubKey * pk, PGP_MPI * _m,
|
||||||
PGP_MPI **c1_p, PGP_MPI **c2_p)
|
PGP_MPI ** c1_p, PGP_MPI ** c2_p)
|
||||||
{
|
{
|
||||||
return PXE_PGP_NO_BIGNUM;
|
return PXE_PGP_NO_BIGNUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2,
|
pgp_elgamal_decrypt(PGP_PubKey * pk, PGP_MPI * _c1, PGP_MPI * _c2,
|
||||||
PGP_MPI **msg_p)
|
PGP_MPI ** msg_p)
|
||||||
{
|
{
|
||||||
return PXE_PGP_NO_BIGNUM;
|
return PXE_PGP_NO_BIGNUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *m, PGP_MPI **c)
|
int
|
||||||
|
pgp_rsa_encrypt(PGP_PubKey * pk, PGP_MPI * m, PGP_MPI ** c)
|
||||||
{
|
{
|
||||||
return PXE_PGP_NO_BIGNUM;
|
return PXE_PGP_NO_BIGNUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *c, PGP_MPI **m)
|
int
|
||||||
|
pgp_rsa_decrypt(PGP_PubKey * pk, PGP_MPI * c, PGP_MPI ** m)
|
||||||
{
|
{
|
||||||
return PXE_PGP_NO_BIGNUM;
|
return PXE_PGP_NO_BIGNUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-openssl.c,v 1.3 2005/08/13 02:06:20 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi-openssl.c,v 1.4 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
@ -37,15 +37,16 @@
|
|||||||
#include "pgp.h"
|
#include "pgp.h"
|
||||||
|
|
||||||
static BIGNUM *
|
static BIGNUM *
|
||||||
mpi_to_bn(PGP_MPI *n)
|
mpi_to_bn(PGP_MPI * n)
|
||||||
{
|
{
|
||||||
BIGNUM *bn = BN_bin2bn(n->data, n->bytes, NULL);
|
BIGNUM *bn = BN_bin2bn(n->data, n->bytes, NULL);
|
||||||
|
|
||||||
if (!bn)
|
if (!bn)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (BN_num_bits(bn) != n->bits)
|
if (BN_num_bits(bn) != n->bits)
|
||||||
{
|
{
|
||||||
px_debug("mpi_to_bn: bignum conversion failed: mpi=%d, bn=%d",
|
px_debug("mpi_to_bn: bignum conversion failed: mpi=%d, bn=%d",
|
||||||
n->bits, BN_num_bits(bn));
|
n->bits, BN_num_bits(bn));
|
||||||
BN_clear_free(bn);
|
BN_clear_free(bn);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -55,8 +56,8 @@ mpi_to_bn(PGP_MPI *n)
|
|||||||
static PGP_MPI *
|
static PGP_MPI *
|
||||||
bn_to_mpi(BIGNUM *bn)
|
bn_to_mpi(BIGNUM *bn)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_MPI *n;
|
PGP_MPI *n;
|
||||||
|
|
||||||
res = pgp_mpi_alloc(BN_num_bits(bn), &n);
|
res = pgp_mpi_alloc(BN_num_bits(bn), &n);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -65,7 +66,7 @@ bn_to_mpi(BIGNUM *bn)
|
|||||||
if (BN_num_bytes(bn) != n->bytes)
|
if (BN_num_bytes(bn) != n->bytes)
|
||||||
{
|
{
|
||||||
px_debug("bn_to_mpi: bignum conversion failed: bn=%d, mpi=%d",
|
px_debug("bn_to_mpi: bignum conversion failed: bn=%d, mpi=%d",
|
||||||
BN_num_bytes(bn), n->bytes);
|
BN_num_bytes(bn), n->bytes);
|
||||||
pgp_mpi_free(n);
|
pgp_mpi_free(n);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -81,7 +82,7 @@ bn_to_mpi(BIGNUM *bn)
|
|||||||
*
|
*
|
||||||
* Until I research it further, I just mimic gpg behaviour.
|
* Until I research it further, I just mimic gpg behaviour.
|
||||||
* It has a special mapping table, for values <= 5120,
|
* It has a special mapping table, for values <= 5120,
|
||||||
* above that it uses 'arbitrary high number'. Following
|
* above that it uses 'arbitrary high number'. Following
|
||||||
* algorihm hovers 10-70 bits above gpg values. And for
|
* algorihm hovers 10-70 bits above gpg values. And for
|
||||||
* larger p, it uses gpg's algorihm.
|
* larger p, it uses gpg's algorihm.
|
||||||
*
|
*
|
||||||
@ -98,20 +99,20 @@ decide_k_bits(int p_bits)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
|
pgp_elgamal_encrypt(PGP_PubKey * pk, PGP_MPI * _m,
|
||||||
PGP_MPI **c1_p, PGP_MPI **c2_p)
|
PGP_MPI ** c1_p, PGP_MPI ** c2_p)
|
||||||
{
|
{
|
||||||
int res = PXE_PGP_MATH_FAILED;
|
int res = PXE_PGP_MATH_FAILED;
|
||||||
int k_bits;
|
int k_bits;
|
||||||
BIGNUM *m = mpi_to_bn(_m);
|
BIGNUM *m = mpi_to_bn(_m);
|
||||||
BIGNUM *p = mpi_to_bn(pk->pub.elg.p);
|
BIGNUM *p = mpi_to_bn(pk->pub.elg.p);
|
||||||
BIGNUM *g = mpi_to_bn(pk->pub.elg.g);
|
BIGNUM *g = mpi_to_bn(pk->pub.elg.g);
|
||||||
BIGNUM *y = mpi_to_bn(pk->pub.elg.y);
|
BIGNUM *y = mpi_to_bn(pk->pub.elg.y);
|
||||||
BIGNUM *k = BN_new();
|
BIGNUM *k = BN_new();
|
||||||
BIGNUM *yk = BN_new();
|
BIGNUM *yk = BN_new();
|
||||||
BIGNUM *c1 = BN_new();
|
BIGNUM *c1 = BN_new();
|
||||||
BIGNUM *c2 = BN_new();
|
BIGNUM *c2 = BN_new();
|
||||||
BN_CTX *tmp = BN_CTX_new();
|
BN_CTX *tmp = BN_CTX_new();
|
||||||
|
|
||||||
if (!m || !p || !g || !y || !k || !yk || !c1 || !c2 || !tmp)
|
if (!m || !p || !g || !y || !k || !yk || !c1 || !c2 || !tmp)
|
||||||
goto err;
|
goto err;
|
||||||
@ -124,8 +125,7 @@ pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* c1 = g^k
|
* c1 = g^k c2 = m * y^k
|
||||||
* c2 = m * y^k
|
|
||||||
*/
|
*/
|
||||||
if (!BN_mod_exp(c1, g, k, p, tmp))
|
if (!BN_mod_exp(c1, g, k, p, tmp))
|
||||||
goto err;
|
goto err;
|
||||||
@ -140,31 +140,40 @@ pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
|
|||||||
if (*c1_p && *c2_p)
|
if (*c1_p && *c2_p)
|
||||||
res = 0;
|
res = 0;
|
||||||
err:
|
err:
|
||||||
if (tmp) BN_CTX_free(tmp);
|
if (tmp)
|
||||||
if (c2) BN_clear_free(c2);
|
BN_CTX_free(tmp);
|
||||||
if (c1) BN_clear_free(c1);
|
if (c2)
|
||||||
if (yk) BN_clear_free(yk);
|
BN_clear_free(c2);
|
||||||
if (k) BN_clear_free(k);
|
if (c1)
|
||||||
if (y) BN_clear_free(y);
|
BN_clear_free(c1);
|
||||||
if (g) BN_clear_free(g);
|
if (yk)
|
||||||
if (p) BN_clear_free(p);
|
BN_clear_free(yk);
|
||||||
if (m) BN_clear_free(m);
|
if (k)
|
||||||
|
BN_clear_free(k);
|
||||||
|
if (y)
|
||||||
|
BN_clear_free(y);
|
||||||
|
if (g)
|
||||||
|
BN_clear_free(g);
|
||||||
|
if (p)
|
||||||
|
BN_clear_free(p);
|
||||||
|
if (m)
|
||||||
|
BN_clear_free(m);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2,
|
pgp_elgamal_decrypt(PGP_PubKey * pk, PGP_MPI * _c1, PGP_MPI * _c2,
|
||||||
PGP_MPI **msg_p)
|
PGP_MPI ** msg_p)
|
||||||
{
|
{
|
||||||
int res = PXE_PGP_MATH_FAILED;
|
int res = PXE_PGP_MATH_FAILED;
|
||||||
BIGNUM *c1 = mpi_to_bn(_c1);
|
BIGNUM *c1 = mpi_to_bn(_c1);
|
||||||
BIGNUM *c2 = mpi_to_bn(_c2);
|
BIGNUM *c2 = mpi_to_bn(_c2);
|
||||||
BIGNUM *p = mpi_to_bn(pk->pub.elg.p);
|
BIGNUM *p = mpi_to_bn(pk->pub.elg.p);
|
||||||
BIGNUM *x = mpi_to_bn(pk->sec.elg.x);
|
BIGNUM *x = mpi_to_bn(pk->sec.elg.x);
|
||||||
BIGNUM *c1x = BN_new();
|
BIGNUM *c1x = BN_new();
|
||||||
BIGNUM *div = BN_new();
|
BIGNUM *div = BN_new();
|
||||||
BIGNUM *m = BN_new();
|
BIGNUM *m = BN_new();
|
||||||
BN_CTX *tmp = BN_CTX_new();
|
BN_CTX *tmp = BN_CTX_new();
|
||||||
|
|
||||||
if (!c1 || !c2 || !p || !x || !c1x || !div || !m || !tmp)
|
if (!c1 || !c2 || !p || !x || !c1x || !div || !m || !tmp)
|
||||||
goto err;
|
goto err;
|
||||||
@ -184,26 +193,34 @@ pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2,
|
|||||||
if (*msg_p)
|
if (*msg_p)
|
||||||
res = 0;
|
res = 0;
|
||||||
err:
|
err:
|
||||||
if (tmp) BN_CTX_free(tmp);
|
if (tmp)
|
||||||
if (m) BN_clear_free(m);
|
BN_CTX_free(tmp);
|
||||||
if (div) BN_clear_free(div);
|
if (m)
|
||||||
if (c1x) BN_clear_free(c1x);
|
BN_clear_free(m);
|
||||||
if (x) BN_clear_free(x);
|
if (div)
|
||||||
if (p) BN_clear_free(p);
|
BN_clear_free(div);
|
||||||
if (c2) BN_clear_free(c2);
|
if (c1x)
|
||||||
if (c1) BN_clear_free(c1);
|
BN_clear_free(c1x);
|
||||||
|
if (x)
|
||||||
|
BN_clear_free(x);
|
||||||
|
if (p)
|
||||||
|
BN_clear_free(p);
|
||||||
|
if (c2)
|
||||||
|
BN_clear_free(c2);
|
||||||
|
if (c1)
|
||||||
|
BN_clear_free(c1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *_m, PGP_MPI **c_p)
|
pgp_rsa_encrypt(PGP_PubKey * pk, PGP_MPI * _m, PGP_MPI ** c_p)
|
||||||
{
|
{
|
||||||
int res = PXE_PGP_MATH_FAILED;
|
int res = PXE_PGP_MATH_FAILED;
|
||||||
BIGNUM *m = mpi_to_bn(_m);
|
BIGNUM *m = mpi_to_bn(_m);
|
||||||
BIGNUM *e = mpi_to_bn(pk->pub.rsa.e);
|
BIGNUM *e = mpi_to_bn(pk->pub.rsa.e);
|
||||||
BIGNUM *n = mpi_to_bn(pk->pub.rsa.n);
|
BIGNUM *n = mpi_to_bn(pk->pub.rsa.n);
|
||||||
BIGNUM *c = BN_new();
|
BIGNUM *c = BN_new();
|
||||||
BN_CTX *tmp = BN_CTX_new();
|
BN_CTX *tmp = BN_CTX_new();
|
||||||
|
|
||||||
if (!m || !e || !n || !c || !tmp)
|
if (!m || !e || !n || !c || !tmp)
|
||||||
goto err;
|
goto err;
|
||||||
@ -218,23 +235,28 @@ pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *_m, PGP_MPI **c_p)
|
|||||||
if (*c_p)
|
if (*c_p)
|
||||||
res = 0;
|
res = 0;
|
||||||
err:
|
err:
|
||||||
if (tmp) BN_CTX_free(tmp);
|
if (tmp)
|
||||||
if (c) BN_clear_free(c);
|
BN_CTX_free(tmp);
|
||||||
if (n) BN_clear_free(n);
|
if (c)
|
||||||
if (e) BN_clear_free(e);
|
BN_clear_free(c);
|
||||||
if (m) BN_clear_free(m);
|
if (n)
|
||||||
|
BN_clear_free(n);
|
||||||
|
if (e)
|
||||||
|
BN_clear_free(e);
|
||||||
|
if (m)
|
||||||
|
BN_clear_free(m);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *_c, PGP_MPI **m_p)
|
pgp_rsa_decrypt(PGP_PubKey * pk, PGP_MPI * _c, PGP_MPI ** m_p)
|
||||||
{
|
{
|
||||||
int res = PXE_PGP_MATH_FAILED;
|
int res = PXE_PGP_MATH_FAILED;
|
||||||
BIGNUM *c = mpi_to_bn(_c);
|
BIGNUM *c = mpi_to_bn(_c);
|
||||||
BIGNUM *d = mpi_to_bn(pk->sec.rsa.d);
|
BIGNUM *d = mpi_to_bn(pk->sec.rsa.d);
|
||||||
BIGNUM *n = mpi_to_bn(pk->pub.rsa.n);
|
BIGNUM *n = mpi_to_bn(pk->pub.rsa.n);
|
||||||
BIGNUM *m = BN_new();
|
BIGNUM *m = BN_new();
|
||||||
BN_CTX *tmp = BN_CTX_new();
|
BN_CTX *tmp = BN_CTX_new();
|
||||||
|
|
||||||
if (!m || !d || !n || !c || !tmp)
|
if (!m || !d || !n || !c || !tmp)
|
||||||
goto err;
|
goto err;
|
||||||
@ -249,11 +271,15 @@ pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *_c, PGP_MPI **m_p)
|
|||||||
if (*m_p)
|
if (*m_p)
|
||||||
res = 0;
|
res = 0;
|
||||||
err:
|
err:
|
||||||
if (tmp) BN_CTX_free(tmp);
|
if (tmp)
|
||||||
if (m) BN_clear_free(m);
|
BN_CTX_free(tmp);
|
||||||
if (n) BN_clear_free(n);
|
if (m)
|
||||||
if (d) BN_clear_free(d);
|
BN_clear_free(m);
|
||||||
if (c) BN_clear_free(c);
|
if (n)
|
||||||
|
BN_clear_free(n);
|
||||||
|
if (d)
|
||||||
|
BN_clear_free(d);
|
||||||
|
if (c)
|
||||||
|
BN_clear_free(c);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi.c,v 1.3 2005/08/13 02:06:20 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-mpi.c,v 1.4 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
@ -34,10 +34,12 @@
|
|||||||
#include "mbuf.h"
|
#include "mbuf.h"
|
||||||
#include "pgp.h"
|
#include "pgp.h"
|
||||||
|
|
||||||
int pgp_mpi_alloc(int bits, PGP_MPI **mpi)
|
int
|
||||||
|
pgp_mpi_alloc(int bits, PGP_MPI ** mpi)
|
||||||
{
|
{
|
||||||
PGP_MPI *n;
|
PGP_MPI *n;
|
||||||
int len = (bits + 7) / 8;
|
int len = (bits + 7) / 8;
|
||||||
|
|
||||||
if (bits < 0 || bits > 0xFFFF)
|
if (bits < 0 || bits > 0xFFFF)
|
||||||
{
|
{
|
||||||
px_debug("pgp_mpi_alloc: unreasonable request: bits=%d", bits);
|
px_debug("pgp_mpi_alloc: unreasonable request: bits=%d", bits);
|
||||||
@ -46,15 +48,16 @@ int pgp_mpi_alloc(int bits, PGP_MPI **mpi)
|
|||||||
n = px_alloc(sizeof(*n) + len);
|
n = px_alloc(sizeof(*n) + len);
|
||||||
n->bits = bits;
|
n->bits = bits;
|
||||||
n->bytes = len;
|
n->bytes = len;
|
||||||
n->data = (uint8*)(n) + sizeof(*n);
|
n->data = (uint8 *) (n) + sizeof(*n);
|
||||||
*mpi = n;
|
*mpi = n;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pgp_mpi_create(uint8 *data, int bits, PGP_MPI **mpi)
|
int
|
||||||
|
pgp_mpi_create(uint8 *data, int bits, PGP_MPI ** mpi)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_MPI *n;
|
PGP_MPI *n;
|
||||||
|
|
||||||
res = pgp_mpi_alloc(bits, &n);
|
res = pgp_mpi_alloc(bits, &n);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -64,7 +67,8 @@ int pgp_mpi_create(uint8 *data, int bits, PGP_MPI **mpi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pgp_mpi_free(PGP_MPI *mpi)
|
int
|
||||||
|
pgp_mpi_free(PGP_MPI * mpi)
|
||||||
{
|
{
|
||||||
if (mpi == NULL)
|
if (mpi == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
@ -73,17 +77,18 @@ int pgp_mpi_free(PGP_MPI *mpi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pgp_mpi_read(PullFilter *src, PGP_MPI **mpi)
|
int
|
||||||
|
pgp_mpi_read(PullFilter * src, PGP_MPI ** mpi)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
uint8 hdr[2];
|
uint8 hdr[2];
|
||||||
int bits;
|
int bits;
|
||||||
PGP_MPI *n;
|
PGP_MPI *n;
|
||||||
|
|
||||||
res = pullf_read_fixed(src, 2, hdr);
|
res = pullf_read_fixed(src, 2, hdr);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
bits = ((unsigned)hdr[0] << 8) + hdr[1];
|
bits = ((unsigned) hdr[0] << 8) + hdr[1];
|
||||||
|
|
||||||
res = pgp_mpi_alloc(bits, &n);
|
res = pgp_mpi_alloc(bits, &n);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -97,10 +102,11 @@ int pgp_mpi_read(PullFilter *src, PGP_MPI **mpi)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pgp_mpi_write(PushFilter *dst, PGP_MPI *n)
|
int
|
||||||
|
pgp_mpi_write(PushFilter * dst, PGP_MPI * n)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
uint8 buf[2];
|
uint8 buf[2];
|
||||||
|
|
||||||
buf[0] = n->bits >> 8;
|
buf[0] = n->bits >> 8;
|
||||||
buf[1] = n->bits & 0xFF;
|
buf[1] = n->bits & 0xFF;
|
||||||
@ -110,9 +116,10 @@ int pgp_mpi_write(PushFilter *dst, PGP_MPI *n)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pgp_mpi_hash(PX_MD *md, PGP_MPI *n)
|
int
|
||||||
|
pgp_mpi_hash(PX_MD * md, PGP_MPI * n)
|
||||||
{
|
{
|
||||||
uint8 buf[2];
|
uint8 buf[2];
|
||||||
|
|
||||||
buf[0] = n->bits >> 8;
|
buf[0] = n->bits >> 8;
|
||||||
buf[1] = n->bits & 0xFF;
|
buf[1] = n->bits & 0xFF;
|
||||||
@ -122,9 +129,10 @@ int pgp_mpi_hash(PX_MD *md, PGP_MPI *n)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned pgp_mpi_cksum(unsigned cksum, PGP_MPI *n)
|
unsigned
|
||||||
|
pgp_mpi_cksum(unsigned cksum, PGP_MPI * n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cksum += n->bits >> 8;
|
cksum += n->bits >> 8;
|
||||||
cksum += n->bits & 0xFF;
|
cksum += n->bits & 0xFF;
|
||||||
@ -133,4 +141,3 @@ unsigned pgp_mpi_cksum(unsigned cksum, PGP_MPI *n)
|
|||||||
|
|
||||||
return cksum & 0xFFFF;
|
return cksum & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pgsql.c,v 1.5 2005/09/24 19:14:04 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pgsql.c,v 1.6 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -42,20 +42,20 @@
|
|||||||
/*
|
/*
|
||||||
* public functions
|
* public functions
|
||||||
*/
|
*/
|
||||||
Datum pgp_sym_encrypt_text(PG_FUNCTION_ARGS);
|
Datum pgp_sym_encrypt_text(PG_FUNCTION_ARGS);
|
||||||
Datum pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS);
|
Datum pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS);
|
||||||
Datum pgp_sym_decrypt_text(PG_FUNCTION_ARGS);
|
Datum pgp_sym_decrypt_text(PG_FUNCTION_ARGS);
|
||||||
Datum pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS);
|
Datum pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
Datum pgp_pub_encrypt_text(PG_FUNCTION_ARGS);
|
Datum pgp_pub_encrypt_text(PG_FUNCTION_ARGS);
|
||||||
Datum pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS);
|
Datum pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS);
|
||||||
Datum pgp_pub_decrypt_text(PG_FUNCTION_ARGS);
|
Datum pgp_pub_decrypt_text(PG_FUNCTION_ARGS);
|
||||||
Datum pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS);
|
Datum pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
Datum pgp_key_id_w(PG_FUNCTION_ARGS);
|
Datum pgp_key_id_w(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
Datum pg_armor(PG_FUNCTION_ARGS);
|
Datum pg_armor(PG_FUNCTION_ARGS);
|
||||||
Datum pg_dearmor(PG_FUNCTION_ARGS);
|
Datum pg_dearmor(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
/* function headers */
|
/* function headers */
|
||||||
|
|
||||||
@ -89,9 +89,10 @@ PG_FUNCTION_INFO_V1(pg_dearmor);
|
|||||||
/*
|
/*
|
||||||
* Mix a block of data into RNG.
|
* Mix a block of data into RNG.
|
||||||
*/
|
*/
|
||||||
static void add_block_entropy(PX_MD *md, text *data)
|
static void
|
||||||
|
add_block_entropy(PX_MD * md, text *data)
|
||||||
{
|
{
|
||||||
uint8 sha1[20];
|
uint8 sha1[20];
|
||||||
|
|
||||||
px_md_reset(md);
|
px_md_reset(md);
|
||||||
px_md_update(md, (uint8 *) VARDATA(data), VARSIZE(data) - VARHDRSZ);
|
px_md_update(md, (uint8 *) VARDATA(data), VARSIZE(data) - VARHDRSZ);
|
||||||
@ -103,13 +104,14 @@ static void add_block_entropy(PX_MD *md, text *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mix user data into RNG. It is for user own interests to have
|
* Mix user data into RNG. It is for user own interests to have
|
||||||
* RNG state shuffled.
|
* RNG state shuffled.
|
||||||
*/
|
*/
|
||||||
static void add_entropy(text *data1, text *data2, text *data3)
|
static void
|
||||||
|
add_entropy(text *data1, text *data2, text *data3)
|
||||||
{
|
{
|
||||||
PX_MD *md;
|
PX_MD *md;
|
||||||
uint8 rnd[3];
|
uint8 rnd[3];
|
||||||
|
|
||||||
if (!data1 && !data2 && !data3)
|
if (!data1 && !data2 && !data3)
|
||||||
return;
|
return;
|
||||||
@ -123,8 +125,8 @@ static void add_entropy(text *data1, text *data2, text *data3)
|
|||||||
/*
|
/*
|
||||||
* Try to make the feeding unpredictable.
|
* Try to make the feeding unpredictable.
|
||||||
*
|
*
|
||||||
* Prefer data over keys, as it's rather likely
|
* Prefer data over keys, as it's rather likely that key is same in several
|
||||||
* that key is same in several calls.
|
* calls.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* chance: 7/8 */
|
/* chance: 7/8 */
|
||||||
@ -146,13 +148,14 @@ static void add_entropy(text *data1, text *data2, text *data3)
|
|||||||
/*
|
/*
|
||||||
* returns src in case of no conversion or error
|
* returns src in case of no conversion or error
|
||||||
*/
|
*/
|
||||||
static text *convert_charset(text *src, int cset_from, int cset_to)
|
static text *
|
||||||
|
convert_charset(text *src, int cset_from, int cset_to)
|
||||||
{
|
{
|
||||||
int src_len = VARSIZE(src) - VARHDRSZ;
|
int src_len = VARSIZE(src) - VARHDRSZ;
|
||||||
int dst_len;
|
int dst_len;
|
||||||
unsigned char *dst;
|
unsigned char *dst;
|
||||||
unsigned char *csrc = (unsigned char *) VARDATA(src);
|
unsigned char *csrc = (unsigned char *) VARDATA(src);
|
||||||
text *res;
|
text *res;
|
||||||
|
|
||||||
dst = pg_do_encoding_conversion(csrc, src_len, cset_from, cset_to);
|
dst = pg_do_encoding_conversion(csrc, src_len, cset_from, cset_to);
|
||||||
if (dst == csrc)
|
if (dst == csrc)
|
||||||
@ -166,12 +169,14 @@ static text *convert_charset(text *src, int cset_from, int cset_to)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static text *convert_from_utf8(text *src)
|
static text *
|
||||||
|
convert_from_utf8(text *src)
|
||||||
{
|
{
|
||||||
return convert_charset(src, PG_UTF8, GetDatabaseEncoding());
|
return convert_charset(src, PG_UTF8, GetDatabaseEncoding());
|
||||||
}
|
}
|
||||||
|
|
||||||
static text *convert_to_utf8(text *src)
|
static text *
|
||||||
|
convert_to_utf8(text *src)
|
||||||
{
|
{
|
||||||
return convert_charset(src, GetDatabaseEncoding(), PG_UTF8);
|
return convert_charset(src, GetDatabaseEncoding(), PG_UTF8);
|
||||||
}
|
}
|
||||||
@ -186,20 +191,22 @@ clear_and_pfree(text *p)
|
|||||||
/*
|
/*
|
||||||
* expect-* arguments storage
|
* expect-* arguments storage
|
||||||
*/
|
*/
|
||||||
struct debug_expect {
|
struct debug_expect
|
||||||
int debug;
|
{
|
||||||
int expect;
|
int debug;
|
||||||
int cipher_algo;
|
int expect;
|
||||||
int s2k_mode;
|
int cipher_algo;
|
||||||
int s2k_cipher_algo;
|
int s2k_mode;
|
||||||
int s2k_digest_algo;
|
int s2k_cipher_algo;
|
||||||
int compress_algo;
|
int s2k_digest_algo;
|
||||||
int use_sess_key;
|
int compress_algo;
|
||||||
int disable_mdc;
|
int use_sess_key;
|
||||||
int unicode_mode;
|
int disable_mdc;
|
||||||
|
int unicode_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fill_expect(struct debug_expect *ex, int text_mode)
|
static void
|
||||||
|
fill_expect(struct debug_expect * ex, int text_mode)
|
||||||
{
|
{
|
||||||
ex->debug = 0;
|
ex->debug = 0;
|
||||||
ex->expect = 0;
|
ex->expect = 0;
|
||||||
@ -222,7 +229,8 @@ static void fill_expect(struct debug_expect *ex, int text_mode)
|
|||||||
if (ex->arg >= 0 && ex->arg != ctx->arg) EX_MSG(arg); \
|
if (ex->arg >= 0 && ex->arg != ctx->arg) EX_MSG(arg); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static void check_expect(PGP_Context *ctx, struct debug_expect *ex)
|
static void
|
||||||
|
check_expect(PGP_Context * ctx, struct debug_expect * ex)
|
||||||
{
|
{
|
||||||
EX_CHECK(cipher_algo);
|
EX_CHECK(cipher_algo);
|
||||||
EX_CHECK(s2k_mode);
|
EX_CHECK(s2k_mode);
|
||||||
@ -235,15 +243,18 @@ static void check_expect(PGP_Context *ctx, struct debug_expect *ex)
|
|||||||
EX_CHECK(unicode_mode);
|
EX_CHECK(unicode_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_debug(const char *msg)
|
static void
|
||||||
|
show_debug(const char *msg)
|
||||||
{
|
{
|
||||||
ereport(NOTICE, (errmsg("dbg: %s", msg)));
|
ereport(NOTICE, (errmsg("dbg: %s", msg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_arg(PGP_Context *ctx, char *key, char*val,
|
static int
|
||||||
struct debug_expect *ex)
|
set_arg(PGP_Context * ctx, char *key, char *val,
|
||||||
|
struct debug_expect * ex)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
if (strcmp(key, "cipher-algo") == 0)
|
if (strcmp(key, "cipher-algo") == 0)
|
||||||
res = pgp_set_cipher_algo(ctx, val);
|
res = pgp_set_cipher_algo(ctx, val);
|
||||||
else if (strcmp(key, "disable-mdc") == 0)
|
else if (strcmp(key, "disable-mdc") == 0)
|
||||||
@ -314,11 +325,12 @@ static int set_arg(PGP_Context *ctx, char *key, char*val,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find next word. Handle ',' and '=' as words. Skip whitespace.
|
* Find next word. Handle ',' and '=' as words. Skip whitespace.
|
||||||
* Put word info into res_p, res_len.
|
* Put word info into res_p, res_len.
|
||||||
* Returns ptr to next word.
|
* Returns ptr to next word.
|
||||||
*/
|
*/
|
||||||
static char *getword(char *p, char **res_p, int *res_len)
|
static char *
|
||||||
|
getword(char *p, char **res_p, int *res_len)
|
||||||
{
|
{
|
||||||
/* whitespace at start */
|
/* whitespace at start */
|
||||||
while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
|
while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
|
||||||
@ -330,7 +342,7 @@ static char *getword(char *p, char **res_p, int *res_len)
|
|||||||
p++;
|
p++;
|
||||||
else
|
else
|
||||||
while (*p && !(*p == ' ' || *p == '\t' || *p == '\n'
|
while (*p && !(*p == ' ' || *p == '\t' || *p == '\n'
|
||||||
|| *p == '=' || *p == ','))
|
|| *p == '=' || *p == ','))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
/* word end */
|
/* word end */
|
||||||
@ -346,11 +358,15 @@ static char *getword(char *p, char **res_p, int *res_len)
|
|||||||
/*
|
/*
|
||||||
* Convert to lowercase asciiz string.
|
* Convert to lowercase asciiz string.
|
||||||
*/
|
*/
|
||||||
static char *downcase_convert(const uint8 *s, int len)
|
static char *
|
||||||
|
downcase_convert(const uint8 *s, int len)
|
||||||
{
|
{
|
||||||
int c, i;
|
int c,
|
||||||
char *res = palloc(len + 1);
|
i;
|
||||||
for (i = 0; i < len; i++) {
|
char *res = palloc(len + 1);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
c = s[i];
|
c = s[i];
|
||||||
if (c >= 'A' && c <= 'Z')
|
if (c >= 'A' && c <= 'Z')
|
||||||
c += 'a' - 'A';
|
c += 'a' - 'A';
|
||||||
@ -360,14 +376,17 @@ static char *downcase_convert(const uint8 *s, int len)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_args(PGP_Context *ctx, uint8 *args, int arg_len,
|
static int
|
||||||
struct debug_expect *ex)
|
parse_args(PGP_Context * ctx, uint8 *args, int arg_len,
|
||||||
|
struct debug_expect * ex)
|
||||||
{
|
{
|
||||||
char *str = downcase_convert(args, arg_len);
|
char *str = downcase_convert(args, arg_len);
|
||||||
char *key, *val;
|
char *key,
|
||||||
int key_len, val_len;
|
*val;
|
||||||
int res = 0;
|
int key_len,
|
||||||
char *p = str;
|
val_len;
|
||||||
|
int res = 0;
|
||||||
|
char *p = str;
|
||||||
|
|
||||||
while (*p)
|
while (*p)
|
||||||
{
|
{
|
||||||
@ -403,10 +422,10 @@ create_mbuf_from_vardata(text *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_work(PGP_Context **ctx_p, int is_text,
|
init_work(PGP_Context ** ctx_p, int is_text,
|
||||||
text *args, struct debug_expect *ex)
|
text *args, struct debug_expect * ex)
|
||||||
{
|
{
|
||||||
int err = pgp_init(ctx_p);
|
int err = pgp_init(ctx_p);
|
||||||
|
|
||||||
fill_expect(ex, is_text);
|
fill_expect(ex, is_text);
|
||||||
|
|
||||||
@ -429,17 +448,18 @@ init_work(PGP_Context **ctx_p, int is_text,
|
|||||||
|
|
||||||
static bytea *
|
static bytea *
|
||||||
encrypt_internal(int is_pubenc, int is_text,
|
encrypt_internal(int is_pubenc, int is_text,
|
||||||
text *data, text *key, text *args)
|
text *data, text *key, text *args)
|
||||||
{
|
{
|
||||||
MBuf *src, *dst;
|
MBuf *src,
|
||||||
uint8 tmp[VARHDRSZ];
|
*dst;
|
||||||
uint8 *restmp;
|
uint8 tmp[VARHDRSZ];
|
||||||
bytea *res;
|
uint8 *restmp;
|
||||||
int res_len;
|
bytea *res;
|
||||||
|
int res_len;
|
||||||
PGP_Context *ctx;
|
PGP_Context *ctx;
|
||||||
int err;
|
int err;
|
||||||
struct debug_expect ex;
|
struct debug_expect ex;
|
||||||
text *tmp_data = NULL;
|
text *tmp_data = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add data and key info RNG.
|
* Add data and key info RNG.
|
||||||
@ -470,9 +490,10 @@ encrypt_internal(int is_pubenc, int is_text,
|
|||||||
*/
|
*/
|
||||||
if (is_pubenc)
|
if (is_pubenc)
|
||||||
{
|
{
|
||||||
MBuf *kbuf = create_mbuf_from_vardata(key);
|
MBuf *kbuf = create_mbuf_from_vardata(key);
|
||||||
|
|
||||||
err = pgp_set_pubkey(ctx, kbuf,
|
err = pgp_set_pubkey(ctx, kbuf,
|
||||||
NULL, 0, 0);
|
NULL, 0, 0);
|
||||||
mbuf_free(kbuf);
|
mbuf_free(kbuf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -520,17 +541,18 @@ encrypt_internal(int is_pubenc, int is_text,
|
|||||||
|
|
||||||
static bytea *
|
static bytea *
|
||||||
decrypt_internal(int is_pubenc, int need_text, text *data,
|
decrypt_internal(int is_pubenc, int need_text, text *data,
|
||||||
text *key, text *keypsw, text *args)
|
text *key, text *keypsw, text *args)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
MBuf *src = NULL, *dst = NULL;
|
MBuf *src = NULL,
|
||||||
uint8 tmp[VARHDRSZ];
|
*dst = NULL;
|
||||||
uint8 *restmp;
|
uint8 tmp[VARHDRSZ];
|
||||||
bytea *res;
|
uint8 *restmp;
|
||||||
int res_len;
|
bytea *res;
|
||||||
|
int res_len;
|
||||||
PGP_Context *ctx = NULL;
|
PGP_Context *ctx = NULL;
|
||||||
struct debug_expect ex;
|
struct debug_expect ex;
|
||||||
int got_unicode = 0;
|
int got_unicode = 0;
|
||||||
|
|
||||||
|
|
||||||
init_work(&ctx, need_text, args, &ex);
|
init_work(&ctx, need_text, args, &ex);
|
||||||
@ -549,9 +571,10 @@ decrypt_internal(int is_pubenc, int need_text, text *data,
|
|||||||
*/
|
*/
|
||||||
if (is_pubenc)
|
if (is_pubenc)
|
||||||
{
|
{
|
||||||
uint8 *psw = NULL;
|
uint8 *psw = NULL;
|
||||||
int psw_len = 0;
|
int psw_len = 0;
|
||||||
MBuf *kbuf;
|
MBuf *kbuf;
|
||||||
|
|
||||||
if (keypsw)
|
if (keypsw)
|
||||||
{
|
{
|
||||||
psw = (uint8 *) VARDATA(keypsw);
|
psw = (uint8 *) VARDATA(keypsw);
|
||||||
@ -608,7 +631,8 @@ out:
|
|||||||
|
|
||||||
if (need_text && got_unicode)
|
if (need_text && got_unicode)
|
||||||
{
|
{
|
||||||
text *utf = convert_from_utf8(res);
|
text *utf = convert_from_utf8(res);
|
||||||
|
|
||||||
if (utf != res)
|
if (utf != res)
|
||||||
{
|
{
|
||||||
clear_and_pfree(res);
|
clear_and_pfree(res);
|
||||||
@ -927,4 +951,3 @@ pgp_key_id_w(PG_FUNCTION_ARGS)
|
|||||||
PG_FREE_IF_COPY(data, 0);
|
PG_FREE_IF_COPY(data, 0);
|
||||||
PG_RETURN_TEXT_P(res);
|
PG_RETURN_TEXT_P(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubdec.c,v 1.4 2005/08/13 02:06:20 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubdec.c,v 1.5 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
@ -42,9 +42,9 @@
|
|||||||
static uint8 *
|
static uint8 *
|
||||||
check_eme_pkcs1_v15(uint8 *data, int len)
|
check_eme_pkcs1_v15(uint8 *data, int len)
|
||||||
{
|
{
|
||||||
uint8 *data_end = data + len;
|
uint8 *data_end = data + len;
|
||||||
uint8 *p = data;
|
uint8 *p = data;
|
||||||
int rnd = 0;
|
int rnd = 0;
|
||||||
|
|
||||||
if (len < 1 + 8 + 1)
|
if (len < 1 + 8 + 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -52,7 +52,8 @@ check_eme_pkcs1_v15(uint8 *data, int len)
|
|||||||
if (*p++ != 2)
|
if (*p++ != 2)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while (p < data_end && *p) {
|
while (p < data_end && *p)
|
||||||
|
{
|
||||||
p++;
|
p++;
|
||||||
rnd++;
|
rnd++;
|
||||||
}
|
}
|
||||||
@ -73,8 +74,9 @@ check_eme_pkcs1_v15(uint8 *data, int len)
|
|||||||
static int
|
static int
|
||||||
control_cksum(uint8 *msg, int msglen)
|
control_cksum(uint8 *msg, int msglen)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned my_cksum, got_cksum;
|
unsigned my_cksum,
|
||||||
|
got_cksum;
|
||||||
|
|
||||||
if (msglen < 3)
|
if (msglen < 3)
|
||||||
return PXE_PGP_WRONG_KEY;
|
return PXE_PGP_WRONG_KEY;
|
||||||
@ -83,8 +85,9 @@ control_cksum(uint8 *msg, int msglen)
|
|||||||
for (i = 1; i < msglen - 2; i++)
|
for (i = 1; i < msglen - 2; i++)
|
||||||
my_cksum += msg[i];
|
my_cksum += msg[i];
|
||||||
my_cksum &= 0xFFFF;
|
my_cksum &= 0xFFFF;
|
||||||
got_cksum = ((unsigned)(msg[msglen-2]) << 8) + msg[msglen-1];
|
got_cksum = ((unsigned) (msg[msglen - 2]) << 8) + msg[msglen - 1];
|
||||||
if (my_cksum != got_cksum) {
|
if (my_cksum != got_cksum)
|
||||||
|
{
|
||||||
px_debug("pubenc cksum failed");
|
px_debug("pubenc cksum failed");
|
||||||
return PXE_PGP_WRONG_KEY;
|
return PXE_PGP_WRONG_KEY;
|
||||||
}
|
}
|
||||||
@ -92,11 +95,11 @@ control_cksum(uint8 *msg, int msglen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
decrypt_elgamal(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
|
decrypt_elgamal(PGP_PubKey * pk, PullFilter * pkt, PGP_MPI ** m_p)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_MPI *c1 = NULL;
|
PGP_MPI *c1 = NULL;
|
||||||
PGP_MPI *c2 = NULL;
|
PGP_MPI *c2 = NULL;
|
||||||
|
|
||||||
if (pk->algo != PGP_PUB_ELG_ENCRYPT)
|
if (pk->algo != PGP_PUB_ELG_ENCRYPT)
|
||||||
return PXE_PGP_WRONG_KEY;
|
return PXE_PGP_WRONG_KEY;
|
||||||
@ -119,13 +122,13 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
decrypt_rsa(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
|
decrypt_rsa(PGP_PubKey * pk, PullFilter * pkt, PGP_MPI ** m_p)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_MPI *c;
|
PGP_MPI *c;
|
||||||
|
|
||||||
if (pk->algo != PGP_PUB_RSA_ENCRYPT
|
if (pk->algo != PGP_PUB_RSA_ENCRYPT
|
||||||
&& pk->algo != PGP_PUB_RSA_ENCRYPT_SIGN)
|
&& pk->algo != PGP_PUB_RSA_ENCRYPT_SIGN)
|
||||||
return PXE_PGP_WRONG_KEY;
|
return PXE_PGP_WRONG_KEY;
|
||||||
|
|
||||||
/* read rsa encrypted data */
|
/* read rsa encrypted data */
|
||||||
@ -142,28 +145,30 @@ decrypt_rsa(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
|
|||||||
|
|
||||||
/* key id is missing - user is expected to try all keys */
|
/* key id is missing - user is expected to try all keys */
|
||||||
static const uint8
|
static const uint8
|
||||||
any_key[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
any_key[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
|
pgp_parse_pubenc_sesskey(PGP_Context * ctx, PullFilter * pkt)
|
||||||
{
|
{
|
||||||
int ver;
|
int ver;
|
||||||
int algo;
|
int algo;
|
||||||
int res;
|
int res;
|
||||||
uint8 key_id[8];
|
uint8 key_id[8];
|
||||||
PGP_PubKey *pk;
|
PGP_PubKey *pk;
|
||||||
uint8 *msg;
|
uint8 *msg;
|
||||||
int msglen;
|
int msglen;
|
||||||
PGP_MPI *m;
|
PGP_MPI *m;
|
||||||
|
|
||||||
pk = ctx->pub_key;
|
pk = ctx->pub_key;
|
||||||
if (pk == NULL) {
|
if (pk == NULL)
|
||||||
|
{
|
||||||
px_debug("no pubkey?");
|
px_debug("no pubkey?");
|
||||||
return PXE_BUG;
|
return PXE_BUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
GETBYTE(pkt, ver);
|
GETBYTE(pkt, ver);
|
||||||
if (ver != 3) {
|
if (ver != 3)
|
||||||
|
{
|
||||||
px_debug("unknown pubenc_sesskey pkt ver=%d", ver);
|
px_debug("unknown pubenc_sesskey pkt ver=%d", ver);
|
||||||
return PXE_PGP_CORRUPT_DATA;
|
return PXE_PGP_CORRUPT_DATA;
|
||||||
}
|
}
|
||||||
@ -175,7 +180,7 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
|
|||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
if (memcmp(key_id, any_key, 8) != 0
|
if (memcmp(key_id, any_key, 8) != 0
|
||||||
&& memcmp(key_id, pk->key_id, 8) != 0)
|
&& memcmp(key_id, pk->key_id, 8) != 0)
|
||||||
{
|
{
|
||||||
px_debug("key_id's does not match");
|
px_debug("key_id's does not match");
|
||||||
return PXE_PGP_WRONG_KEY;
|
return PXE_PGP_WRONG_KEY;
|
||||||
@ -204,7 +209,8 @@ pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
|
|||||||
* extract message
|
* extract message
|
||||||
*/
|
*/
|
||||||
msg = check_eme_pkcs1_v15(m->data, m->bytes);
|
msg = check_eme_pkcs1_v15(m->data, m->bytes);
|
||||||
if (msg == NULL) {
|
if (msg == NULL)
|
||||||
|
{
|
||||||
px_debug("check_eme_pkcs1_v15 failed");
|
px_debug("check_eme_pkcs1_v15 failed");
|
||||||
res = PXE_PGP_WRONG_KEY;
|
res = PXE_PGP_WRONG_KEY;
|
||||||
goto out;
|
goto out;
|
||||||
@ -228,5 +234,3 @@ out:
|
|||||||
return res;
|
return res;
|
||||||
return pgp_expect_packet_end(pkt);
|
return pgp_expect_packet_end(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* pgp-pubenc.c
|
* pgp-pubenc.c
|
||||||
* Encrypt session key with public key.
|
* Encrypt session key with public key.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2005 Marko Kreen
|
* Copyright (c) 2005 Marko Kreen
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubenc.c,v 1.3 2005/08/13 02:06:20 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubenc.c,v 1.4 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
@ -40,9 +40,10 @@
|
|||||||
static int
|
static int
|
||||||
pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p)
|
pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
uint8 *buf, *p;
|
uint8 *buf,
|
||||||
int pad_len = res_len - 2 - data_len;
|
*p;
|
||||||
|
int pad_len = res_len - 2 - data_len;
|
||||||
|
|
||||||
if (pad_len < 8)
|
if (pad_len < 8)
|
||||||
return PXE_BUG;
|
return PXE_BUG;
|
||||||
@ -85,14 +86,15 @@ pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p, int full_bytes)
|
create_secmsg(PGP_Context * ctx, PGP_MPI ** msg_p, int full_bytes)
|
||||||
{
|
{
|
||||||
uint8 *secmsg;
|
uint8 *secmsg;
|
||||||
int res, i;
|
int res,
|
||||||
unsigned cksum = 0;
|
i;
|
||||||
int klen = ctx->sess_key_len;
|
unsigned cksum = 0;
|
||||||
uint8 *padded = NULL;
|
int klen = ctx->sess_key_len;
|
||||||
PGP_MPI *m = NULL;
|
uint8 *padded = NULL;
|
||||||
|
PGP_MPI *m = NULL;
|
||||||
|
|
||||||
/* calc checksum */
|
/* calc checksum */
|
||||||
for (i = 0; i < klen; i++)
|
for (i = 0; i < klen; i++)
|
||||||
@ -114,7 +116,8 @@ create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p, int full_bytes)
|
|||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
{
|
{
|
||||||
/* first byte will be 0x02 */
|
/* first byte will be 0x02 */
|
||||||
int full_bits = full_bytes * 8 - 6;
|
int full_bits = full_bytes * 8 - 6;
|
||||||
|
|
||||||
res = pgp_mpi_create(padded, full_bits, &m);
|
res = pgp_mpi_create(padded, full_bits, &m);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,10 +136,12 @@ create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p, int full_bytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
encrypt_and_write_elgamal(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt)
|
encrypt_and_write_elgamal(PGP_Context * ctx, PGP_PubKey * pk, PushFilter * pkt)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_MPI *m = NULL, *c1 = NULL, *c2 = NULL;
|
PGP_MPI *m = NULL,
|
||||||
|
*c1 = NULL,
|
||||||
|
*c2 = NULL;
|
||||||
|
|
||||||
/* create padded msg */
|
/* create padded msg */
|
||||||
res = create_secmsg(ctx, &m, pk->pub.elg.p->bytes - 1);
|
res = create_secmsg(ctx, &m, pk->pub.elg.p->bytes - 1);
|
||||||
@ -162,10 +167,11 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
encrypt_and_write_rsa(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt)
|
encrypt_and_write_rsa(PGP_Context * ctx, PGP_PubKey * pk, PushFilter * pkt)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_MPI *m = NULL, *c = NULL;
|
PGP_MPI *m = NULL,
|
||||||
|
*c = NULL;
|
||||||
|
|
||||||
/* create padded msg */
|
/* create padded msg */
|
||||||
res = create_secmsg(ctx, &m, pk->pub.rsa.n->bytes - 1);
|
res = create_secmsg(ctx, &m, pk->pub.rsa.n->bytes - 1);
|
||||||
@ -186,15 +192,17 @@ err:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst)
|
int
|
||||||
|
pgp_write_pubenc_sesskey(PGP_Context * ctx, PushFilter * dst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_PubKey *pk = ctx->pub_key;
|
PGP_PubKey *pk = ctx->pub_key;
|
||||||
uint8 ver = 3;
|
uint8 ver = 3;
|
||||||
PushFilter *pkt = NULL;
|
PushFilter *pkt = NULL;
|
||||||
uint8 algo = pk->algo;
|
uint8 algo = pk->algo;
|
||||||
|
|
||||||
if (pk == NULL) {
|
if (pk == NULL)
|
||||||
|
{
|
||||||
px_debug("no pubkey?\n");
|
px_debug("no pubkey?\n");
|
||||||
return PXE_BUG;
|
return PXE_BUG;
|
||||||
}
|
}
|
||||||
@ -238,5 +246,3 @@ err:
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubkey.c,v 1.3 2005/08/13 02:06:20 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pubkey.c,v 1.4 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
@ -34,16 +34,19 @@
|
|||||||
#include "mbuf.h"
|
#include "mbuf.h"
|
||||||
#include "pgp.h"
|
#include "pgp.h"
|
||||||
|
|
||||||
int pgp_key_alloc(PGP_PubKey **pk_p)
|
int
|
||||||
|
pgp_key_alloc(PGP_PubKey ** pk_p)
|
||||||
{
|
{
|
||||||
PGP_PubKey *pk;
|
PGP_PubKey *pk;
|
||||||
|
|
||||||
pk = px_alloc(sizeof(*pk));
|
pk = px_alloc(sizeof(*pk));
|
||||||
memset(pk, 0, sizeof(*pk));
|
memset(pk, 0, sizeof(*pk));
|
||||||
*pk_p = pk;
|
*pk_p = pk;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pgp_key_free(PGP_PubKey *pk)
|
void
|
||||||
|
pgp_key_free(PGP_PubKey * pk)
|
||||||
{
|
{
|
||||||
if (pk == NULL)
|
if (pk == NULL)
|
||||||
return;
|
return;
|
||||||
@ -79,13 +82,13 @@ void pgp_key_free(PGP_PubKey *pk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
calc_key_id(PGP_PubKey *pk)
|
calc_key_id(PGP_PubKey * pk)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PX_MD *md;
|
PX_MD *md;
|
||||||
int len;
|
int len;
|
||||||
uint8 hdr[3];
|
uint8 hdr[3];
|
||||||
uint8 hash[20];
|
uint8 hash[20];
|
||||||
|
|
||||||
res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
|
res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -152,9 +155,10 @@ calc_key_id(PGP_PubKey *pk)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
|
int
|
||||||
|
_pgp_read_public_key(PullFilter * pkt, PGP_PubKey ** pk_p)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PGP_PubKey *pk;
|
PGP_PubKey *pk;
|
||||||
|
|
||||||
res = pgp_key_alloc(&pk);
|
res = pgp_key_alloc(&pk);
|
||||||
@ -163,7 +167,8 @@ int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
|
|||||||
|
|
||||||
/* get version */
|
/* get version */
|
||||||
GETBYTE(pkt, pk->ver);
|
GETBYTE(pkt, pk->ver);
|
||||||
if (pk->ver != 4) {
|
if (pk->ver != 4)
|
||||||
|
{
|
||||||
res = PXE_PGP_NOT_V4_KEYPKT;
|
res = PXE_PGP_NOT_V4_KEYPKT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -176,16 +181,21 @@ int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
|
|||||||
/* pubkey algorithm */
|
/* pubkey algorithm */
|
||||||
GETBYTE(pkt, pk->algo);
|
GETBYTE(pkt, pk->algo);
|
||||||
|
|
||||||
switch (pk->algo) {
|
switch (pk->algo)
|
||||||
|
{
|
||||||
case PGP_PUB_DSA_SIGN:
|
case PGP_PUB_DSA_SIGN:
|
||||||
res = pgp_mpi_read(pkt, &pk->pub.dsa.p);
|
res = pgp_mpi_read(pkt, &pk->pub.dsa.p);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
res = pgp_mpi_read(pkt, &pk->pub.dsa.q);
|
res = pgp_mpi_read(pkt, &pk->pub.dsa.q);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
res = pgp_mpi_read(pkt, &pk->pub.dsa.g);
|
res = pgp_mpi_read(pkt, &pk->pub.dsa.g);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
res = pgp_mpi_read(pkt, &pk->pub.dsa.y);
|
res = pgp_mpi_read(pkt, &pk->pub.dsa.y);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
res = calc_key_id(pk);
|
res = calc_key_id(pk);
|
||||||
break;
|
break;
|
||||||
@ -194,9 +204,11 @@ int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
|
|||||||
case PGP_PUB_RSA_ENCRYPT:
|
case PGP_PUB_RSA_ENCRYPT:
|
||||||
case PGP_PUB_RSA_ENCRYPT_SIGN:
|
case PGP_PUB_RSA_ENCRYPT_SIGN:
|
||||||
res = pgp_mpi_read(pkt, &pk->pub.rsa.n);
|
res = pgp_mpi_read(pkt, &pk->pub.rsa.n);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
res = pgp_mpi_read(pkt, &pk->pub.rsa.e);
|
res = pgp_mpi_read(pkt, &pk->pub.rsa.e);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
res = calc_key_id(pk);
|
res = calc_key_id(pk);
|
||||||
|
|
||||||
@ -206,11 +218,14 @@ int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
|
|||||||
|
|
||||||
case PGP_PUB_ELG_ENCRYPT:
|
case PGP_PUB_ELG_ENCRYPT:
|
||||||
res = pgp_mpi_read(pkt, &pk->pub.elg.p);
|
res = pgp_mpi_read(pkt, &pk->pub.elg.p);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
res = pgp_mpi_read(pkt, &pk->pub.elg.g);
|
res = pgp_mpi_read(pkt, &pk->pub.elg.g);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
res = pgp_mpi_read(pkt, &pk->pub.elg.y);
|
res = pgp_mpi_read(pkt, &pk->pub.elg.y);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
res = calc_key_id(pk);
|
res = calc_key_id(pk);
|
||||||
|
|
||||||
@ -236,12 +251,12 @@ out:
|
|||||||
#define HIDE_SHA1 254
|
#define HIDE_SHA1 254
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_key_sha1(PullFilter *src, PGP_PubKey *pk)
|
check_key_sha1(PullFilter * src, PGP_PubKey * pk)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
uint8 got_sha1[20];
|
uint8 got_sha1[20];
|
||||||
uint8 my_sha1[20];
|
uint8 my_sha1[20];
|
||||||
PX_MD *md;
|
PX_MD *md;
|
||||||
|
|
||||||
res = pullf_read_fixed(src, 20, got_sha1);
|
res = pullf_read_fixed(src, 20, got_sha1);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -282,17 +297,18 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_key_cksum(PullFilter *src, PGP_PubKey *pk)
|
check_key_cksum(PullFilter * src, PGP_PubKey * pk)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
unsigned got_cksum, my_cksum = 0;
|
unsigned got_cksum,
|
||||||
uint8 buf[2];
|
my_cksum = 0;
|
||||||
|
uint8 buf[2];
|
||||||
|
|
||||||
res = pullf_read_fixed(src, 2, buf);
|
res = pullf_read_fixed(src, 2, buf);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
got_cksum = ((unsigned)buf[0] << 8) + buf[1];
|
got_cksum = ((unsigned) buf[0] << 8) + buf[1];
|
||||||
switch (pk->algo)
|
switch (pk->algo)
|
||||||
{
|
{
|
||||||
case PGP_PUB_ELG_ENCRYPT:
|
case PGP_PUB_ELG_ENCRYPT:
|
||||||
@ -318,17 +334,19 @@ check_key_cksum(PullFilter *src, PGP_PubKey *pk)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
|
static int
|
||||||
const uint8 *key, int key_len)
|
process_secret_key(PullFilter * pkt, PGP_PubKey ** pk_p,
|
||||||
|
const uint8 *key, int key_len)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
int hide_type;
|
int hide_type;
|
||||||
int cipher_algo;
|
int cipher_algo;
|
||||||
int bs;
|
int bs;
|
||||||
uint8 iv[512];
|
uint8 iv[512];
|
||||||
PullFilter *pf_decrypt = NULL, *pf_key;
|
PullFilter *pf_decrypt = NULL,
|
||||||
PGP_CFB *cfb = NULL;
|
*pf_key;
|
||||||
PGP_S2K s2k;
|
PGP_CFB *cfb = NULL;
|
||||||
|
PGP_S2K s2k;
|
||||||
PGP_PubKey *pk;
|
PGP_PubKey *pk;
|
||||||
|
|
||||||
/* first read public key part */
|
/* first read public key part */
|
||||||
@ -340,7 +358,8 @@ static int process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
|
|||||||
* is secret key encrypted?
|
* is secret key encrypted?
|
||||||
*/
|
*/
|
||||||
GETBYTE(pkt, hide_type);
|
GETBYTE(pkt, hide_type);
|
||||||
if (hide_type == HIDE_SHA1 || hide_type == HIDE_CKSUM) {
|
if (hide_type == HIDE_SHA1 || hide_type == HIDE_CKSUM)
|
||||||
|
{
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
return PXE_PGP_NEED_SECRET_PSW;
|
return PXE_PGP_NEED_SECRET_PSW;
|
||||||
GETBYTE(pkt, cipher_algo);
|
GETBYTE(pkt, cipher_algo);
|
||||||
@ -353,13 +372,15 @@ static int process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
|
|||||||
return res;
|
return res;
|
||||||
|
|
||||||
bs = pgp_get_cipher_block_size(cipher_algo);
|
bs = pgp_get_cipher_block_size(cipher_algo);
|
||||||
if (bs == 0) {
|
if (bs == 0)
|
||||||
|
{
|
||||||
px_debug("unknown cipher algo=%d", cipher_algo);
|
px_debug("unknown cipher algo=%d", cipher_algo);
|
||||||
return PXE_PGP_UNSUPPORTED_CIPHER;
|
return PXE_PGP_UNSUPPORTED_CIPHER;
|
||||||
}
|
}
|
||||||
res = pullf_read_fixed(pkt, bs, iv);
|
res = pullf_read_fixed(pkt, bs, iv);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create decrypt filter
|
* create decrypt filter
|
||||||
*/
|
*/
|
||||||
@ -370,26 +391,35 @@ static int process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
|
|||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
pf_key = pf_decrypt;
|
pf_key = pf_decrypt;
|
||||||
} else if (hide_type == HIDE_CLEAR) {
|
}
|
||||||
|
else if (hide_type == HIDE_CLEAR)
|
||||||
|
{
|
||||||
pf_key = pkt;
|
pf_key = pkt;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
px_debug("unknown hide type");
|
px_debug("unknown hide type");
|
||||||
return PXE_PGP_KEYPKT_CORRUPT;
|
return PXE_PGP_KEYPKT_CORRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read secret key */
|
/* read secret key */
|
||||||
switch (pk->algo) {
|
switch (pk->algo)
|
||||||
|
{
|
||||||
case PGP_PUB_RSA_SIGN:
|
case PGP_PUB_RSA_SIGN:
|
||||||
case PGP_PUB_RSA_ENCRYPT:
|
case PGP_PUB_RSA_ENCRYPT:
|
||||||
case PGP_PUB_RSA_ENCRYPT_SIGN:
|
case PGP_PUB_RSA_ENCRYPT_SIGN:
|
||||||
res = pgp_mpi_read(pkt, &pk->sec.rsa.d);
|
res = pgp_mpi_read(pkt, &pk->sec.rsa.d);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
res = pgp_mpi_read(pkt, &pk->sec.rsa.p);
|
res = pgp_mpi_read(pkt, &pk->sec.rsa.p);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
res = pgp_mpi_read(pkt, &pk->sec.rsa.q);
|
res = pgp_mpi_read(pkt, &pk->sec.rsa.q);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
res = pgp_mpi_read(pkt, &pk->sec.rsa.u);
|
res = pgp_mpi_read(pkt, &pk->sec.rsa.u);
|
||||||
if (res < 0) break;
|
if (res < 0)
|
||||||
|
break;
|
||||||
break;
|
break;
|
||||||
case PGP_PUB_ELG_ENCRYPT:
|
case PGP_PUB_ELG_ENCRYPT:
|
||||||
res = pgp_mpi_read(pf_key, &pk->sec.elg.x);
|
res = pgp_mpi_read(pf_key, &pk->sec.elg.x);
|
||||||
@ -426,23 +456,24 @@ static int process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
|
internal_read_key(PullFilter * src, PGP_PubKey ** pk_p,
|
||||||
const uint8 *psw, int psw_len, int pubtype)
|
const uint8 *psw, int psw_len, int pubtype)
|
||||||
{
|
{
|
||||||
PullFilter *pkt = NULL;
|
PullFilter *pkt = NULL;
|
||||||
int res;
|
int res;
|
||||||
uint8 tag;
|
uint8 tag;
|
||||||
int len;
|
int len;
|
||||||
PGP_PubKey *enc_key = NULL;
|
PGP_PubKey *enc_key = NULL;
|
||||||
PGP_PubKey *pk = NULL;
|
PGP_PubKey *pk = NULL;
|
||||||
int got_main_key = 0;
|
int got_main_key = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search for encryption key.
|
* Search for encryption key.
|
||||||
*
|
*
|
||||||
* Error out on anything fancy.
|
* Error out on anything fancy.
|
||||||
*/
|
*/
|
||||||
while (1) {
|
while (1)
|
||||||
|
{
|
||||||
res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
|
res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
break;
|
break;
|
||||||
@ -450,7 +481,8 @@ internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
|
|||||||
if (res < 0)
|
if (res < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag)
|
||||||
|
{
|
||||||
case PGP_PKT_PUBLIC_KEY:
|
case PGP_PKT_PUBLIC_KEY:
|
||||||
case PGP_PKT_SECRET_KEY:
|
case PGP_PKT_SECRET_KEY:
|
||||||
if (got_main_key)
|
if (got_main_key)
|
||||||
@ -489,7 +521,7 @@ internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
|
|||||||
res = PXE_PGP_UNEXPECTED_PKT;
|
res = PXE_PGP_UNEXPECTED_PKT;
|
||||||
}
|
}
|
||||||
pullf_free(pkt);
|
pullf_free(pkt);
|
||||||
pkt = NULL;
|
pkt = NULL;
|
||||||
|
|
||||||
if (pk != NULL)
|
if (pk != NULL)
|
||||||
{
|
{
|
||||||
@ -531,10 +563,10 @@ internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt,
|
pgp_set_pubkey(PGP_Context * ctx, MBuf * keypkt,
|
||||||
const uint8 *key, int key_len, int pubtype)
|
const uint8 *key, int key_len, int pubtype)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PullFilter *src;
|
PullFilter *src;
|
||||||
PGP_PubKey *pk = NULL;
|
PGP_PubKey *pk = NULL;
|
||||||
|
|
||||||
@ -550,4 +582,3 @@ pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt,
|
|||||||
|
|
||||||
return res < 0 ? res : 0;
|
return res < 0 ? res : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-s2k.c,v 1.3 2005/07/18 17:12:54 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-s2k.c,v 1.4 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -36,7 +36,7 @@
|
|||||||
#include "pgp.h"
|
#include "pgp.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
calc_s2k_simple(PGP_S2K * s2k, PX_MD *md, const uint8 *key,
|
calc_s2k_simple(PGP_S2K * s2k, PX_MD * md, const uint8 *key,
|
||||||
unsigned key_len)
|
unsigned key_len)
|
||||||
{
|
{
|
||||||
unsigned md_bs,
|
unsigned md_bs,
|
||||||
@ -81,7 +81,7 @@ calc_s2k_simple(PGP_S2K * s2k, PX_MD *md, const uint8 *key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
calc_s2k_salted(PGP_S2K * s2k, PX_MD *md, const uint8 *key, unsigned key_len)
|
calc_s2k_salted(PGP_S2K * s2k, PX_MD * md, const uint8 *key, unsigned key_len)
|
||||||
{
|
{
|
||||||
unsigned md_bs,
|
unsigned md_bs,
|
||||||
md_rlen;
|
md_rlen;
|
||||||
@ -126,8 +126,8 @@ calc_s2k_salted(PGP_S2K * s2k, PX_MD *md, const uint8 *key, unsigned key_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
calc_s2k_iter_salted(PGP_S2K * s2k, PX_MD *md, const uint8 *key,
|
calc_s2k_iter_salted(PGP_S2K * s2k, PX_MD * md, const uint8 *key,
|
||||||
unsigned key_len)
|
unsigned key_len)
|
||||||
{
|
{
|
||||||
unsigned md_bs,
|
unsigned md_bs,
|
||||||
md_rlen;
|
md_rlen;
|
||||||
@ -213,15 +213,16 @@ decide_count(unsigned rand_byte)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_s2k_fill(PGP_S2K *s2k, int mode,int digest_algo)
|
pgp_s2k_fill(PGP_S2K * s2k, int mode, int digest_algo)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
uint8 tmp;
|
uint8 tmp;
|
||||||
|
|
||||||
s2k->mode = mode;
|
s2k->mode = mode;
|
||||||
s2k->digest_algo = digest_algo;
|
s2k->digest_algo = digest_algo;
|
||||||
|
|
||||||
switch (s2k->mode) {
|
switch (s2k->mode)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
@ -243,13 +244,14 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode,int digest_algo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
|
pgp_s2k_read(PullFilter * src, PGP_S2K * s2k)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
GETBYTE(src, s2k->mode);
|
GETBYTE(src, s2k->mode);
|
||||||
GETBYTE(src, s2k->digest_algo);
|
GETBYTE(src, s2k->digest_algo);
|
||||||
switch (s2k->mode) {
|
switch (s2k->mode)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
@ -267,10 +269,11 @@ pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
|
int
|
||||||
|
pgp_s2k_process(PGP_S2K * s2k, int cipher, const uint8 *key, int key_len)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
PX_MD *md;
|
PX_MD *md;
|
||||||
|
|
||||||
s2k->key_len = pgp_get_cipher_key_size(cipher);
|
s2k->key_len = pgp_get_cipher_key_size(cipher);
|
||||||
if (s2k->key_len <= 0)
|
if (s2k->key_len <= 0)
|
||||||
@ -280,7 +283,8 @@ int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
|
|||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
switch (s2k->mode) {
|
switch (s2k->mode)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
res = calc_s2k_simple(s2k, md, key, key_len);
|
res = calc_s2k_simple(s2k, md, key, key_len);
|
||||||
break;
|
break;
|
||||||
@ -296,4 +300,3 @@ int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
|
|||||||
px_md_free(md);
|
px_md_free(md);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp.c,v 1.2 2005/07/11 15:07:59 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp.c,v 1.3 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -62,8 +62,8 @@ struct cipher_info
|
|||||||
const char *name;
|
const char *name;
|
||||||
int code;
|
int code;
|
||||||
const char *int_name;
|
const char *int_name;
|
||||||
int key_len;
|
int key_len;
|
||||||
int block_len;
|
int block_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct digest_info digest_list[] = {
|
static const struct digest_info digest_list[] = {
|
||||||
@ -78,15 +78,15 @@ static const struct digest_info digest_list[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct cipher_info cipher_list[] = {
|
static const struct cipher_info cipher_list[] = {
|
||||||
{"3des", PGP_SYM_DES3, "3des-ecb", 192/8, 64/8},
|
{"3des", PGP_SYM_DES3, "3des-ecb", 192 / 8, 64 / 8},
|
||||||
{"cast5", PGP_SYM_CAST5, "cast5-ecb", 128/8, 64/8},
|
{"cast5", PGP_SYM_CAST5, "cast5-ecb", 128 / 8, 64 / 8},
|
||||||
{"bf", PGP_SYM_BLOWFISH, "bf-ecb", 128/8, 64/8},
|
{"bf", PGP_SYM_BLOWFISH, "bf-ecb", 128 / 8, 64 / 8},
|
||||||
{"blowfish", PGP_SYM_BLOWFISH, "bf-ecb", 128/8, 64/8},
|
{"blowfish", PGP_SYM_BLOWFISH, "bf-ecb", 128 / 8, 64 / 8},
|
||||||
{"aes", PGP_SYM_AES_128, "aes-ecb", 128/8, 128/8},
|
{"aes", PGP_SYM_AES_128, "aes-ecb", 128 / 8, 128 / 8},
|
||||||
{"aes128", PGP_SYM_AES_128, "aes-ecb", 128/8, 128/8},
|
{"aes128", PGP_SYM_AES_128, "aes-ecb", 128 / 8, 128 / 8},
|
||||||
{"aes192", PGP_SYM_AES_192, "aes-ecb", 192/8, 128/8},
|
{"aes192", PGP_SYM_AES_192, "aes-ecb", 192 / 8, 128 / 8},
|
||||||
{"aes256", PGP_SYM_AES_256, "aes-ecb", 256/8, 128/8},
|
{"aes256", PGP_SYM_AES_256, "aes-ecb", 256 / 8, 128 / 8},
|
||||||
{"twofish", PGP_SYM_TWOFISH, "twofish-ecb", 256/8, 128/8},
|
{"twofish", PGP_SYM_TWOFISH, "twofish-ecb", 256 / 8, 128 / 8},
|
||||||
{NULL, 0, NULL}
|
{NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -94,6 +94,7 @@ static const struct cipher_info *
|
|||||||
get_cipher_info(int code)
|
get_cipher_info(int code)
|
||||||
{
|
{
|
||||||
const struct cipher_info *i;
|
const struct cipher_info *i;
|
||||||
|
|
||||||
for (i = cipher_list; i->name; i++)
|
for (i = cipher_list; i->name; i++)
|
||||||
if (i->code == code)
|
if (i->code == code)
|
||||||
return i;
|
return i;
|
||||||
@ -104,6 +105,7 @@ int
|
|||||||
pgp_get_digest_code(const char *name)
|
pgp_get_digest_code(const char *name)
|
||||||
{
|
{
|
||||||
const struct digest_info *i;
|
const struct digest_info *i;
|
||||||
|
|
||||||
for (i = digest_list; i->name; i++)
|
for (i = digest_list; i->name; i++)
|
||||||
if (pg_strcasecmp(i->name, name) == 0)
|
if (pg_strcasecmp(i->name, name) == 0)
|
||||||
return i->code;
|
return i->code;
|
||||||
@ -114,6 +116,7 @@ int
|
|||||||
pgp_get_cipher_code(const char *name)
|
pgp_get_cipher_code(const char *name)
|
||||||
{
|
{
|
||||||
const struct cipher_info *i;
|
const struct cipher_info *i;
|
||||||
|
|
||||||
for (i = cipher_list; i->name; i++)
|
for (i = cipher_list; i->name; i++)
|
||||||
if (pg_strcasecmp(i->name, name) == 0)
|
if (pg_strcasecmp(i->name, name) == 0)
|
||||||
return i->code;
|
return i->code;
|
||||||
@ -124,6 +127,7 @@ const char *
|
|||||||
pgp_get_digest_name(int code)
|
pgp_get_digest_name(int code)
|
||||||
{
|
{
|
||||||
const struct digest_info *i;
|
const struct digest_info *i;
|
||||||
|
|
||||||
for (i = digest_list; i->name; i++)
|
for (i = digest_list; i->name; i++)
|
||||||
if (i->code == code)
|
if (i->code == code)
|
||||||
return i->name;
|
return i->name;
|
||||||
@ -134,6 +138,7 @@ const char *
|
|||||||
pgp_get_cipher_name(int code)
|
pgp_get_cipher_name(int code)
|
||||||
{
|
{
|
||||||
const struct cipher_info *i = get_cipher_info(code);
|
const struct cipher_info *i = get_cipher_info(code);
|
||||||
|
|
||||||
if (i != NULL)
|
if (i != NULL)
|
||||||
return i->name;
|
return i->name;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -143,6 +148,7 @@ int
|
|||||||
pgp_get_cipher_key_size(int code)
|
pgp_get_cipher_key_size(int code)
|
||||||
{
|
{
|
||||||
const struct cipher_info *i = get_cipher_info(code);
|
const struct cipher_info *i = get_cipher_info(code);
|
||||||
|
|
||||||
if (i != NULL)
|
if (i != NULL)
|
||||||
return i->key_len;
|
return i->key_len;
|
||||||
return 0;
|
return 0;
|
||||||
@ -152,6 +158,7 @@ int
|
|||||||
pgp_get_cipher_block_size(int code)
|
pgp_get_cipher_block_size(int code)
|
||||||
{
|
{
|
||||||
const struct cipher_info *i = get_cipher_info(code);
|
const struct cipher_info *i = get_cipher_info(code);
|
||||||
|
|
||||||
if (i != NULL)
|
if (i != NULL)
|
||||||
return i->block_len;
|
return i->block_len;
|
||||||
return 0;
|
return 0;
|
||||||
@ -300,6 +307,7 @@ int
|
|||||||
pgp_set_cipher_algo(PGP_Context * ctx, const char *name)
|
pgp_set_cipher_algo(PGP_Context * ctx, const char *name)
|
||||||
{
|
{
|
||||||
int code = pgp_get_cipher_code(name);
|
int code = pgp_get_cipher_code(name);
|
||||||
|
|
||||||
if (code < 0)
|
if (code < 0)
|
||||||
return code;
|
return code;
|
||||||
ctx->cipher_algo = code;
|
ctx->cipher_algo = code;
|
||||||
@ -310,6 +318,7 @@ int
|
|||||||
pgp_set_s2k_cipher_algo(PGP_Context * ctx, const char *name)
|
pgp_set_s2k_cipher_algo(PGP_Context * ctx, const char *name)
|
||||||
{
|
{
|
||||||
int code = pgp_get_cipher_code(name);
|
int code = pgp_get_cipher_code(name);
|
||||||
|
|
||||||
if (code < 0)
|
if (code < 0)
|
||||||
return code;
|
return code;
|
||||||
ctx->s2k_cipher_algo = code;
|
ctx->s2k_cipher_algo = code;
|
||||||
@ -320,6 +329,7 @@ int
|
|||||||
pgp_set_s2k_digest_algo(PGP_Context * ctx, const char *name)
|
pgp_set_s2k_digest_algo(PGP_Context * ctx, const char *name)
|
||||||
{
|
{
|
||||||
int code = pgp_get_digest_code(name);
|
int code = pgp_get_digest_code(name);
|
||||||
|
|
||||||
if (code < 0)
|
if (code < 0)
|
||||||
return code;
|
return code;
|
||||||
ctx->s2k_digest_algo = code;
|
ctx->s2k_digest_algo = code;
|
||||||
@ -327,20 +337,20 @@ pgp_set_s2k_digest_algo(PGP_Context * ctx, const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_get_unicode_mode(PGP_Context *ctx)
|
pgp_get_unicode_mode(PGP_Context * ctx)
|
||||||
{
|
{
|
||||||
return ctx->unicode_mode;
|
return ctx->unicode_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_set_unicode_mode(PGP_Context *ctx, int mode)
|
pgp_set_unicode_mode(PGP_Context * ctx, int mode)
|
||||||
{
|
{
|
||||||
ctx->unicode_mode = mode ? 1 : 0;
|
ctx->unicode_mode = mode ? 1 : 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int len)
|
pgp_set_symkey(PGP_Context * ctx, const uint8 *key, int len)
|
||||||
{
|
{
|
||||||
if (key == NULL || len < 1)
|
if (key == NULL || len < 1)
|
||||||
return PXE_ARGUMENT_ERROR;
|
return PXE_ARGUMENT_ERROR;
|
||||||
@ -348,4 +358,3 @@ pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int len)
|
|||||||
ctx->sym_key_len = len;
|
ctx->sym_key_len = len;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp.h,v 1.3 2005/08/13 02:06:20 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp.h,v 1.4 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -55,7 +55,7 @@ enum
|
|||||||
PGP_PKT_USER_ATTR = 17,
|
PGP_PKT_USER_ATTR = 17,
|
||||||
PGP_PKT_SYMENCRYPTED_DATA_MDC = 18,
|
PGP_PKT_SYMENCRYPTED_DATA_MDC = 18,
|
||||||
PGP_PKT_MDC = 19,
|
PGP_PKT_MDC = 19,
|
||||||
PGP_PKT_PRIV_61 = 61 /* occurs in gpg secring */
|
PGP_PKT_PRIV_61 = 61 /* occurs in gpg secring */
|
||||||
} PGP_PKT_TYPE;
|
} PGP_PKT_TYPE;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -93,11 +93,11 @@ enum
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PGP_DIGEST_MD5 = 1, /* should, deprecated */
|
PGP_DIGEST_MD5 = 1, /* should, deprecated */
|
||||||
PGP_DIGEST_SHA1 = 2, /* must */
|
PGP_DIGEST_SHA1 = 2, /* must */
|
||||||
PGP_DIGEST_RIPEMD160 = 3,
|
PGP_DIGEST_RIPEMD160 = 3,
|
||||||
PGP_DIGEST_XSHA = 4, /* obsolete */
|
PGP_DIGEST_XSHA = 4, /* obsolete */
|
||||||
PGP_DIGEST_MD2 = 5, /* obsolete */
|
PGP_DIGEST_MD2 = 5, /* obsolete */
|
||||||
PGP_DIGEST_TIGER192 = 6, /* obsolete */
|
PGP_DIGEST_TIGER192 = 6, /* obsolete */
|
||||||
PGP_DIGEST_HAVAL5_160 = 7, /* obsolete */
|
PGP_DIGEST_HAVAL5_160 = 7, /* obsolete */
|
||||||
PGP_DIGEST_SHA256 = 8,
|
PGP_DIGEST_SHA256 = 8,
|
||||||
PGP_DIGEST_SHA384 = 9,
|
PGP_DIGEST_SHA384 = 9,
|
||||||
@ -114,14 +114,15 @@ typedef struct PGP_PubKey PGP_PubKey;
|
|||||||
typedef struct PGP_Context PGP_Context;
|
typedef struct PGP_Context PGP_Context;
|
||||||
typedef struct PGP_S2K PGP_S2K;
|
typedef struct PGP_S2K PGP_S2K;
|
||||||
|
|
||||||
struct PGP_S2K {
|
struct PGP_S2K
|
||||||
uint8 mode;
|
{
|
||||||
uint8 digest_algo;
|
uint8 mode;
|
||||||
uint8 salt[8];
|
uint8 digest_algo;
|
||||||
uint8 iter;
|
uint8 salt[8];
|
||||||
|
uint8 iter;
|
||||||
/* calculated: */
|
/* calculated: */
|
||||||
uint8 key[PGP_MAX_KEY];
|
uint8 key[PGP_MAX_KEY];
|
||||||
uint8 key_len;
|
uint8 key_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -152,8 +153,8 @@ struct PGP_Context
|
|||||||
int use_mdcbuf_filter;
|
int use_mdcbuf_filter;
|
||||||
PX_MD *mdc_ctx;
|
PX_MD *mdc_ctx;
|
||||||
|
|
||||||
PGP_PubKey *pub_key; /* ctx owns it*/
|
PGP_PubKey *pub_key; /* ctx owns it */
|
||||||
const uint8 *sym_key; /* ctx does not own it */
|
const uint8 *sym_key; /* ctx does not own it */
|
||||||
int sym_key_len;
|
int sym_key_len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -163,54 +164,64 @@ struct PGP_Context
|
|||||||
unsigned sess_key_len;
|
unsigned sess_key_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PGP_MPI {
|
struct PGP_MPI
|
||||||
uint8 *data;
|
{
|
||||||
int bits;
|
uint8 *data;
|
||||||
int bytes;
|
int bits;
|
||||||
|
int bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PGP_PubKey {
|
struct PGP_PubKey
|
||||||
uint8 ver;
|
{
|
||||||
uint8 time[4];
|
uint8 ver;
|
||||||
uint8 algo;
|
uint8 time[4];
|
||||||
|
uint8 algo;
|
||||||
|
|
||||||
/* public part */
|
/* public part */
|
||||||
union {
|
union
|
||||||
struct {
|
{
|
||||||
PGP_MPI *p;
|
struct
|
||||||
PGP_MPI *g;
|
{
|
||||||
PGP_MPI *y;
|
PGP_MPI *p;
|
||||||
} elg;
|
PGP_MPI *g;
|
||||||
struct {
|
PGP_MPI *y;
|
||||||
PGP_MPI *n;
|
} elg;
|
||||||
PGP_MPI *e;
|
struct
|
||||||
} rsa;
|
{
|
||||||
struct {
|
PGP_MPI *n;
|
||||||
PGP_MPI *p;
|
PGP_MPI *e;
|
||||||
PGP_MPI *q;
|
} rsa;
|
||||||
PGP_MPI *g;
|
struct
|
||||||
PGP_MPI *y;
|
{
|
||||||
} dsa;
|
PGP_MPI *p;
|
||||||
} pub;
|
PGP_MPI *q;
|
||||||
|
PGP_MPI *g;
|
||||||
|
PGP_MPI *y;
|
||||||
|
} dsa;
|
||||||
|
} pub;
|
||||||
|
|
||||||
/* secret part */
|
/* secret part */
|
||||||
union {
|
union
|
||||||
struct {
|
{
|
||||||
PGP_MPI *x;
|
struct
|
||||||
} elg;
|
{
|
||||||
struct {
|
PGP_MPI *x;
|
||||||
PGP_MPI *d;
|
} elg;
|
||||||
PGP_MPI *p;
|
struct
|
||||||
PGP_MPI *q;
|
{
|
||||||
PGP_MPI *u;
|
PGP_MPI *d;
|
||||||
} rsa;
|
PGP_MPI *p;
|
||||||
struct {
|
PGP_MPI *q;
|
||||||
PGP_MPI *x;
|
PGP_MPI *u;
|
||||||
} dsa;
|
} rsa;
|
||||||
} sec;
|
struct
|
||||||
|
{
|
||||||
|
PGP_MPI *x;
|
||||||
|
} dsa;
|
||||||
|
} sec;
|
||||||
|
|
||||||
uint8 key_id[8];
|
uint8 key_id[8];
|
||||||
int can_encrypt;
|
int can_encrypt;
|
||||||
};
|
};
|
||||||
|
|
||||||
int pgp_init(PGP_Context ** ctx);
|
int pgp_init(PGP_Context ** ctx);
|
||||||
@ -236,11 +247,11 @@ int pgp_set_text_mode(PGP_Context * ctx, int mode);
|
|||||||
int pgp_set_unicode_mode(PGP_Context * ctx, int mode);
|
int pgp_set_unicode_mode(PGP_Context * ctx, int mode);
|
||||||
int pgp_get_unicode_mode(PGP_Context * ctx);
|
int pgp_get_unicode_mode(PGP_Context * ctx);
|
||||||
|
|
||||||
int pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int klen);
|
int pgp_set_symkey(PGP_Context * ctx, const uint8 *key, int klen);
|
||||||
int pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt,
|
int pgp_set_pubkey(PGP_Context * ctx, MBuf * keypkt,
|
||||||
const uint8 *key, int klen, int pubtype);
|
const uint8 *key, int klen, int pubtype);
|
||||||
|
|
||||||
int pgp_get_keyid(MBuf *pgp_data, char *dst);
|
int pgp_get_keyid(MBuf * pgp_data, char *dst);
|
||||||
|
|
||||||
/* internal functions */
|
/* internal functions */
|
||||||
|
|
||||||
@ -249,55 +260,55 @@ int pgp_load_cipher(int c, PX_Cipher ** res);
|
|||||||
int pgp_get_cipher_key_size(int c);
|
int pgp_get_cipher_key_size(int c);
|
||||||
int pgp_get_cipher_block_size(int c);
|
int pgp_get_cipher_block_size(int c);
|
||||||
|
|
||||||
int pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo);
|
int pgp_s2k_fill(PGP_S2K * s2k, int mode, int digest_algo);
|
||||||
int pgp_s2k_read(PullFilter *src, PGP_S2K *s2k);
|
int pgp_s2k_read(PullFilter * src, PGP_S2K * s2k);
|
||||||
int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int klen);
|
int pgp_s2k_process(PGP_S2K * s2k, int cipher, const uint8 *key, int klen);
|
||||||
|
|
||||||
typedef struct PGP_CFB PGP_CFB;
|
typedef struct PGP_CFB PGP_CFB;
|
||||||
int pgp_cfb_create(PGP_CFB **ctx_p, int algo,
|
int
|
||||||
const uint8 *key, int key_len, int recync, uint8 *iv);
|
pgp_cfb_create(PGP_CFB ** ctx_p, int algo,
|
||||||
void pgp_cfb_free(PGP_CFB *ctx);
|
const uint8 *key, int key_len, int recync, uint8 *iv);
|
||||||
int pgp_cfb_encrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst);
|
void pgp_cfb_free(PGP_CFB * ctx);
|
||||||
int pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst);
|
int pgp_cfb_encrypt(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst);
|
||||||
|
int pgp_cfb_decrypt(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst);
|
||||||
|
|
||||||
int pgp_armor_encode(const uint8 *src, unsigned len, uint8 *dst);
|
int pgp_armor_encode(const uint8 *src, unsigned len, uint8 *dst);
|
||||||
int pgp_armor_decode(const uint8 *src, unsigned len, uint8 *dst);
|
int pgp_armor_decode(const uint8 *src, unsigned len, uint8 *dst);
|
||||||
unsigned pgp_armor_enc_len(unsigned len);
|
unsigned pgp_armor_enc_len(unsigned len);
|
||||||
unsigned pgp_armor_dec_len(unsigned len);
|
unsigned pgp_armor_dec_len(unsigned len);
|
||||||
|
|
||||||
int pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst);
|
int pgp_compress_filter(PushFilter ** res, PGP_Context * ctx, PushFilter * dst);
|
||||||
int pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src);
|
int pgp_decompress_filter(PullFilter ** res, PGP_Context * ctx, PullFilter * src);
|
||||||
|
|
||||||
int pgp_key_alloc(PGP_PubKey **pk_p);
|
int pgp_key_alloc(PGP_PubKey ** pk_p);
|
||||||
void pgp_key_free(PGP_PubKey *pk);
|
void pgp_key_free(PGP_PubKey * pk);
|
||||||
int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p);
|
int _pgp_read_public_key(PullFilter * pkt, PGP_PubKey ** pk_p);
|
||||||
|
|
||||||
int pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt);
|
int pgp_parse_pubenc_sesskey(PGP_Context * ctx, PullFilter * pkt);
|
||||||
int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
|
int pgp_create_pkt_reader(PullFilter ** pf_p, PullFilter * src, int len,
|
||||||
int pkttype, PGP_Context *ctx);
|
int pkttype, PGP_Context * ctx);
|
||||||
int pgp_parse_pkt_hdr(PullFilter * src, uint8 *tag, int *len_p,
|
int pgp_parse_pkt_hdr(PullFilter * src, uint8 *tag, int *len_p,
|
||||||
int allow_ctx);
|
int allow_ctx);
|
||||||
|
|
||||||
int pgp_skip_packet(PullFilter *pkt);
|
int pgp_skip_packet(PullFilter * pkt);
|
||||||
int pgp_expect_packet_end(PullFilter *pkt);
|
int pgp_expect_packet_end(PullFilter * pkt);
|
||||||
|
|
||||||
int pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst);
|
int pgp_write_pubenc_sesskey(PGP_Context * ctx, PushFilter * dst);
|
||||||
int pgp_create_pkt_writer(PushFilter *dst, int tag, PushFilter **res_p);
|
int pgp_create_pkt_writer(PushFilter * dst, int tag, PushFilter ** res_p);
|
||||||
|
|
||||||
int pgp_mpi_alloc(int bits, PGP_MPI **mpi);
|
int pgp_mpi_alloc(int bits, PGP_MPI ** mpi);
|
||||||
int pgp_mpi_create(uint8 *data, int bits, PGP_MPI **mpi);
|
int pgp_mpi_create(uint8 *data, int bits, PGP_MPI ** mpi);
|
||||||
int pgp_mpi_free(PGP_MPI *mpi);
|
int pgp_mpi_free(PGP_MPI * mpi);
|
||||||
int pgp_mpi_read(PullFilter *src, PGP_MPI **mpi);
|
int pgp_mpi_read(PullFilter * src, PGP_MPI ** mpi);
|
||||||
int pgp_mpi_write(PushFilter *dst, PGP_MPI *n);
|
int pgp_mpi_write(PushFilter * dst, PGP_MPI * n);
|
||||||
int pgp_mpi_hash(PX_MD *md, PGP_MPI *n);
|
int pgp_mpi_hash(PX_MD * md, PGP_MPI * n);
|
||||||
unsigned pgp_mpi_cksum(unsigned cksum, PGP_MPI *n);
|
unsigned pgp_mpi_cksum(unsigned cksum, PGP_MPI * n);
|
||||||
|
|
||||||
int pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *m,
|
int pgp_elgamal_encrypt(PGP_PubKey * pk, PGP_MPI * m,
|
||||||
PGP_MPI **c1, PGP_MPI **c2);
|
PGP_MPI ** c1, PGP_MPI ** c2);
|
||||||
int pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *c1, PGP_MPI *c2,
|
int pgp_elgamal_decrypt(PGP_PubKey * pk, PGP_MPI * c1, PGP_MPI * c2,
|
||||||
PGP_MPI **m);
|
PGP_MPI ** m);
|
||||||
int pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *m, PGP_MPI **c);
|
int pgp_rsa_encrypt(PGP_PubKey * pk, PGP_MPI * m, PGP_MPI ** c);
|
||||||
int pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *c, PGP_MPI **m);
|
int pgp_rsa_decrypt(PGP_PubKey * pk, PGP_MPI * c, PGP_MPI ** m);
|
||||||
|
|
||||||
extern struct PullFilterOps pgp_decrypt_filter;
|
extern struct PullFilterOps pgp_decrypt_filter;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.c,v 1.14 2005/09/24 19:14:04 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.c,v 1.15 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -77,9 +77,9 @@ struct px_crypt_algo
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct px_crypt_algo
|
static const struct px_crypt_algo
|
||||||
px_crypt_list[] = {
|
px_crypt_list[] = {
|
||||||
{"$2a$", 4, run_crypt_bf},
|
{"$2a$", 4, run_crypt_bf},
|
||||||
{"$2$", 3, NULL}, /* N/A */
|
{"$2$", 3, NULL}, /* N/A */
|
||||||
{"$1$", 3, run_crypt_md5},
|
{"$1$", 3, run_crypt_md5},
|
||||||
{"_", 1, run_crypt_des},
|
{"_", 1, run_crypt_des},
|
||||||
{"", 0, run_crypt_des},
|
{"", 0, run_crypt_des},
|
||||||
@ -164,4 +164,3 @@ px_gen_salt(const char *salt_type, char *buf, int rounds)
|
|||||||
|
|
||||||
return strlen(p);
|
return strlen(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.h,v 1.8 2005/08/13 02:06:20 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/px-crypt.h,v 1.9 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _PX_CRYPT_H
|
#ifndef _PX_CRYPT_H
|
||||||
@ -65,13 +65,13 @@ extern char px_crypt_a64[];
|
|||||||
|
|
||||||
/* crypt-gensalt.c */
|
/* crypt-gensalt.c */
|
||||||
char *_crypt_gensalt_traditional_rn(unsigned long count,
|
char *_crypt_gensalt_traditional_rn(unsigned long count,
|
||||||
const char *input, int size, char *output, int output_size);
|
const char *input, int size, char *output, int output_size);
|
||||||
char *_crypt_gensalt_extended_rn(unsigned long count,
|
char *_crypt_gensalt_extended_rn(unsigned long count,
|
||||||
const char *input, int size, char *output, int output_size);
|
const char *input, int size, char *output, int output_size);
|
||||||
char *_crypt_gensalt_md5_rn(unsigned long count,
|
char *_crypt_gensalt_md5_rn(unsigned long count,
|
||||||
const char *input, int size, char *output, int output_size);
|
const char *input, int size, char *output, int output_size);
|
||||||
char *_crypt_gensalt_blowfish_rn(unsigned long count,
|
char *_crypt_gensalt_blowfish_rn(unsigned long count,
|
||||||
const char *input, int size, char *output, int output_size);
|
const char *input, int size, char *output, int output_size);
|
||||||
|
|
||||||
/* disable 'extended DES crypt' */
|
/* disable 'extended DES crypt' */
|
||||||
/* #define DISABLE_XDES */
|
/* #define DISABLE_XDES */
|
||||||
|
@ -26,15 +26,16 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/px.c,v 1.14 2005/08/13 02:06:20 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/px.c,v 1.15 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "px.h"
|
#include "px.h"
|
||||||
|
|
||||||
struct error_desc {
|
struct error_desc
|
||||||
int err;
|
{
|
||||||
|
int err;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,14 +68,14 @@ static const struct error_desc px_err_list[] = {
|
|||||||
{PXE_PGP_UNEXPECTED_PKT, "Unexpected packet in key data"},
|
{PXE_PGP_UNEXPECTED_PKT, "Unexpected packet in key data"},
|
||||||
{PXE_PGP_NO_BIGNUM,
|
{PXE_PGP_NO_BIGNUM,
|
||||||
"public-key functions disabled - "
|
"public-key functions disabled - "
|
||||||
"pgcrypto needs OpenSSL for bignums"},
|
"pgcrypto needs OpenSSL for bignums"},
|
||||||
{PXE_PGP_MATH_FAILED, "Math operation failed"},
|
{PXE_PGP_MATH_FAILED, "Math operation failed"},
|
||||||
{PXE_PGP_SHORT_ELGAMAL_KEY, "Elgamal keys must be at least 1024 bits long"},
|
{PXE_PGP_SHORT_ELGAMAL_KEY, "Elgamal keys must be at least 1024 bits long"},
|
||||||
{PXE_PGP_RSA_UNSUPPORTED, "pgcrypto does not support RSA keys"},
|
{PXE_PGP_RSA_UNSUPPORTED, "pgcrypto does not support RSA keys"},
|
||||||
{PXE_PGP_UNKNOWN_PUBALGO, "Unknown public-key encryption algorithm"},
|
{PXE_PGP_UNKNOWN_PUBALGO, "Unknown public-key encryption algorithm"},
|
||||||
{PXE_PGP_WRONG_KEY, "Wrong key"},
|
{PXE_PGP_WRONG_KEY, "Wrong key"},
|
||||||
{PXE_PGP_MULTIPLE_KEYS,
|
{PXE_PGP_MULTIPLE_KEYS,
|
||||||
"Several keys given - pgcrypto does not handle keyring"},
|
"Several keys given - pgcrypto does not handle keyring"},
|
||||||
{PXE_PGP_EXPECT_PUBLIC_KEY, "Refusing to encrypt with secret key"},
|
{PXE_PGP_EXPECT_PUBLIC_KEY, "Refusing to encrypt with secret key"},
|
||||||
{PXE_PGP_EXPECT_SECRET_KEY, "Cannot decrypt with public key"},
|
{PXE_PGP_EXPECT_SECRET_KEY, "Cannot decrypt with public key"},
|
||||||
{PXE_PGP_NOT_V4_KEYPKT, "Only V4 key packets are supported"},
|
{PXE_PGP_NOT_V4_KEYPKT, "Only V4 key packets are supported"},
|
||||||
@ -91,9 +92,11 @@ static const struct error_desc px_err_list[] = {
|
|||||||
{0, NULL},
|
{0, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *px_strerror(int err)
|
const char *
|
||||||
|
px_strerror(int err)
|
||||||
{
|
{
|
||||||
const struct error_desc *e;
|
const struct error_desc *e;
|
||||||
|
|
||||||
for (e = px_err_list; e->desc; e++)
|
for (e = px_err_list; e->desc; e++)
|
||||||
if (e->err == err)
|
if (e->err == err)
|
||||||
return e->desc;
|
return e->desc;
|
||||||
@ -113,19 +116,24 @@ px_resolve_alias(const PX_Alias * list, const char *name)
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void (*debug_handler)(const char *) = NULL;
|
static void (*debug_handler) (const char *) = NULL;
|
||||||
|
|
||||||
void px_set_debug_handler(void (*handler)(const char *))
|
void
|
||||||
|
px_set_debug_handler(void (*handler) (const char *))
|
||||||
{
|
{
|
||||||
debug_handler = handler;
|
debug_handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void px_debug(const char *fmt, ...)
|
void
|
||||||
|
px_debug(const char *fmt,...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
if (debug_handler) {
|
if (debug_handler)
|
||||||
char buf[512];
|
{
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
debug_handler(buf);
|
debug_handler(buf);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/px.h,v 1.15 2005/08/13 02:06:20 momjian Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/px.h,v 1.16 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __PX_H
|
#ifndef __PX_H
|
||||||
@ -90,12 +90,12 @@ void px_free(void *p);
|
|||||||
|
|
||||||
#define PXE_PGP_CORRUPT_DATA -100
|
#define PXE_PGP_CORRUPT_DATA -100
|
||||||
#define PXE_PGP_CORRUPT_ARMOR -101
|
#define PXE_PGP_CORRUPT_ARMOR -101
|
||||||
#define PXE_PGP_UNSUPPORTED_COMPR -102
|
#define PXE_PGP_UNSUPPORTED_COMPR -102
|
||||||
#define PXE_PGP_UNSUPPORTED_CIPHER -103
|
#define PXE_PGP_UNSUPPORTED_CIPHER -103
|
||||||
#define PXE_PGP_UNSUPPORTED_HASH -104
|
#define PXE_PGP_UNSUPPORTED_HASH -104
|
||||||
#define PXE_PGP_COMPRESSION_ERROR -105
|
#define PXE_PGP_COMPRESSION_ERROR -105
|
||||||
#define PXE_PGP_NOT_TEXT -106
|
#define PXE_PGP_NOT_TEXT -106
|
||||||
#define PXE_PGP_UNEXPECTED_PKT -107
|
#define PXE_PGP_UNEXPECTED_PKT -107
|
||||||
#define PXE_PGP_NO_BIGNUM -108
|
#define PXE_PGP_NO_BIGNUM -108
|
||||||
#define PXE_PGP_MATH_FAILED -109
|
#define PXE_PGP_MATH_FAILED -109
|
||||||
#define PXE_PGP_SHORT_ELGAMAL_KEY -110
|
#define PXE_PGP_SHORT_ELGAMAL_KEY -110
|
||||||
@ -110,7 +110,7 @@ void px_free(void *p);
|
|||||||
#define PXE_PGP_NO_USABLE_KEY -119
|
#define PXE_PGP_NO_USABLE_KEY -119
|
||||||
#define PXE_PGP_NEED_SECRET_PSW -120
|
#define PXE_PGP_NEED_SECRET_PSW -120
|
||||||
#define PXE_PGP_BAD_S2K_MODE -121
|
#define PXE_PGP_BAD_S2K_MODE -121
|
||||||
#define PXE_PGP_UNSUPPORTED_PUBALGO -122
|
#define PXE_PGP_UNSUPPORTED_PUBALGO -122
|
||||||
#define PXE_PGP_MULTIPLE_SUBKEYS -123
|
#define PXE_PGP_MULTIPLE_SUBKEYS -123
|
||||||
|
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ struct px_digest
|
|||||||
union
|
union
|
||||||
{
|
{
|
||||||
unsigned code;
|
unsigned code;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
} p;
|
} p;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -207,9 +207,10 @@ const char *px_strerror(int err);
|
|||||||
|
|
||||||
const char *px_resolve_alias(const PX_Alias * aliases, const char *name);
|
const char *px_resolve_alias(const PX_Alias * aliases, const char *name);
|
||||||
|
|
||||||
void px_set_debug_handler(void (*handler)(const char *));
|
void px_set_debug_handler(void (*handler) (const char *));
|
||||||
|
|
||||||
#ifdef PX_DEBUG
|
#ifdef PX_DEBUG
|
||||||
void px_debug(const char *fmt, ...);
|
void px_debug(const char *fmt,...);
|
||||||
#else
|
#else
|
||||||
#define px_debug(...)
|
#define px_debug(...)
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/random.c,v 1.15 2005/07/18 17:09:01 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/random.c,v 1.16 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -95,7 +95,6 @@ try_dev_random(uint8 *dst)
|
|||||||
dst += res;
|
dst += res;
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -114,16 +113,17 @@ try_dev_random(uint8 *dst)
|
|||||||
*
|
*
|
||||||
* try to use Microsoft crypto API
|
* try to use Microsoft crypto API
|
||||||
*/
|
*/
|
||||||
static uint8 * try_win32_genrand(uint8 *dst)
|
static uint8 *
|
||||||
|
try_win32_genrand(uint8 *dst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
HCRYPTPROV h = 0;
|
HCRYPTPROV h = 0;
|
||||||
|
|
||||||
res = CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL,
|
res = CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL,
|
||||||
(CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
|
(CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
|
||||||
if (!res)
|
if (!res)
|
||||||
res = CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL,
|
res = CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL,
|
||||||
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET);
|
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET);
|
||||||
if (!res)
|
if (!res)
|
||||||
return dst;
|
return dst;
|
||||||
|
|
||||||
@ -135,9 +135,10 @@ static uint8 * try_win32_genrand(uint8 *dst)
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8 * try_win32_perfc(uint8 *dst)
|
static uint8 *
|
||||||
|
try_win32_perfc(uint8 *dst)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
LARGE_INTEGER time;
|
LARGE_INTEGER time;
|
||||||
|
|
||||||
res = QueryPerformanceCounter(&time);
|
res = QueryPerformanceCounter(&time);
|
||||||
@ -147,8 +148,7 @@ static uint8 * try_win32_perfc(uint8 *dst)
|
|||||||
memcpy(dst, &time, sizeof(time));
|
memcpy(dst, &time, sizeof(time));
|
||||||
return dst + sizeof(time);
|
return dst + sizeof(time);
|
||||||
}
|
}
|
||||||
|
#endif /* WIN32 */
|
||||||
#endif /* WIN32 */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -174,33 +174,34 @@ static uint8 * try_win32_perfc(uint8 *dst)
|
|||||||
static uint8 *
|
static uint8 *
|
||||||
try_unix_std(uint8 *dst)
|
try_unix_std(uint8 *dst)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int x;
|
int x;
|
||||||
PX_MD *md;
|
PX_MD *md;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/* process id */
|
/* process id */
|
||||||
pid = getpid();
|
pid = getpid();
|
||||||
memcpy(dst, (uint8*)&pid, sizeof(pid));
|
memcpy(dst, (uint8 *) &pid, sizeof(pid));
|
||||||
dst += sizeof(pid);
|
dst += sizeof(pid);
|
||||||
|
|
||||||
/* time */
|
/* time */
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
memcpy(dst, (uint8*)&tv, sizeof(tv));
|
memcpy(dst, (uint8 *) &tv, sizeof(tv));
|
||||||
dst += sizeof(tv);
|
dst += sizeof(tv);
|
||||||
|
|
||||||
/* pointless, but should not hurt */
|
/* pointless, but should not hurt */
|
||||||
x = random();
|
x = random();
|
||||||
memcpy(dst, (uint8*)&x, sizeof(x));
|
memcpy(dst, (uint8 *) &x, sizeof(x));
|
||||||
dst += sizeof(x);
|
dst += sizeof(x);
|
||||||
|
|
||||||
/* let's be desperate */
|
/* let's be desperate */
|
||||||
res = px_find_digest("sha1", &md);
|
res = px_find_digest("sha1", &md);
|
||||||
if (res >= 0) {
|
if (res >= 0)
|
||||||
uint8 *ptr;
|
{
|
||||||
uint8 stack[8192];
|
uint8 *ptr;
|
||||||
int alloc = 32*1024;
|
uint8 stack[8192];
|
||||||
|
int alloc = 32 * 1024;
|
||||||
|
|
||||||
px_md_update(md, stack, sizeof(stack));
|
px_md_update(md, stack, sizeof(stack));
|
||||||
ptr = px_alloc(alloc);
|
ptr = px_alloc(alloc);
|
||||||
@ -215,7 +216,6 @@ try_unix_std(uint8 *dst)
|
|||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -223,9 +223,11 @@ try_unix_std(uint8 *dst)
|
|||||||
*
|
*
|
||||||
* dst should have room for 1024 bytes.
|
* dst should have room for 1024 bytes.
|
||||||
*/
|
*/
|
||||||
unsigned px_acquire_system_randomness(uint8 *dst)
|
unsigned
|
||||||
|
px_acquire_system_randomness(uint8 *dst)
|
||||||
{
|
{
|
||||||
uint8 *p = dst;
|
uint8 *p = dst;
|
||||||
|
|
||||||
#ifdef TRY_DEV_RANDOM
|
#ifdef TRY_DEV_RANDOM
|
||||||
p = try_dev_random(p);
|
p = try_dev_random(p);
|
||||||
#endif
|
#endif
|
||||||
@ -240,4 +242,3 @@ unsigned px_acquire_system_randomness(uint8 *dst)
|
|||||||
#endif
|
#endif
|
||||||
return p - dst;
|
return p - dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* $OpenBSD: rijndael.c,v 1.6 2000/12/09 18:51:34 markus Exp $ */
|
/* $OpenBSD: rijndael.c,v 1.6 2000/12/09 18:51:34 markus Exp $ */
|
||||||
|
|
||||||
/* $PostgreSQL: pgsql/contrib/pgcrypto/rijndael.c,v 1.11 2005/07/11 15:07:59 tgl Exp $ */
|
/* $PostgreSQL: pgsql/contrib/pgcrypto/rijndael.c,v 1.12 2005/10/15 02:49:06 momjian Exp $ */
|
||||||
|
|
||||||
/* This is an independent implementation of the encryption algorithm: */
|
/* This is an independent implementation of the encryption algorithm: */
|
||||||
/* */
|
/* */
|
||||||
@ -91,7 +91,6 @@ static void gen_tabs(void);
|
|||||||
|
|
||||||
#include "rijndael.tbl"
|
#include "rijndael.tbl"
|
||||||
#define tab_gen 1
|
#define tab_gen 1
|
||||||
|
|
||||||
#else /* !PRE_CALC_TABLES */
|
#else /* !PRE_CALC_TABLES */
|
||||||
|
|
||||||
static u1byte pow_tab[256];
|
static u1byte pow_tab[256];
|
||||||
@ -143,7 +142,6 @@ static u4byte tab_gen = 0;
|
|||||||
il_tab[1][byte((bi)[((n) + 3) & 3],1)] ^ \
|
il_tab[1][byte((bi)[((n) + 3) & 3],1)] ^ \
|
||||||
il_tab[2][byte((bi)[((n) + 2) & 3],2)] ^ \
|
il_tab[2][byte((bi)[((n) + 2) & 3],2)] ^ \
|
||||||
il_tab[3][byte((bi)[((n) + 1) & 3],3)] ^ *((k) + (n))
|
il_tab[3][byte((bi)[((n) + 1) & 3],3)] ^ *((k) + (n))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define ls_box(x) \
|
#define ls_box(x) \
|
||||||
|
@ -11,18 +11,18 @@
|
|||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. Neither the name of the copyright holder nor the names of contributors
|
* 3. Neither the name of the copyright holder nor the names of contributors
|
||||||
* may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
@ -33,7 +33,7 @@
|
|||||||
*
|
*
|
||||||
* $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
|
* $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/contrib/pgcrypto/sha2.c,v 1.4 2005/07/12 20:27:42 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgcrypto/sha2.c,v 1.5 2005/10/15 02:49:06 momjian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -48,11 +48,11 @@
|
|||||||
* loop version for the hash transform rounds (defined using macros
|
* loop version for the hash transform rounds (defined using macros
|
||||||
* later in this file). Either define on the command line, for example:
|
* later in this file). Either define on the command line, for example:
|
||||||
*
|
*
|
||||||
* cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
|
* cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
|
||||||
*
|
*
|
||||||
* or define below:
|
* or define below:
|
||||||
*
|
*
|
||||||
* #define SHA2_UNROLL_TRANSFORM
|
* #define SHA2_UNROLL_TRANSFORM
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -69,16 +69,16 @@
|
|||||||
* If your system does not define the above, then you can do so by
|
* If your system does not define the above, then you can do so by
|
||||||
* hand like this:
|
* hand like this:
|
||||||
*
|
*
|
||||||
* #define LITTLE_ENDIAN 1234
|
* #define LITTLE_ENDIAN 1234
|
||||||
* #define BIG_ENDIAN 4321
|
* #define BIG_ENDIAN 4321
|
||||||
*
|
*
|
||||||
* And for little-endian machines, add:
|
* And for little-endian machines, add:
|
||||||
*
|
*
|
||||||
* #define BYTE_ORDER LITTLE_ENDIAN
|
* #define BYTE_ORDER LITTLE_ENDIAN
|
||||||
*
|
*
|
||||||
* Or for big-endian machines:
|
* Or for big-endian machines:
|
||||||
*
|
*
|
||||||
* #define BYTE_ORDER BIG_ENDIAN
|
* #define BYTE_ORDER BIG_ENDIAN
|
||||||
*
|
*
|
||||||
* The FreeBSD machine this was written on defines BYTE_ORDER
|
* The FreeBSD machine this was written on defines BYTE_ORDER
|
||||||
* appropriately by including <sys/types.h> (which in turn includes
|
* appropriately by including <sys/types.h> (which in turn includes
|
||||||
@ -108,11 +108,11 @@
|
|||||||
uint64 tmp = (w); \
|
uint64 tmp = (w); \
|
||||||
tmp = (tmp >> 32) | (tmp << 32); \
|
tmp = (tmp >> 32) | (tmp << 32); \
|
||||||
tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
|
tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
|
||||||
((tmp & 0x00ff00ff00ff00ffULL) << 8); \
|
((tmp & 0x00ff00ff00ff00ffULL) << 8); \
|
||||||
(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
|
(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
|
||||||
((tmp & 0x0000ffff0000ffffULL) << 16); \
|
((tmp & 0x0000ffff0000ffffULL) << 16); \
|
||||||
}
|
}
|
||||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro for incrementally adding the unsigned 64-bit integer n to the
|
* Macro for incrementally adding the unsigned 64-bit integer n to the
|
||||||
@ -130,13 +130,13 @@
|
|||||||
/*
|
/*
|
||||||
* Bit shifting and rotation (used by the six SHA-XYZ logical functions:
|
* Bit shifting and rotation (used by the six SHA-XYZ logical functions:
|
||||||
*
|
*
|
||||||
* NOTE: The naming of R and S appears backwards here (R is a SHIFT and
|
* NOTE: The naming of R and S appears backwards here (R is a SHIFT and
|
||||||
* S is a ROTATION) because the SHA-256/384/512 description document
|
* S is a ROTATION) because the SHA-256/384/512 description document
|
||||||
* (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
|
* (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
|
||||||
* same "backwards" definition.
|
* same "backwards" definition.
|
||||||
*/
|
*/
|
||||||
/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
|
/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
|
||||||
#define R(b,x) ((x) >> (b))
|
#define R(b,x) ((x) >> (b))
|
||||||
/* 32-bit Rotate-right (used in SHA-256): */
|
/* 32-bit Rotate-right (used in SHA-256): */
|
||||||
#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
|
#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
|
||||||
/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
|
/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
|
||||||
@ -163,9 +163,9 @@
|
|||||||
* library -- they are intended for private internal visibility/use
|
* library -- they are intended for private internal visibility/use
|
||||||
* only.
|
* only.
|
||||||
*/
|
*/
|
||||||
void SHA512_Last(SHA512_CTX *);
|
void SHA512_Last(SHA512_CTX *);
|
||||||
void SHA256_Transform(SHA256_CTX *, const uint8 *);
|
void SHA256_Transform(SHA256_CTX *, const uint8 *);
|
||||||
void SHA512_Transform(SHA512_CTX *, const uint8 *);
|
void SHA512_Transform(SHA512_CTX *, const uint8 *);
|
||||||
|
|
||||||
|
|
||||||
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
|
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
|
||||||
@ -272,7 +272,7 @@ static const uint64 sha512_initial_hash_value[8] = {
|
|||||||
|
|
||||||
/*** SHA-256: *********************************************************/
|
/*** SHA-256: *********************************************************/
|
||||||
void
|
void
|
||||||
SHA256_Init(SHA256_CTX *context)
|
SHA256_Init(SHA256_CTX * context)
|
||||||
{
|
{
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
return;
|
return;
|
||||||
@ -285,36 +285,46 @@ SHA256_Init(SHA256_CTX *context)
|
|||||||
|
|
||||||
/* Unrolled SHA-256 round macros: */
|
/* Unrolled SHA-256 round macros: */
|
||||||
|
|
||||||
#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do { \
|
#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do { \
|
||||||
W256[j] = (uint32)data[3] | ((uint32)data[2] << 8) | \
|
W256[j] = (uint32)data[3] | ((uint32)data[2] << 8) | \
|
||||||
((uint32)data[1] << 16) | ((uint32)data[0] << 24); \
|
((uint32)data[1] << 16) | ((uint32)data[0] << 24); \
|
||||||
data += 4; \
|
data += 4; \
|
||||||
T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \
|
T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \
|
||||||
(d) += T1; \
|
(d) += T1; \
|
||||||
(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \
|
(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \
|
||||||
j++; \
|
j++; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define ROUND256(a,b,c,d,e,f,g,h) do { \
|
#define ROUND256(a,b,c,d,e,f,g,h) do { \
|
||||||
s0 = W256[(j+1)&0x0f]; \
|
s0 = W256[(j+1)&0x0f]; \
|
||||||
s0 = sigma0_256(s0); \
|
s0 = sigma0_256(s0); \
|
||||||
s1 = W256[(j+14)&0x0f]; \
|
s1 = W256[(j+14)&0x0f]; \
|
||||||
s1 = sigma1_256(s1); \
|
s1 = sigma1_256(s1); \
|
||||||
T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + \
|
T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + \
|
||||||
(W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
|
(W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
|
||||||
(d) += T1; \
|
(d) += T1; \
|
||||||
(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \
|
(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \
|
||||||
j++; \
|
j++; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
void
|
void
|
||||||
SHA256_Transform(SHA256_CTX *context, const uint8 *data)
|
SHA256_Transform(SHA256_CTX * context, const uint8 *data)
|
||||||
{
|
{
|
||||||
uint32 a, b, c, d, e, f, g, h, s0, s1;
|
uint32 a,
|
||||||
uint32 T1, *W256;
|
b,
|
||||||
int j;
|
c,
|
||||||
|
d,
|
||||||
|
e,
|
||||||
|
f,
|
||||||
|
g,
|
||||||
|
h,
|
||||||
|
s0,
|
||||||
|
s1;
|
||||||
|
uint32 T1,
|
||||||
|
*W256;
|
||||||
|
int j;
|
||||||
|
|
||||||
W256 = (uint32 *)context->buffer;
|
W256 = (uint32 *) context->buffer;
|
||||||
|
|
||||||
/* Initialize registers with the prev. intermediate value */
|
/* Initialize registers with the prev. intermediate value */
|
||||||
a = context->state[0];
|
a = context->state[0];
|
||||||
@ -327,28 +337,30 @@ SHA256_Transform(SHA256_CTX *context, const uint8 *data)
|
|||||||
h = context->state[7];
|
h = context->state[7];
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
/* Rounds 0 to 15 (unrolled): */
|
/* Rounds 0 to 15 (unrolled): */
|
||||||
ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
|
ROUND256_0_TO_15(a, b, c, d, e, f, g, h);
|
||||||
ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
|
ROUND256_0_TO_15(h, a, b, c, d, e, f, g);
|
||||||
ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
|
ROUND256_0_TO_15(g, h, a, b, c, d, e, f);
|
||||||
ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
|
ROUND256_0_TO_15(f, g, h, a, b, c, d, e);
|
||||||
ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
|
ROUND256_0_TO_15(e, f, g, h, a, b, c, d);
|
||||||
ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
|
ROUND256_0_TO_15(d, e, f, g, h, a, b, c);
|
||||||
ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
|
ROUND256_0_TO_15(c, d, e, f, g, h, a, b);
|
||||||
ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
|
ROUND256_0_TO_15(b, c, d, e, f, g, h, a);
|
||||||
} while (j < 16);
|
} while (j < 16);
|
||||||
|
|
||||||
/* Now for the remaining rounds to 64: */
|
/* Now for the remaining rounds to 64: */
|
||||||
do {
|
do
|
||||||
ROUND256(a,b,c,d,e,f,g,h);
|
{
|
||||||
ROUND256(h,a,b,c,d,e,f,g);
|
ROUND256(a, b, c, d, e, f, g, h);
|
||||||
ROUND256(g,h,a,b,c,d,e,f);
|
ROUND256(h, a, b, c, d, e, f, g);
|
||||||
ROUND256(f,g,h,a,b,c,d,e);
|
ROUND256(g, h, a, b, c, d, e, f);
|
||||||
ROUND256(e,f,g,h,a,b,c,d);
|
ROUND256(f, g, h, a, b, c, d, e);
|
||||||
ROUND256(d,e,f,g,h,a,b,c);
|
ROUND256(e, f, g, h, a, b, c, d);
|
||||||
ROUND256(c,d,e,f,g,h,a,b);
|
ROUND256(d, e, f, g, h, a, b, c);
|
||||||
ROUND256(b,c,d,e,f,g,h,a);
|
ROUND256(c, d, e, f, g, h, a, b);
|
||||||
|
ROUND256(b, c, d, e, f, g, h, a);
|
||||||
} while (j < 64);
|
} while (j < 64);
|
||||||
|
|
||||||
/* Compute the current intermediate hash value */
|
/* Compute the current intermediate hash value */
|
||||||
@ -364,17 +376,27 @@ SHA256_Transform(SHA256_CTX *context, const uint8 *data)
|
|||||||
/* Clean up */
|
/* Clean up */
|
||||||
a = b = c = d = e = f = g = h = T1 = 0;
|
a = b = c = d = e = f = g = h = T1 = 0;
|
||||||
}
|
}
|
||||||
|
#else /* SHA2_UNROLL_TRANSFORM */
|
||||||
#else /* SHA2_UNROLL_TRANSFORM */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SHA256_Transform(SHA256_CTX *context, const uint8 *data)
|
SHA256_Transform(SHA256_CTX * context, const uint8 *data)
|
||||||
{
|
{
|
||||||
uint32 a, b, c, d, e, f, g, h, s0, s1;
|
uint32 a,
|
||||||
uint32 T1, T2, *W256;
|
b,
|
||||||
int j;
|
c,
|
||||||
|
d,
|
||||||
|
e,
|
||||||
|
f,
|
||||||
|
g,
|
||||||
|
h,
|
||||||
|
s0,
|
||||||
|
s1;
|
||||||
|
uint32 T1,
|
||||||
|
T2,
|
||||||
|
*W256;
|
||||||
|
int j;
|
||||||
|
|
||||||
W256 = (uint32 *)context->buffer;
|
W256 = (uint32 *) context->buffer;
|
||||||
|
|
||||||
/* Initialize registers with the prev. intermediate value */
|
/* Initialize registers with the prev. intermediate value */
|
||||||
a = context->state[0];
|
a = context->state[0];
|
||||||
@ -387,9 +409,10 @@ SHA256_Transform(SHA256_CTX *context, const uint8 *data)
|
|||||||
h = context->state[7];
|
h = context->state[7];
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
do {
|
do
|
||||||
W256[j] = (uint32)data[3] | ((uint32)data[2] << 8) |
|
{
|
||||||
((uint32)data[1] << 16) | ((uint32)data[0] << 24);
|
W256[j] = (uint32) data[3] | ((uint32) data[2] << 8) |
|
||||||
|
((uint32) data[1] << 16) | ((uint32) data[0] << 24);
|
||||||
data += 4;
|
data += 4;
|
||||||
/* Apply the SHA-256 compression function to update a..h */
|
/* Apply the SHA-256 compression function to update a..h */
|
||||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
|
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
|
||||||
@ -406,16 +429,17 @@ SHA256_Transform(SHA256_CTX *context, const uint8 *data)
|
|||||||
j++;
|
j++;
|
||||||
} while (j < 16);
|
} while (j < 16);
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
/* Part of the message block expansion: */
|
/* Part of the message block expansion: */
|
||||||
s0 = W256[(j+1)&0x0f];
|
s0 = W256[(j + 1) & 0x0f];
|
||||||
s0 = sigma0_256(s0);
|
s0 = sigma0_256(s0);
|
||||||
s1 = W256[(j+14)&0x0f];
|
s1 = W256[(j + 14) & 0x0f];
|
||||||
s1 = sigma1_256(s1);
|
s1 = sigma1_256(s1);
|
||||||
|
|
||||||
/* Apply the SHA-256 compression function to update a..h */
|
/* Apply the SHA-256 compression function to update a..h */
|
||||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
|
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
|
||||||
(W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
|
(W256[j & 0x0f] += s1 + W256[(j + 9) & 0x0f] + s0);
|
||||||
T2 = Sigma0_256(a) + Maj(a, b, c);
|
T2 = Sigma0_256(a) + Maj(a, b, c);
|
||||||
h = g;
|
h = g;
|
||||||
g = f;
|
g = f;
|
||||||
@ -442,31 +466,35 @@ SHA256_Transform(SHA256_CTX *context, const uint8 *data)
|
|||||||
/* Clean up */
|
/* Clean up */
|
||||||
a = b = c = d = e = f = g = h = T1 = T2 = 0;
|
a = b = c = d = e = f = g = h = T1 = T2 = 0;
|
||||||
}
|
}
|
||||||
|
#endif /* SHA2_UNROLL_TRANSFORM */
|
||||||
#endif /* SHA2_UNROLL_TRANSFORM */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SHA256_Update(SHA256_CTX *context, const uint8 *data, size_t len)
|
SHA256_Update(SHA256_CTX * context, const uint8 *data, size_t len)
|
||||||
{
|
{
|
||||||
size_t freespace, usedspace;
|
size_t freespace,
|
||||||
|
usedspace;
|
||||||
|
|
||||||
/* Calling with no data is valid (we do nothing) */
|
/* Calling with no data is valid (we do nothing) */
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
||||||
if (usedspace > 0) {
|
if (usedspace > 0)
|
||||||
|
{
|
||||||
/* Calculate how much free space is available in the buffer */
|
/* Calculate how much free space is available in the buffer */
|
||||||
freespace = SHA256_BLOCK_LENGTH - usedspace;
|
freespace = SHA256_BLOCK_LENGTH - usedspace;
|
||||||
|
|
||||||
if (len >= freespace) {
|
if (len >= freespace)
|
||||||
|
{
|
||||||
/* Fill the buffer completely and process it */
|
/* Fill the buffer completely and process it */
|
||||||
memcpy(&context->buffer[usedspace], data, freespace);
|
memcpy(&context->buffer[usedspace], data, freespace);
|
||||||
context->bitcount += freespace << 3;
|
context->bitcount += freespace << 3;
|
||||||
len -= freespace;
|
len -= freespace;
|
||||||
data += freespace;
|
data += freespace;
|
||||||
SHA256_Transform(context, context->buffer);
|
SHA256_Transform(context, context->buffer);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* The buffer is not yet full */
|
/* The buffer is not yet full */
|
||||||
memcpy(&context->buffer[usedspace], data, len);
|
memcpy(&context->buffer[usedspace], data, len);
|
||||||
context->bitcount += len << 3;
|
context->bitcount += len << 3;
|
||||||
@ -475,14 +503,16 @@ SHA256_Update(SHA256_CTX *context, const uint8 *data, size_t len)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (len >= SHA256_BLOCK_LENGTH) {
|
while (len >= SHA256_BLOCK_LENGTH)
|
||||||
|
{
|
||||||
/* Process as many complete blocks as we can */
|
/* Process as many complete blocks as we can */
|
||||||
SHA256_Transform(context, data);
|
SHA256_Transform(context, data);
|
||||||
context->bitcount += SHA256_BLOCK_LENGTH << 3;
|
context->bitcount += SHA256_BLOCK_LENGTH << 3;
|
||||||
len -= SHA256_BLOCK_LENGTH;
|
len -= SHA256_BLOCK_LENGTH;
|
||||||
data += SHA256_BLOCK_LENGTH;
|
data += SHA256_BLOCK_LENGTH;
|
||||||
}
|
}
|
||||||
if (len > 0) {
|
if (len > 0)
|
||||||
|
{
|
||||||
/* There's left-overs, so save 'em */
|
/* There's left-overs, so save 'em */
|
||||||
memcpy(context->buffer, data, len);
|
memcpy(context->buffer, data, len);
|
||||||
context->bitcount += len << 3;
|
context->bitcount += len << 3;
|
||||||
@ -492,26 +522,32 @@ SHA256_Update(SHA256_CTX *context, const uint8 *data, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SHA256_Final(uint8 digest[], SHA256_CTX *context)
|
SHA256_Final(uint8 digest[], SHA256_CTX * context)
|
||||||
{
|
{
|
||||||
unsigned int usedspace;
|
unsigned int usedspace;
|
||||||
|
|
||||||
/* If no digest buffer is passed, we don't bother doing this: */
|
/* If no digest buffer is passed, we don't bother doing this: */
|
||||||
if (digest != NULL) {
|
if (digest != NULL)
|
||||||
|
{
|
||||||
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
||||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
/* Convert FROM host byte order */
|
/* Convert FROM host byte order */
|
||||||
REVERSE64(context->bitcount,context->bitcount);
|
REVERSE64(context->bitcount, context->bitcount);
|
||||||
#endif
|
#endif
|
||||||
if (usedspace > 0) {
|
if (usedspace > 0)
|
||||||
|
{
|
||||||
/* Begin padding with a 1 bit: */
|
/* Begin padding with a 1 bit: */
|
||||||
context->buffer[usedspace++] = 0x80;
|
context->buffer[usedspace++] = 0x80;
|
||||||
|
|
||||||
if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
|
if (usedspace <= SHA256_SHORT_BLOCK_LENGTH)
|
||||||
|
{
|
||||||
/* Set-up for the last transform: */
|
/* Set-up for the last transform: */
|
||||||
memset(&context->buffer[usedspace], 0, SHA256_SHORT_BLOCK_LENGTH - usedspace);
|
memset(&context->buffer[usedspace], 0, SHA256_SHORT_BLOCK_LENGTH - usedspace);
|
||||||
} else {
|
}
|
||||||
if (usedspace < SHA256_BLOCK_LENGTH) {
|
else
|
||||||
|
{
|
||||||
|
if (usedspace < SHA256_BLOCK_LENGTH)
|
||||||
|
{
|
||||||
memset(&context->buffer[usedspace], 0, SHA256_BLOCK_LENGTH - usedspace);
|
memset(&context->buffer[usedspace], 0, SHA256_BLOCK_LENGTH - usedspace);
|
||||||
}
|
}
|
||||||
/* Do second-to-last transform: */
|
/* Do second-to-last transform: */
|
||||||
@ -520,7 +556,9 @@ SHA256_Final(uint8 digest[], SHA256_CTX *context)
|
|||||||
/* And set-up for the last transform: */
|
/* And set-up for the last transform: */
|
||||||
memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
|
memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Set-up for the last transform: */
|
/* Set-up for the last transform: */
|
||||||
memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
|
memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
|
||||||
|
|
||||||
@ -528,7 +566,7 @@ SHA256_Final(uint8 digest[], SHA256_CTX *context)
|
|||||||
*context->buffer = 0x80;
|
*context->buffer = 0x80;
|
||||||
}
|
}
|
||||||
/* Set the bit count: */
|
/* Set the bit count: */
|
||||||
*(uint64 *)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
|
*(uint64 *) &context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
|
||||||
|
|
||||||
/* Final transform: */
|
/* Final transform: */
|
||||||
SHA256_Transform(context, context->buffer);
|
SHA256_Transform(context, context->buffer);
|
||||||
@ -536,9 +574,11 @@ SHA256_Final(uint8 digest[], SHA256_CTX *context)
|
|||||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
{
|
{
|
||||||
/* Convert TO host byte order */
|
/* Convert TO host byte order */
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 8; j++) {
|
|
||||||
REVERSE32(context->state[j],context->state[j]);
|
for (j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
REVERSE32(context->state[j], context->state[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -553,50 +593,60 @@ SHA256_Final(uint8 digest[], SHA256_CTX *context)
|
|||||||
|
|
||||||
/*** SHA-512: *********************************************************/
|
/*** SHA-512: *********************************************************/
|
||||||
void
|
void
|
||||||
SHA512_Init(SHA512_CTX *context)
|
SHA512_Init(SHA512_CTX * context)
|
||||||
{
|
{
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
return;
|
return;
|
||||||
memcpy(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
|
memcpy(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
|
||||||
memset(context->buffer, 0, SHA512_BLOCK_LENGTH);
|
memset(context->buffer, 0, SHA512_BLOCK_LENGTH);
|
||||||
context->bitcount[0] = context->bitcount[1] = 0;
|
context->bitcount[0] = context->bitcount[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SHA2_UNROLL_TRANSFORM
|
#ifdef SHA2_UNROLL_TRANSFORM
|
||||||
|
|
||||||
/* Unrolled SHA-512 round macros: */
|
/* Unrolled SHA-512 round macros: */
|
||||||
|
|
||||||
#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do { \
|
#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do { \
|
||||||
W512[j] = (uint64)data[7] | ((uint64)data[6] << 8) | \
|
W512[j] = (uint64)data[7] | ((uint64)data[6] << 8) | \
|
||||||
((uint64)data[5] << 16) | ((uint64)data[4] << 24) | \
|
((uint64)data[5] << 16) | ((uint64)data[4] << 24) | \
|
||||||
((uint64)data[3] << 32) | ((uint64)data[2] << 40) | \
|
((uint64)data[3] << 32) | ((uint64)data[2] << 40) | \
|
||||||
((uint64)data[1] << 48) | ((uint64)data[0] << 56); \
|
((uint64)data[1] << 48) | ((uint64)data[0] << 56); \
|
||||||
data += 8; \
|
data += 8; \
|
||||||
T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \
|
T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \
|
||||||
(d) += T1; \
|
(d) += T1; \
|
||||||
(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \
|
(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \
|
||||||
j++; \
|
j++; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
#define ROUND512(a,b,c,d,e,f,g,h) do { \
|
#define ROUND512(a,b,c,d,e,f,g,h) do { \
|
||||||
s0 = W512[(j+1)&0x0f]; \
|
s0 = W512[(j+1)&0x0f]; \
|
||||||
s0 = sigma0_512(s0); \
|
s0 = sigma0_512(s0); \
|
||||||
s1 = W512[(j+14)&0x0f]; \
|
s1 = W512[(j+14)&0x0f]; \
|
||||||
s1 = sigma1_512(s1); \
|
s1 = sigma1_512(s1); \
|
||||||
T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + \
|
T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + \
|
||||||
(W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
|
(W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
|
||||||
(d) += T1; \
|
(d) += T1; \
|
||||||
(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \
|
(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \
|
||||||
j++; \
|
j++; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
void
|
void
|
||||||
SHA512_Transform(SHA512_CTX *context, const uint8 *data)
|
SHA512_Transform(SHA512_CTX * context, const uint8 *data)
|
||||||
{
|
{
|
||||||
uint64 a, b, c, d, e, f, g, h, s0, s1;
|
uint64 a,
|
||||||
uint64 T1, *W512 = (uint64 *)context->buffer;
|
b,
|
||||||
int j;
|
c,
|
||||||
|
d,
|
||||||
|
e,
|
||||||
|
f,
|
||||||
|
g,
|
||||||
|
h,
|
||||||
|
s0,
|
||||||
|
s1;
|
||||||
|
uint64 T1,
|
||||||
|
*W512 = (uint64 *) context->buffer;
|
||||||
|
int j;
|
||||||
|
|
||||||
/* Initialize registers with the prev. intermediate value */
|
/* Initialize registers with the prev. intermediate value */
|
||||||
a = context->state[0];
|
a = context->state[0];
|
||||||
@ -609,27 +659,29 @@ SHA512_Transform(SHA512_CTX *context, const uint8 *data)
|
|||||||
h = context->state[7];
|
h = context->state[7];
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
do {
|
do
|
||||||
ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
|
{
|
||||||
ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
|
ROUND512_0_TO_15(a, b, c, d, e, f, g, h);
|
||||||
ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
|
ROUND512_0_TO_15(h, a, b, c, d, e, f, g);
|
||||||
ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
|
ROUND512_0_TO_15(g, h, a, b, c, d, e, f);
|
||||||
ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
|
ROUND512_0_TO_15(f, g, h, a, b, c, d, e);
|
||||||
ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
|
ROUND512_0_TO_15(e, f, g, h, a, b, c, d);
|
||||||
ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
|
ROUND512_0_TO_15(d, e, f, g, h, a, b, c);
|
||||||
ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
|
ROUND512_0_TO_15(c, d, e, f, g, h, a, b);
|
||||||
|
ROUND512_0_TO_15(b, c, d, e, f, g, h, a);
|
||||||
} while (j < 16);
|
} while (j < 16);
|
||||||
|
|
||||||
/* Now for the remaining rounds up to 79: */
|
/* Now for the remaining rounds up to 79: */
|
||||||
do {
|
do
|
||||||
ROUND512(a,b,c,d,e,f,g,h);
|
{
|
||||||
ROUND512(h,a,b,c,d,e,f,g);
|
ROUND512(a, b, c, d, e, f, g, h);
|
||||||
ROUND512(g,h,a,b,c,d,e,f);
|
ROUND512(h, a, b, c, d, e, f, g);
|
||||||
ROUND512(f,g,h,a,b,c,d,e);
|
ROUND512(g, h, a, b, c, d, e, f);
|
||||||
ROUND512(e,f,g,h,a,b,c,d);
|
ROUND512(f, g, h, a, b, c, d, e);
|
||||||
ROUND512(d,e,f,g,h,a,b,c);
|
ROUND512(e, f, g, h, a, b, c, d);
|
||||||
ROUND512(c,d,e,f,g,h,a,b);
|
ROUND512(d, e, f, g, h, a, b, c);
|
||||||
ROUND512(b,c,d,e,f,g,h,a);
|
ROUND512(c, d, e, f, g, h, a, b);
|
||||||
|
ROUND512(b, c, d, e, f, g, h, a);
|
||||||
} while (j < 80);
|
} while (j < 80);
|
||||||
|
|
||||||
/* Compute the current intermediate hash value */
|
/* Compute the current intermediate hash value */
|
||||||
@ -645,15 +697,25 @@ SHA512_Transform(SHA512_CTX *context, const uint8 *data)
|
|||||||
/* Clean up */
|
/* Clean up */
|
||||||
a = b = c = d = e = f = g = h = T1 = 0;
|
a = b = c = d = e = f = g = h = T1 = 0;
|
||||||
}
|
}
|
||||||
|
#else /* SHA2_UNROLL_TRANSFORM */
|
||||||
#else /* SHA2_UNROLL_TRANSFORM */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SHA512_Transform(SHA512_CTX *context, const uint8 *data)
|
SHA512_Transform(SHA512_CTX * context, const uint8 *data)
|
||||||
{
|
{
|
||||||
uint64 a, b, c, d, e, f, g, h, s0, s1;
|
uint64 a,
|
||||||
uint64 T1, T2, *W512 = (uint64 *)context->buffer;
|
b,
|
||||||
int j;
|
c,
|
||||||
|
d,
|
||||||
|
e,
|
||||||
|
f,
|
||||||
|
g,
|
||||||
|
h,
|
||||||
|
s0,
|
||||||
|
s1;
|
||||||
|
uint64 T1,
|
||||||
|
T2,
|
||||||
|
*W512 = (uint64 *) context->buffer;
|
||||||
|
int j;
|
||||||
|
|
||||||
/* Initialize registers with the prev. intermediate value */
|
/* Initialize registers with the prev. intermediate value */
|
||||||
a = context->state[0];
|
a = context->state[0];
|
||||||
@ -666,11 +728,12 @@ SHA512_Transform(SHA512_CTX *context, const uint8 *data)
|
|||||||
h = context->state[7];
|
h = context->state[7];
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
do {
|
do
|
||||||
W512[j] = (uint64)data[7] | ((uint64)data[6] << 8) |
|
{
|
||||||
((uint64)data[5] << 16) | ((uint64)data[4] << 24) |
|
W512[j] = (uint64) data[7] | ((uint64) data[6] << 8) |
|
||||||
((uint64)data[3] << 32) | ((uint64)data[2] << 40) |
|
((uint64) data[5] << 16) | ((uint64) data[4] << 24) |
|
||||||
((uint64)data[1] << 48) | ((uint64)data[0] << 56);
|
((uint64) data[3] << 32) | ((uint64) data[2] << 40) |
|
||||||
|
((uint64) data[1] << 48) | ((uint64) data[0] << 56);
|
||||||
data += 8;
|
data += 8;
|
||||||
/* Apply the SHA-512 compression function to update a..h */
|
/* Apply the SHA-512 compression function to update a..h */
|
||||||
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
|
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
|
||||||
@ -687,16 +750,17 @@ SHA512_Transform(SHA512_CTX *context, const uint8 *data)
|
|||||||
j++;
|
j++;
|
||||||
} while (j < 16);
|
} while (j < 16);
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
/* Part of the message block expansion: */
|
/* Part of the message block expansion: */
|
||||||
s0 = W512[(j+1)&0x0f];
|
s0 = W512[(j + 1) & 0x0f];
|
||||||
s0 = sigma0_512(s0);
|
s0 = sigma0_512(s0);
|
||||||
s1 = W512[(j+14)&0x0f];
|
s1 = W512[(j + 14) & 0x0f];
|
||||||
s1 = sigma1_512(s1);
|
s1 = sigma1_512(s1);
|
||||||
|
|
||||||
/* Apply the SHA-512 compression function to update a..h */
|
/* Apply the SHA-512 compression function to update a..h */
|
||||||
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
|
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
|
||||||
(W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
|
(W512[j & 0x0f] += s1 + W512[(j + 9) & 0x0f] + s0);
|
||||||
T2 = Sigma0_512(a) + Maj(a, b, c);
|
T2 = Sigma0_512(a) + Maj(a, b, c);
|
||||||
h = g;
|
h = g;
|
||||||
g = f;
|
g = f;
|
||||||
@ -723,31 +787,35 @@ SHA512_Transform(SHA512_CTX *context, const uint8 *data)
|
|||||||
/* Clean up */
|
/* Clean up */
|
||||||
a = b = c = d = e = f = g = h = T1 = T2 = 0;
|
a = b = c = d = e = f = g = h = T1 = T2 = 0;
|
||||||
}
|
}
|
||||||
|
#endif /* SHA2_UNROLL_TRANSFORM */
|
||||||
#endif /* SHA2_UNROLL_TRANSFORM */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SHA512_Update(SHA512_CTX *context, const uint8 *data, size_t len)
|
SHA512_Update(SHA512_CTX * context, const uint8 *data, size_t len)
|
||||||
{
|
{
|
||||||
size_t freespace, usedspace;
|
size_t freespace,
|
||||||
|
usedspace;
|
||||||
|
|
||||||
/* Calling with no data is valid (we do nothing) */
|
/* Calling with no data is valid (we do nothing) */
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
||||||
if (usedspace > 0) {
|
if (usedspace > 0)
|
||||||
|
{
|
||||||
/* Calculate how much free space is available in the buffer */
|
/* Calculate how much free space is available in the buffer */
|
||||||
freespace = SHA512_BLOCK_LENGTH - usedspace;
|
freespace = SHA512_BLOCK_LENGTH - usedspace;
|
||||||
|
|
||||||
if (len >= freespace) {
|
if (len >= freespace)
|
||||||
|
{
|
||||||
/* Fill the buffer completely and process it */
|
/* Fill the buffer completely and process it */
|
||||||
memcpy(&context->buffer[usedspace], data, freespace);
|
memcpy(&context->buffer[usedspace], data, freespace);
|
||||||
ADDINC128(context->bitcount, freespace << 3);
|
ADDINC128(context->bitcount, freespace << 3);
|
||||||
len -= freespace;
|
len -= freespace;
|
||||||
data += freespace;
|
data += freespace;
|
||||||
SHA512_Transform(context, context->buffer);
|
SHA512_Transform(context, context->buffer);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* The buffer is not yet full */
|
/* The buffer is not yet full */
|
||||||
memcpy(&context->buffer[usedspace], data, len);
|
memcpy(&context->buffer[usedspace], data, len);
|
||||||
ADDINC128(context->bitcount, len << 3);
|
ADDINC128(context->bitcount, len << 3);
|
||||||
@ -756,14 +824,16 @@ SHA512_Update(SHA512_CTX *context, const uint8 *data, size_t len)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (len >= SHA512_BLOCK_LENGTH) {
|
while (len >= SHA512_BLOCK_LENGTH)
|
||||||
|
{
|
||||||
/* Process as many complete blocks as we can */
|
/* Process as many complete blocks as we can */
|
||||||
SHA512_Transform(context, data);
|
SHA512_Transform(context, data);
|
||||||
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
|
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
|
||||||
len -= SHA512_BLOCK_LENGTH;
|
len -= SHA512_BLOCK_LENGTH;
|
||||||
data += SHA512_BLOCK_LENGTH;
|
data += SHA512_BLOCK_LENGTH;
|
||||||
}
|
}
|
||||||
if (len > 0) {
|
if (len > 0)
|
||||||
|
{
|
||||||
/* There's left-overs, so save 'em */
|
/* There's left-overs, so save 'em */
|
||||||
memcpy(context->buffer, data, len);
|
memcpy(context->buffer, data, len);
|
||||||
ADDINC128(context->bitcount, len << 3);
|
ADDINC128(context->bitcount, len << 3);
|
||||||
@ -773,25 +843,30 @@ SHA512_Update(SHA512_CTX *context, const uint8 *data, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SHA512_Last(SHA512_CTX *context)
|
SHA512_Last(SHA512_CTX * context)
|
||||||
{
|
{
|
||||||
unsigned int usedspace;
|
unsigned int usedspace;
|
||||||
|
|
||||||
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
||||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
/* Convert FROM host byte order */
|
/* Convert FROM host byte order */
|
||||||
REVERSE64(context->bitcount[0],context->bitcount[0]);
|
REVERSE64(context->bitcount[0], context->bitcount[0]);
|
||||||
REVERSE64(context->bitcount[1],context->bitcount[1]);
|
REVERSE64(context->bitcount[1], context->bitcount[1]);
|
||||||
#endif
|
#endif
|
||||||
if (usedspace > 0) {
|
if (usedspace > 0)
|
||||||
|
{
|
||||||
/* Begin padding with a 1 bit: */
|
/* Begin padding with a 1 bit: */
|
||||||
context->buffer[usedspace++] = 0x80;
|
context->buffer[usedspace++] = 0x80;
|
||||||
|
|
||||||
if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
|
if (usedspace <= SHA512_SHORT_BLOCK_LENGTH)
|
||||||
|
{
|
||||||
/* Set-up for the last transform: */
|
/* Set-up for the last transform: */
|
||||||
memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace);
|
memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace);
|
||||||
} else {
|
}
|
||||||
if (usedspace < SHA512_BLOCK_LENGTH) {
|
else
|
||||||
|
{
|
||||||
|
if (usedspace < SHA512_BLOCK_LENGTH)
|
||||||
|
{
|
||||||
memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace);
|
memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace);
|
||||||
}
|
}
|
||||||
/* Do second-to-last transform: */
|
/* Do second-to-last transform: */
|
||||||
@ -800,7 +875,9 @@ SHA512_Last(SHA512_CTX *context)
|
|||||||
/* And set-up for the last transform: */
|
/* And set-up for the last transform: */
|
||||||
memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2);
|
memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Prepare for final transform: */
|
/* Prepare for final transform: */
|
||||||
memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH);
|
memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH);
|
||||||
|
|
||||||
@ -808,27 +885,30 @@ SHA512_Last(SHA512_CTX *context)
|
|||||||
*context->buffer = 0x80;
|
*context->buffer = 0x80;
|
||||||
}
|
}
|
||||||
/* Store the length of input data (in bits): */
|
/* Store the length of input data (in bits): */
|
||||||
*(uint64 *)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
|
*(uint64 *) &context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
|
||||||
*(uint64 *)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
|
*(uint64 *) &context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8] = context->bitcount[0];
|
||||||
|
|
||||||
/* Final transform: */
|
/* Final transform: */
|
||||||
SHA512_Transform(context, context->buffer);
|
SHA512_Transform(context, context->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SHA512_Final(uint8 digest[], SHA512_CTX *context)
|
SHA512_Final(uint8 digest[], SHA512_CTX * context)
|
||||||
{
|
{
|
||||||
/* If no digest buffer is passed, we don't bother doing this: */
|
/* If no digest buffer is passed, we don't bother doing this: */
|
||||||
if (digest != NULL) {
|
if (digest != NULL)
|
||||||
|
{
|
||||||
SHA512_Last(context);
|
SHA512_Last(context);
|
||||||
|
|
||||||
/* Save the hash data for output: */
|
/* Save the hash data for output: */
|
||||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
{
|
{
|
||||||
/* Convert TO host byte order */
|
/* Convert TO host byte order */
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 8; j++) {
|
|
||||||
REVERSE64(context->state[j],context->state[j]);
|
for (j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
REVERSE64(context->state[j], context->state[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -842,7 +922,7 @@ SHA512_Final(uint8 digest[], SHA512_CTX *context)
|
|||||||
|
|
||||||
/*** SHA-384: *********************************************************/
|
/*** SHA-384: *********************************************************/
|
||||||
void
|
void
|
||||||
SHA384_Init(SHA384_CTX *context)
|
SHA384_Init(SHA384_CTX * context)
|
||||||
{
|
{
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
return;
|
return;
|
||||||
@ -852,25 +932,28 @@ SHA384_Init(SHA384_CTX *context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SHA384_Update(SHA384_CTX *context, const uint8 *data, size_t len)
|
SHA384_Update(SHA384_CTX * context, const uint8 *data, size_t len)
|
||||||
{
|
{
|
||||||
SHA512_Update((SHA512_CTX *)context, data, len);
|
SHA512_Update((SHA512_CTX *) context, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SHA384_Final(uint8 digest[], SHA384_CTX *context)
|
SHA384_Final(uint8 digest[], SHA384_CTX * context)
|
||||||
{
|
{
|
||||||
/* If no digest buffer is passed, we don't bother doing this: */
|
/* If no digest buffer is passed, we don't bother doing this: */
|
||||||
if (digest != NULL) {
|
if (digest != NULL)
|
||||||
SHA512_Last((SHA512_CTX *)context);
|
{
|
||||||
|
SHA512_Last((SHA512_CTX *) context);
|
||||||
|
|
||||||
/* Save the hash data for output: */
|
/* Save the hash data for output: */
|
||||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
{
|
{
|
||||||
/* Convert TO host byte order */
|
/* Convert TO host byte order */
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 6; j++) {
|
|
||||||
REVERSE64(context->state[j],context->state[j]);
|
for (j = 0; j < 6; j++)
|
||||||
|
{
|
||||||
|
REVERSE64(context->state[j], context->state[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $PostgreSQL: pgsql/contrib/pgcrypto/sha2.h,v 1.1 2005/07/10 13:46:29 momjian Exp $ */
|
/* $PostgreSQL: pgsql/contrib/pgcrypto/sha2.h,v 1.2 2005/10/15 02:49:06 momjian Exp $ */
|
||||||
/* $OpenBSD: sha2.h,v 1.2 2004/04/28 23:11:57 millert Exp $ */
|
/* $OpenBSD: sha2.h,v 1.2 2004/04/28 23:11:57 millert Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -12,18 +12,18 @@
|
|||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. Neither the name of the copyright holder nor the names of contributors
|
* 3. Neither the name of the copyright holder nor the names of contributors
|
||||||
* may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
@ -42,39 +42,41 @@
|
|||||||
/*** SHA-256/384/512 Various Length Definitions ***********************/
|
/*** SHA-256/384/512 Various Length Definitions ***********************/
|
||||||
#define SHA256_BLOCK_LENGTH 64
|
#define SHA256_BLOCK_LENGTH 64
|
||||||
#define SHA256_DIGEST_LENGTH 32
|
#define SHA256_DIGEST_LENGTH 32
|
||||||
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
|
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
|
||||||
#define SHA384_BLOCK_LENGTH 128
|
#define SHA384_BLOCK_LENGTH 128
|
||||||
#define SHA384_DIGEST_LENGTH 48
|
#define SHA384_DIGEST_LENGTH 48
|
||||||
#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
|
#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
|
||||||
#define SHA512_BLOCK_LENGTH 128
|
#define SHA512_BLOCK_LENGTH 128
|
||||||
#define SHA512_DIGEST_LENGTH 64
|
#define SHA512_DIGEST_LENGTH 64
|
||||||
#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
|
#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
|
||||||
|
|
||||||
|
|
||||||
/*** SHA-256/384/512 Context Structures *******************************/
|
/*** SHA-256/384/512 Context Structures *******************************/
|
||||||
typedef struct _SHA256_CTX {
|
typedef struct _SHA256_CTX
|
||||||
uint32 state[8];
|
{
|
||||||
uint64 bitcount;
|
uint32 state[8];
|
||||||
uint8 buffer[SHA256_BLOCK_LENGTH];
|
uint64 bitcount;
|
||||||
} SHA256_CTX;
|
uint8 buffer[SHA256_BLOCK_LENGTH];
|
||||||
typedef struct _SHA512_CTX {
|
} SHA256_CTX;
|
||||||
uint64 state[8];
|
typedef struct _SHA512_CTX
|
||||||
uint64 bitcount[2];
|
{
|
||||||
uint8 buffer[SHA512_BLOCK_LENGTH];
|
uint64 state[8];
|
||||||
} SHA512_CTX;
|
uint64 bitcount[2];
|
||||||
|
uint8 buffer[SHA512_BLOCK_LENGTH];
|
||||||
|
} SHA512_CTX;
|
||||||
|
|
||||||
typedef SHA512_CTX SHA384_CTX;
|
typedef SHA512_CTX SHA384_CTX;
|
||||||
|
|
||||||
void SHA256_Init(SHA256_CTX *);
|
void SHA256_Init(SHA256_CTX *);
|
||||||
void SHA256_Update(SHA256_CTX *, const uint8 *, size_t);
|
void SHA256_Update(SHA256_CTX *, const uint8 *, size_t);
|
||||||
void SHA256_Final(uint8[SHA256_DIGEST_LENGTH], SHA256_CTX *);
|
void SHA256_Final(uint8[SHA256_DIGEST_LENGTH], SHA256_CTX *);
|
||||||
|
|
||||||
void SHA384_Init(SHA384_CTX *);
|
void SHA384_Init(SHA384_CTX *);
|
||||||
void SHA384_Update(SHA384_CTX *, const uint8 *, size_t);
|
void SHA384_Update(SHA384_CTX *, const uint8 *, size_t);
|
||||||
void SHA384_Final(uint8[SHA384_DIGEST_LENGTH], SHA384_CTX *);
|
void SHA384_Final(uint8[SHA384_DIGEST_LENGTH], SHA384_CTX *);
|
||||||
|
|
||||||
void SHA512_Init(SHA512_CTX *);
|
void SHA512_Init(SHA512_CTX *);
|
||||||
void SHA512_Update(SHA512_CTX *, const uint8 *, size_t);
|
void SHA512_Update(SHA512_CTX *, const uint8 *, size_t);
|
||||||
void SHA512_Final(uint8[SHA512_DIGEST_LENGTH], SHA512_CTX *);
|
void SHA512_Final(uint8[SHA512_DIGEST_LENGTH], SHA512_CTX *);
|
||||||
|
|
||||||
#endif /* _SHA2_H */
|
#endif /* _SHA2_H */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.19 2005/05/30 23:09:06 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.20 2005/10/15 02:49:06 momjian Exp $
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001,2002 Tatsuo Ishii
|
* Copyright (c) 2001,2002 Tatsuo Ishii
|
||||||
*
|
*
|
||||||
@ -123,8 +123,8 @@ pgstattuple_real(Relation rel, FunctionCallInfo fcinfo)
|
|||||||
tupdesc = CreateTupleDescCopy(tupdesc);
|
tupdesc = CreateTupleDescCopy(tupdesc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate attribute metadata needed later to produce tuples from raw
|
* Generate attribute metadata needed later to produce tuples from raw C
|
||||||
* C strings
|
* strings
|
||||||
*/
|
*/
|
||||||
attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
||||||
|
|
||||||
@ -197,9 +197,9 @@ pgstattuple_real(Relation rel, FunctionCallInfo fcinfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare a values array for constructing the tuple. This should be
|
* Prepare a values array for constructing the tuple. This should be an
|
||||||
* an array of C strings which will be processed later by the
|
* array of C strings which will be processed later by the appropriate
|
||||||
* appropriate "in" functions.
|
* "in" functions.
|
||||||
*/
|
*/
|
||||||
values = (char **) palloc(NCOLUMNS * sizeof(char *));
|
values = (char **) palloc(NCOLUMNS * sizeof(char *));
|
||||||
for (i = 0; i < NCOLUMNS; i++)
|
for (i = 0; i < NCOLUMNS; i++)
|
||||||
|
@ -124,8 +124,7 @@ seg_out(SEG * seg)
|
|||||||
if (seg->lower == seg->upper && seg->l_ext == seg->u_ext)
|
if (seg->lower == seg->upper && seg->l_ext == seg->u_ext)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* indicates that this interval was built by seg_in off a single
|
* indicates that this interval was built by seg_in off a single point
|
||||||
* point
|
|
||||||
*/
|
*/
|
||||||
p += restore(p, seg->lower, seg->l_sigd);
|
p += restore(p, seg->lower, seg->l_sigd);
|
||||||
}
|
}
|
||||||
@ -349,8 +348,7 @@ gseg_picksplit(GistEntryVector *entryvec,
|
|||||||
size_waste = size_union - size_inter;
|
size_waste = size_union - size_inter;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* are these a more promising split that what we've already
|
* are these a more promising split that what we've already seen?
|
||||||
* seen?
|
|
||||||
*/
|
*/
|
||||||
if (size_waste > waste || firsttime)
|
if (size_waste > waste || firsttime)
|
||||||
{
|
{
|
||||||
@ -375,24 +373,24 @@ gseg_picksplit(GistEntryVector *entryvec,
|
|||||||
rt_seg_size(datum_r, &size_r);
|
rt_seg_size(datum_r, &size_r);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now split up the regions between the two seeds. An important
|
* Now split up the regions between the two seeds. An important property
|
||||||
* property of this split algorithm is that the split vector v has the
|
* of this split algorithm is that the split vector v has the indices of
|
||||||
* indices of items to be split in order in its left and right
|
* items to be split in order in its left and right vectors. We exploit
|
||||||
* vectors. We exploit this property by doing a merge in the code
|
* this property by doing a merge in the code that actually splits the
|
||||||
* that actually splits the page.
|
* page.
|
||||||
*
|
*
|
||||||
* For efficiency, we also place the new index tuple in this loop. This
|
* For efficiency, we also place the new index tuple in this loop. This is
|
||||||
* is handled at the very end, when we have placed all the existing
|
* handled at the very end, when we have placed all the existing tuples
|
||||||
* tuples and i == maxoff + 1.
|
* and i == maxoff + 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
maxoff = OffsetNumberNext(maxoff);
|
maxoff = OffsetNumberNext(maxoff);
|
||||||
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
|
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If we've already decided where to place this item, just put it
|
* If we've already decided where to place this item, just put it on
|
||||||
* on the right list. Otherwise, we need to figure out which page
|
* the right list. Otherwise, we need to figure out which page needs
|
||||||
* needs the least enlargement in order to store the item.
|
* the least enlargement in order to store the item.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (i == seed_1)
|
if (i == seed_1)
|
||||||
@ -742,8 +740,8 @@ seg_cmp(SEG * a, SEG * b)
|
|||||||
* a->lower == b->lower, so consider type of boundary.
|
* a->lower == b->lower, so consider type of boundary.
|
||||||
*
|
*
|
||||||
* A '-' lower bound is < any other kind (this could only be relevant if
|
* A '-' lower bound is < any other kind (this could only be relevant if
|
||||||
* -HUGE_VAL is used as a regular data value). A '<' lower bound is <
|
* -HUGE_VAL is used as a regular data value). A '<' lower bound is < any
|
||||||
* any other kind except '-'. A '>' lower bound is > any other kind.
|
* other kind except '-'. A '>' lower bound is > any other kind.
|
||||||
*/
|
*/
|
||||||
if (a->l_ext != b->l_ext)
|
if (a->l_ext != b->l_ext)
|
||||||
{
|
{
|
||||||
@ -764,8 +762,7 @@ seg_cmp(SEG * a, SEG * b)
|
|||||||
/*
|
/*
|
||||||
* For other boundary types, consider # of significant digits first.
|
* For other boundary types, consider # of significant digits first.
|
||||||
*/
|
*/
|
||||||
if (a->l_sigd < b->l_sigd) /* (a) is blurred and is likely to include
|
if (a->l_sigd < b->l_sigd) /* (a) is blurred and is likely to include (b) */
|
||||||
* (b) */
|
|
||||||
return -1;
|
return -1;
|
||||||
if (a->l_sigd > b->l_sigd) /* (a) is less blurred and is likely to be
|
if (a->l_sigd > b->l_sigd) /* (a) is less blurred and is likely to be
|
||||||
* included in (b) */
|
* included in (b) */
|
||||||
@ -800,8 +797,8 @@ seg_cmp(SEG * a, SEG * b)
|
|||||||
* a->upper == b->upper, so consider type of boundary.
|
* a->upper == b->upper, so consider type of boundary.
|
||||||
*
|
*
|
||||||
* A '-' upper bound is > any other kind (this could only be relevant if
|
* A '-' upper bound is > any other kind (this could only be relevant if
|
||||||
* HUGE_VAL is used as a regular data value). A '<' upper bound is <
|
* HUGE_VAL is used as a regular data value). A '<' upper bound is < any
|
||||||
* any other kind. A '>' upper bound is > any other kind except '-'.
|
* other kind. A '>' upper bound is > any other kind except '-'.
|
||||||
*/
|
*/
|
||||||
if (a->u_ext != b->u_ext)
|
if (a->u_ext != b->u_ext)
|
||||||
{
|
{
|
||||||
@ -820,11 +817,10 @@ seg_cmp(SEG * a, SEG * b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For other boundary types, consider # of significant digits first.
|
* For other boundary types, consider # of significant digits first. Note
|
||||||
* Note result here is converse of the lower-boundary case.
|
* result here is converse of the lower-boundary case.
|
||||||
*/
|
*/
|
||||||
if (a->u_sigd < b->u_sigd) /* (a) is blurred and is likely to include
|
if (a->u_sigd < b->u_sigd) /* (a) is blurred and is likely to include (b) */
|
||||||
* (b) */
|
|
||||||
return 1;
|
return 1;
|
||||||
if (a->u_sigd > b->u_sigd) /* (a) is less blurred and is likely to be
|
if (a->u_sigd > b->u_sigd) /* (a) is less blurred and is likely to be
|
||||||
* included in (b) */
|
* included in (b) */
|
||||||
@ -908,17 +904,17 @@ restore(char *result, float val, int n)
|
|||||||
sign;
|
sign;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* put a cap on the number of siugnificant digits to avoid nonsense in
|
* put a cap on the number of siugnificant digits to avoid nonsense in the
|
||||||
* the output
|
* output
|
||||||
*/
|
*/
|
||||||
n = Min(n, FLT_DIG);
|
n = Min(n, FLT_DIG);
|
||||||
|
|
||||||
/* remember the sign */
|
/* remember the sign */
|
||||||
sign = (val < 0 ? 1 : 0);
|
sign = (val < 0 ? 1 : 0);
|
||||||
|
|
||||||
efmt[5] = '0' + (n - 1) % 10; /* makes %-15.(n-1)e -- this
|
efmt[5] = '0' + (n - 1) % 10; /* makes %-15.(n-1)e -- this format
|
||||||
* format guarantees that the
|
* guarantees that the exponent is
|
||||||
* exponent is always present */
|
* always present */
|
||||||
|
|
||||||
sprintf(result, efmt, val);
|
sprintf(result, efmt, val);
|
||||||
|
|
||||||
@ -940,8 +936,8 @@ restore(char *result, float val, int n)
|
|||||||
if (Abs(exp) <= 4)
|
if (Abs(exp) <= 4)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* remove the decimal point from the mantyssa and write the
|
* remove the decimal point from the mantyssa and write the digits
|
||||||
* digits to the buf array
|
* to the buf array
|
||||||
*/
|
*/
|
||||||
for (p = result + sign, i = 10, dp = 0; *p != 'e'; p++, i++)
|
for (p = result + sign, i = 10, dp = 0; *p != 'e'; p++, i++)
|
||||||
{
|
{
|
||||||
@ -960,10 +956,9 @@ restore(char *result, float val, int n)
|
|||||||
if (dp - 10 + exp >= n)
|
if (dp - 10 + exp >= n)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* the decimal point is behind the last significant
|
* the decimal point is behind the last significant digit;
|
||||||
* digit; the digits in between must be converted to
|
* the digits in between must be converted to the exponent
|
||||||
* the exponent and the decimal point placed after the
|
* and the decimal point placed after the first digit
|
||||||
* first digit
|
|
||||||
*/
|
*/
|
||||||
exp = dp - 10 + exp - n;
|
exp = dp - 10 + exp - n;
|
||||||
buf[10 + n] = '\0';
|
buf[10 + n] = '\0';
|
||||||
@ -978,8 +973,8 @@ restore(char *result, float val, int n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* adjust the exponent by the number of digits after
|
* adjust the exponent by the number of digits after the
|
||||||
* the decimal point
|
* decimal point
|
||||||
*/
|
*/
|
||||||
if (n > 1)
|
if (n > 1)
|
||||||
sprintf(&buf[11 + n], "e%d", exp + n - 1);
|
sprintf(&buf[11 + n], "e%d", exp + n - 1);
|
||||||
|
@ -73,8 +73,8 @@ autoinc(PG_FUNCTION_ARGS)
|
|||||||
if (SPI_gettypeid(tupdesc, attnum) != INT4OID)
|
if (SPI_gettypeid(tupdesc, attnum) != INT4OID)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||||
errmsg("attribute \"%s\" of \"%s\" must be type INT4",
|
errmsg("attribute \"%s\" of \"%s\" must be type INT4",
|
||||||
args[i], relname)));
|
args[i], relname)));
|
||||||
|
|
||||||
val = DatumGetInt32(SPI_getbinval(rettuple, tupdesc, attnum, &isnull));
|
val = DatumGetInt32(SPI_getbinval(rettuple, tupdesc, attnum, &isnull));
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ insert_username(PG_FUNCTION_ARGS)
|
|||||||
if (attnum < 0)
|
if (attnum < 0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||||
errmsg("\"%s\" has no attribute \"%s\"", relname, args[0])));
|
errmsg("\"%s\" has no attribute \"%s\"", relname, args[0])));
|
||||||
|
|
||||||
if (SPI_gettypeid(tupdesc, attnum) != TEXTOID)
|
if (SPI_gettypeid(tupdesc, attnum) != TEXTOID)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -75,7 +75,7 @@ insert_username(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
/* create fields containing name */
|
/* create fields containing name */
|
||||||
newval = DirectFunctionCall1(textin,
|
newval = DirectFunctionCall1(textin,
|
||||||
CStringGetDatum(GetUserNameFromId(GetUserId())));
|
CStringGetDatum(GetUserNameFromId(GetUserId())));
|
||||||
|
|
||||||
/* construct new tuple */
|
/* construct new tuple */
|
||||||
rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newval, NULL);
|
rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newval, NULL);
|
||||||
|
@ -76,9 +76,8 @@ moddatetime(PG_FUNCTION_ARGS)
|
|||||||
Int32GetDatum(-1));
|
Int32GetDatum(-1));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This gets the position in the tuple of the field we want. args[0]
|
* This gets the position in the tuple of the field we want. args[0] being
|
||||||
* being the name of the field to update, as passed in from the
|
* the name of the field to update, as passed in from the trigger.
|
||||||
* trigger.
|
|
||||||
*/
|
*/
|
||||||
attnum = SPI_fnumber(tupdesc, args[0]);
|
attnum = SPI_fnumber(tupdesc, args[0]);
|
||||||
|
|
||||||
@ -100,8 +99,8 @@ moddatetime(PG_FUNCTION_ARGS)
|
|||||||
if (SPI_gettypeid(tupdesc, attnum) != TIMESTAMPOID)
|
if (SPI_gettypeid(tupdesc, attnum) != TIMESTAMPOID)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||||
errmsg("attribute \"%s\" of \"%s\" must be type TIMESTAMP",
|
errmsg("attribute \"%s\" of \"%s\" must be type TIMESTAMP",
|
||||||
args[0], relname)));
|
args[0], relname)));
|
||||||
|
|
||||||
/* 1 is the number of items in the arrays attnum and newdt.
|
/* 1 is the number of items in the arrays attnum and newdt.
|
||||||
attnum is the positional number of the field to be updated.
|
attnum is the positional number of the field to be updated.
|
||||||
|
@ -114,8 +114,8 @@ check_primary_key(PG_FUNCTION_ARGS)
|
|||||||
kvals = (Datum *) palloc(nkeys * sizeof(Datum));
|
kvals = (Datum *) palloc(nkeys * sizeof(Datum));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct ident string as TriggerName $ TriggeredRelationId and try
|
* Construct ident string as TriggerName $ TriggeredRelationId and try to
|
||||||
* to find prepared execution plan.
|
* find prepared execution plan.
|
||||||
*/
|
*/
|
||||||
snprintf(ident, sizeof(ident), "%s$%u", trigger->tgname, rel->rd_id);
|
snprintf(ident, sizeof(ident), "%s$%u", trigger->tgname, rel->rd_id);
|
||||||
plan = find_plan(ident, &PPlans, &nPPlans);
|
plan = find_plan(ident, &PPlans, &nPPlans);
|
||||||
@ -134,16 +134,16 @@ check_primary_key(PG_FUNCTION_ARGS)
|
|||||||
if (fnumber < 0)
|
if (fnumber < 0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||||
errmsg("there is no attribute \"%s\" in relation \"%s\"",
|
errmsg("there is no attribute \"%s\" in relation \"%s\"",
|
||||||
args[i], SPI_getrelname(rel))));
|
args[i], SPI_getrelname(rel))));
|
||||||
|
|
||||||
/* Well, get binary (in internal format) value of column */
|
/* Well, get binary (in internal format) value of column */
|
||||||
kvals[i] = SPI_getbinval(tuple, tupdesc, fnumber, &isnull);
|
kvals[i] = SPI_getbinval(tuple, tupdesc, fnumber, &isnull);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If it's NULL then nothing to do! DON'T FORGET call SPI_finish
|
* If it's NULL then nothing to do! DON'T FORGET call SPI_finish ()!
|
||||||
* ()! DON'T FORGET return tuple! Executor inserts tuple you're
|
* DON'T FORGET return tuple! Executor inserts tuple you're returning!
|
||||||
* returning! If you return NULL then nothing will be inserted!
|
* If you return NULL then nothing will be inserted!
|
||||||
*/
|
*/
|
||||||
if (isnull)
|
if (isnull)
|
||||||
{
|
{
|
||||||
@ -164,14 +164,14 @@ check_primary_key(PG_FUNCTION_ARGS)
|
|||||||
char sql[8192];
|
char sql[8192];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct query: SELECT 1 FROM _referenced_relation_ WHERE
|
* Construct query: SELECT 1 FROM _referenced_relation_ WHERE Pkey1 =
|
||||||
* Pkey1 = $1 [AND Pkey2 = $2 [...]]
|
* $1 [AND Pkey2 = $2 [...]]
|
||||||
*/
|
*/
|
||||||
snprintf(sql, sizeof(sql), "select 1 from %s where ", relname);
|
snprintf(sql, sizeof(sql), "select 1 from %s where ", relname);
|
||||||
for (i = 0; i < nkeys; i++)
|
for (i = 0; i < nkeys; i++)
|
||||||
{
|
{
|
||||||
snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s = $%d %s",
|
snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s = $%d %s",
|
||||||
args[i + nkeys + 1], i + 1, (i < nkeys - 1) ? "and " : "");
|
args[i + nkeys + 1], i + 1, (i < nkeys - 1) ? "and " : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare plan for query */
|
/* Prepare plan for query */
|
||||||
@ -181,9 +181,8 @@ check_primary_key(PG_FUNCTION_ARGS)
|
|||||||
elog(ERROR, "check_primary_key: SPI_prepare returned %d", SPI_result);
|
elog(ERROR, "check_primary_key: SPI_prepare returned %d", SPI_result);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remember that SPI_prepare places plan in current memory context
|
* Remember that SPI_prepare places plan in current memory context -
|
||||||
* - so, we have to save plan in Top memory context for latter
|
* so, we have to save plan in Top memory context for latter use.
|
||||||
* use.
|
|
||||||
*/
|
*/
|
||||||
pplan = SPI_saveplan(pplan);
|
pplan = SPI_saveplan(pplan);
|
||||||
if (pplan == NULL)
|
if (pplan == NULL)
|
||||||
@ -252,8 +251,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
|||||||
EPlan *plan; /* prepared plan(s) */
|
EPlan *plan; /* prepared plan(s) */
|
||||||
Oid *argtypes = NULL; /* key types to prepare execution plan */
|
Oid *argtypes = NULL; /* key types to prepare execution plan */
|
||||||
bool isnull; /* to know is some column NULL or not */
|
bool isnull; /* to know is some column NULL or not */
|
||||||
bool isequal = true; /* are keys in both tuples equal (in
|
bool isequal = true; /* are keys in both tuples equal (in UPDATE) */
|
||||||
* UPDATE) */
|
|
||||||
char ident[2 * NAMEDATALEN]; /* to identify myself */
|
char ident[2 * NAMEDATALEN]; /* to identify myself */
|
||||||
int is_update = 0;
|
int is_update = 0;
|
||||||
int ret;
|
int ret;
|
||||||
@ -287,9 +285,8 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
|||||||
trigtuple = trigdata->tg_trigtuple;
|
trigtuple = trigdata->tg_trigtuple;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* But if this is UPDATE then we have to return tg_newtuple. Also, if
|
* But if this is UPDATE then we have to return tg_newtuple. Also, if key
|
||||||
* key in tg_newtuple is the same as in tg_trigtuple then nothing to
|
* in tg_newtuple is the same as in tg_trigtuple then nothing to do.
|
||||||
* do.
|
|
||||||
*/
|
*/
|
||||||
is_update = 0;
|
is_update = 0;
|
||||||
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
|
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
|
||||||
@ -337,8 +334,8 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
|||||||
kvals = (Datum *) palloc(nkeys * sizeof(Datum));
|
kvals = (Datum *) palloc(nkeys * sizeof(Datum));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct ident string as TriggerName $ TriggeredRelationId and try
|
* Construct ident string as TriggerName $ TriggeredRelationId and try to
|
||||||
* to find prepared execution plan(s).
|
* find prepared execution plan(s).
|
||||||
*/
|
*/
|
||||||
snprintf(ident, sizeof(ident), "%s$%u", trigger->tgname, rel->rd_id);
|
snprintf(ident, sizeof(ident), "%s$%u", trigger->tgname, rel->rd_id);
|
||||||
plan = find_plan(ident, &FPlans, &nFPlans);
|
plan = find_plan(ident, &FPlans, &nFPlans);
|
||||||
@ -365,16 +362,16 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
|||||||
if (fnumber < 0)
|
if (fnumber < 0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||||
errmsg("there is no attribute \"%s\" in relation \"%s\"",
|
errmsg("there is no attribute \"%s\" in relation \"%s\"",
|
||||||
args[i], SPI_getrelname(rel))));
|
args[i], SPI_getrelname(rel))));
|
||||||
|
|
||||||
/* Well, get binary (in internal format) value of column */
|
/* Well, get binary (in internal format) value of column */
|
||||||
kvals[i] = SPI_getbinval(trigtuple, tupdesc, fnumber, &isnull);
|
kvals[i] = SPI_getbinval(trigtuple, tupdesc, fnumber, &isnull);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If it's NULL then nothing to do! DON'T FORGET call SPI_finish
|
* If it's NULL then nothing to do! DON'T FORGET call SPI_finish ()!
|
||||||
* ()! DON'T FORGET return tuple! Executor inserts tuple you're
|
* DON'T FORGET return tuple! Executor inserts tuple you're returning!
|
||||||
* returning! If you return NULL then nothing will be inserted!
|
* If you return NULL then nothing will be inserted!
|
||||||
*/
|
*/
|
||||||
if (isnull)
|
if (isnull)
|
||||||
{
|
{
|
||||||
@ -383,9 +380,9 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If UPDATE then get column value from new tuple being inserted
|
* If UPDATE then get column value from new tuple being inserted and
|
||||||
* and compare is this the same as old one. For the moment we use
|
* compare is this the same as old one. For the moment we use string
|
||||||
* string presentation of values...
|
* presentation of values...
|
||||||
*/
|
*/
|
||||||
if (newtuple != NULL)
|
if (newtuple != NULL)
|
||||||
{
|
{
|
||||||
@ -473,7 +470,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
|||||||
type = SPI_gettype(tupdesc, fn);
|
type = SPI_gettype(tupdesc, fn);
|
||||||
|
|
||||||
if ((strcmp(type, "text") && strcmp(type, "varchar") &&
|
if ((strcmp(type, "text") && strcmp(type, "varchar") &&
|
||||||
strcmp(type, "char") && strcmp(type, "bpchar") &&
|
strcmp(type, "char") && strcmp(type, "bpchar") &&
|
||||||
strcmp(type, "date") && strcmp(type, "timestamp")) == 0)
|
strcmp(type, "date") && strcmp(type, "timestamp")) == 0)
|
||||||
is_char_type = 1;
|
is_char_type = 1;
|
||||||
#ifdef DEBUG_QUERY
|
#ifdef DEBUG_QUERY
|
||||||
@ -482,8 +479,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* is_char_type =1 i set ' ' for define a new
|
* is_char_type =1 i set ' ' for define a new value
|
||||||
* value
|
|
||||||
*/
|
*/
|
||||||
snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql),
|
snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql),
|
||||||
" %s = %s%s%s %s ",
|
" %s = %s%s%s %s ",
|
||||||
@ -503,8 +499,8 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* For 'S'etnull action we construct UPDATE query - UPDATE
|
* For 'S'etnull action we construct UPDATE query - UPDATE
|
||||||
* _referencing_relation_ SET Fkey1 null [, Fkey2 null [...]]
|
* _referencing_relation_ SET Fkey1 null [, Fkey2 null [...]]
|
||||||
* WHERE Fkey1 = $1 [AND Fkey2 = $2 [...]] - to set key
|
* WHERE Fkey1 = $1 [AND Fkey2 = $2 [...]] - to set key columns in
|
||||||
* columns in all referencing tuples to NULL.
|
* all referencing tuples to NULL.
|
||||||
*/
|
*/
|
||||||
else if (action == 's')
|
else if (action == 's')
|
||||||
{
|
{
|
||||||
@ -532,9 +528,9 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
|||||||
elog(ERROR, "check_foreign_key: SPI_prepare returned %d", SPI_result);
|
elog(ERROR, "check_foreign_key: SPI_prepare returned %d", SPI_result);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remember that SPI_prepare places plan in current memory
|
* Remember that SPI_prepare places plan in current memory context
|
||||||
* context - so, we have to save plan in Top memory context
|
* - so, we have to save plan in Top memory context for latter
|
||||||
* for latter use.
|
* use.
|
||||||
*/
|
*/
|
||||||
pplan = SPI_saveplan(pplan);
|
pplan = SPI_saveplan(pplan);
|
||||||
if (pplan == NULL)
|
if (pplan == NULL)
|
||||||
@ -566,8 +562,8 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
|||||||
for (r = 0; r < nrefs; r++)
|
for (r = 0; r < nrefs; r++)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* For 'R'estrict we may to execute plan for one tuple only, for
|
* For 'R'estrict we may to execute plan for one tuple only, for other
|
||||||
* other actions - for all tuples.
|
* actions - for all tuples.
|
||||||
*/
|
*/
|
||||||
int tcount = (action == 'r') ? 1 : 0;
|
int tcount = (action == 'r') ? 1 : 0;
|
||||||
|
|
||||||
|
@ -245,8 +245,8 @@ timetravel(PG_FUNCTION_ARGS)
|
|||||||
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[a_time_off]);
|
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[a_time_off]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If DELETE/UPDATE of tuple with stop_date neq INFINITY then say
|
* If DELETE/UPDATE of tuple with stop_date neq INFINITY then say upper
|
||||||
* upper Executor to skip operation for this tuple
|
* Executor to skip operation for this tuple
|
||||||
*/
|
*/
|
||||||
if (newtuple != NULL)
|
if (newtuple != NULL)
|
||||||
{ /* UPDATE */
|
{ /* UPDATE */
|
||||||
@ -263,8 +263,7 @@ timetravel(PG_FUNCTION_ARGS)
|
|||||||
relname, args[a_time_on], args[a_time_off]);
|
relname, args[a_time_on], args[a_time_off]);
|
||||||
}
|
}
|
||||||
if (oldtimeoff != NOEND_ABSTIME)
|
if (oldtimeoff != NOEND_ABSTIME)
|
||||||
{ /* current record is a deleted/updated
|
{ /* current record is a deleted/updated record */
|
||||||
* record */
|
|
||||||
pfree(relname);
|
pfree(relname);
|
||||||
return PointerGetDatum(NULL);
|
return PointerGetDatum(NULL);
|
||||||
}
|
}
|
||||||
@ -285,8 +284,7 @@ timetravel(PG_FUNCTION_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* change date column(s) */
|
/* change date column(s) */
|
||||||
cvals[attnum[a_time_off] - 1] = newtimeoff; /* stop_date eq current
|
cvals[attnum[a_time_off] - 1] = newtimeoff; /* stop_date eq current date */
|
||||||
* date */
|
|
||||||
cnulls[attnum[a_time_off] - 1] = ' ';
|
cnulls[attnum[a_time_off] - 1] = ' ';
|
||||||
|
|
||||||
if (!newtuple)
|
if (!newtuple)
|
||||||
@ -299,8 +297,8 @@ timetravel(PG_FUNCTION_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct ident string as TriggerName $ TriggeredRelationId and try
|
* Construct ident string as TriggerName $ TriggeredRelationId and try to
|
||||||
* to find prepared execution plan.
|
* find prepared execution plan.
|
||||||
*/
|
*/
|
||||||
snprintf(ident, sizeof(ident), "%s$%u", trigger->tgname, rel->rd_id);
|
snprintf(ident, sizeof(ident), "%s$%u", trigger->tgname, rel->rd_id);
|
||||||
plan = find_plan(ident, &Plans, &nPlans);
|
plan = find_plan(ident, &Plans, &nPlans);
|
||||||
@ -339,9 +337,8 @@ timetravel(PG_FUNCTION_ARGS)
|
|||||||
elog(ERROR, "timetravel (%s): SPI_prepare returned %d", relname, SPI_result);
|
elog(ERROR, "timetravel (%s): SPI_prepare returned %d", relname, SPI_result);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remember that SPI_prepare places plan in current memory context
|
* Remember that SPI_prepare places plan in current memory context -
|
||||||
* - so, we have to save plan in Top memory context for latter
|
* so, we have to save plan in Top memory context for latter use.
|
||||||
* use.
|
|
||||||
*/
|
*/
|
||||||
pplan = SPI_saveplan(pplan);
|
pplan = SPI_saveplan(pplan);
|
||||||
if (pplan == NULL)
|
if (pplan == NULL)
|
||||||
@ -398,8 +395,8 @@ timetravel(PG_FUNCTION_ARGS)
|
|||||||
rettuple = SPI_modifytuple(rel, newtuple, chnattrs, chattrs, newvals, newnulls);
|
rettuple = SPI_modifytuple(rel, newtuple, chnattrs, chattrs, newvals, newnulls);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SPI_copytuple allocates tmptuple in upper executor context -
|
* SPI_copytuple allocates tmptuple in upper executor context - have
|
||||||
* have to free allocation using SPI_pfree
|
* to free allocation using SPI_pfree
|
||||||
*/
|
*/
|
||||||
/* SPI_pfree(tmptuple); */
|
/* SPI_pfree(tmptuple); */
|
||||||
}
|
}
|
||||||
|
@ -184,8 +184,7 @@ normal_rand(PG_FUNCTION_ARGS)
|
|||||||
funcctx = SRF_FIRSTCALL_INIT();
|
funcctx = SRF_FIRSTCALL_INIT();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* switch to memory context appropriate for multiple function
|
* switch to memory context appropriate for multiple function calls
|
||||||
* calls
|
|
||||||
*/
|
*/
|
||||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||||
|
|
||||||
@ -196,10 +195,10 @@ normal_rand(PG_FUNCTION_ARGS)
|
|||||||
fctx = (normal_rand_fctx *) palloc(sizeof(normal_rand_fctx));
|
fctx = (normal_rand_fctx *) palloc(sizeof(normal_rand_fctx));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use fctx to keep track of upper and lower bounds from call to
|
* Use fctx to keep track of upper and lower bounds from call to call.
|
||||||
* call. It will also be used to carry over the spare value we get
|
* It will also be used to carry over the spare value we get from the
|
||||||
* from the Box-Muller algorithm so that we only actually
|
* Box-Muller algorithm so that we only actually calculate a new value
|
||||||
* calculate a new value every other call.
|
* every other call.
|
||||||
*/
|
*/
|
||||||
fctx->mean = PG_GETARG_FLOAT8(1);
|
fctx->mean = PG_GETARG_FLOAT8(1);
|
||||||
fctx->stddev = PG_GETARG_FLOAT8(2);
|
fctx->stddev = PG_GETARG_FLOAT8(2);
|
||||||
@ -254,7 +253,7 @@ normal_rand(PG_FUNCTION_ARGS)
|
|||||||
SRF_RETURN_NEXT(funcctx, Float8GetDatum(result));
|
SRF_RETURN_NEXT(funcctx, Float8GetDatum(result));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* do when there is no more left */
|
/* do when there is no more left */
|
||||||
SRF_RETURN_DONE(funcctx);
|
SRF_RETURN_DONE(funcctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,8 +330,8 @@ get_normal_pair(float8 *x1, float8 *x2)
|
|||||||
* 1. SQL result must be ordered by 1,2.
|
* 1. SQL result must be ordered by 1,2.
|
||||||
* 2. The number of values columns depends on the tuple description
|
* 2. The number of values columns depends on the tuple description
|
||||||
* of the function's declared return type. The return type's columns
|
* of the function's declared return type. The return type's columns
|
||||||
* must match the datatypes of the SQL query's result. The datatype
|
* must match the datatypes of the SQL query's result. The datatype
|
||||||
* of the category column can be anything, however.
|
* of the category column can be anything, however.
|
||||||
* 3. Missing values (i.e. not enough adjacent rows of same rowid to
|
* 3. Missing values (i.e. not enough adjacent rows of same rowid to
|
||||||
* fill the number of result values columns) are filled in with nulls.
|
* fill the number of result values columns) are filled in with nulls.
|
||||||
* 4. Extra values (i.e. too many adjacent rows of same rowid to fill
|
* 4. Extra values (i.e. too many adjacent rows of same rowid to fill
|
||||||
@ -368,8 +367,7 @@ crosstab(PG_FUNCTION_ARGS)
|
|||||||
funcctx = SRF_FIRSTCALL_INIT();
|
funcctx = SRF_FIRSTCALL_INIT();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* switch to memory context appropriate for multiple function
|
* switch to memory context appropriate for multiple function calls
|
||||||
* calls
|
|
||||||
*/
|
*/
|
||||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||||
|
|
||||||
@ -394,7 +392,7 @@ crosstab(PG_FUNCTION_ARGS)
|
|||||||
* 1. rowname
|
* 1. rowname
|
||||||
* the label or identifier for each row in the final result
|
* the label or identifier for each row in the final result
|
||||||
* 2. category
|
* 2. category
|
||||||
* the label or identifier for each column in the final result
|
* the label or identifier for each column in the final result
|
||||||
* 3. values
|
* 3. values
|
||||||
* the value for each column in the final result
|
* the value for each column in the final result
|
||||||
*----------
|
*----------
|
||||||
@ -404,7 +402,7 @@ crosstab(PG_FUNCTION_ARGS)
|
|||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("invalid source data SQL statement"),
|
errmsg("invalid source data SQL statement"),
|
||||||
errdetail("The provided SQL must return 3 "
|
errdetail("The provided SQL must return 3 "
|
||||||
"columns: rowid, category, and values.")));
|
"columns: rowid, category, and values.")));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -439,8 +437,8 @@ crosstab(PG_FUNCTION_ARGS)
|
|||||||
tupdesc = CreateTupleDescCopy(tupdesc);
|
tupdesc = CreateTupleDescCopy(tupdesc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that return tupdesc is compatible with the data we got
|
* Check that return tupdesc is compatible with the data we got from
|
||||||
* from SPI, at least based on number and type of attributes
|
* SPI, at least based on number and type of attributes
|
||||||
*/
|
*/
|
||||||
if (!compatCrosstabTupleDescs(tupdesc, spi_tupdesc))
|
if (!compatCrosstabTupleDescs(tupdesc, spi_tupdesc))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -449,8 +447,8 @@ crosstab(PG_FUNCTION_ARGS)
|
|||||||
"incompatible")));
|
"incompatible")));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate attribute metadata needed later to produce tuples from
|
* Generate attribute metadata needed later to produce tuples from raw
|
||||||
* raw C strings
|
* C strings
|
||||||
*/
|
*/
|
||||||
attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
||||||
funcctx->attinmeta = attinmeta;
|
funcctx->attinmeta = attinmeta;
|
||||||
@ -530,11 +528,10 @@ crosstab(PG_FUNCTION_ARGS)
|
|||||||
rowid = SPI_getvalue(spi_tuple, spi_tupdesc, 1);
|
rowid = SPI_getvalue(spi_tuple, spi_tupdesc, 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is the first pass through the values for this
|
* If this is the first pass through the values for this rowid
|
||||||
* rowid set it, otherwise make sure it hasn't changed on
|
* set it, otherwise make sure it hasn't changed on us. Also
|
||||||
* us. Also check to see if the rowid is the same as that
|
* check to see if the rowid is the same as that of the last
|
||||||
* of the last tuple sent -- if so, skip this tuple
|
* tuple sent -- if so, skip this tuple entirely
|
||||||
* entirely
|
|
||||||
*/
|
*/
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
values[0] = pstrdup(rowid);
|
values[0] = pstrdup(rowid);
|
||||||
@ -550,16 +547,15 @@ crosstab(PG_FUNCTION_ARGS)
|
|||||||
* Get the next category item value, which is alway
|
* Get the next category item value, which is alway
|
||||||
* attribute number three.
|
* attribute number three.
|
||||||
*
|
*
|
||||||
* Be careful to sssign the value to the array index
|
* Be careful to sssign the value to the array index based on
|
||||||
* based on which category we are presently
|
* which category we are presently processing.
|
||||||
* processing.
|
|
||||||
*/
|
*/
|
||||||
values[1 + i] = SPI_getvalue(spi_tuple, spi_tupdesc, 3);
|
values[1 + i] = SPI_getvalue(spi_tuple, spi_tupdesc, 3);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* increment the counter since we consume a row for
|
* increment the counter since we consume a row for each
|
||||||
* each category, but not for last pass because the
|
* category, but not for last pass because the API will do
|
||||||
* API will do that for us
|
* that for us
|
||||||
*/
|
*/
|
||||||
if (i < (num_categories - 1))
|
if (i < (num_categories - 1))
|
||||||
call_cntr = ++funcctx->call_cntr;
|
call_cntr = ++funcctx->call_cntr;
|
||||||
@ -567,9 +563,9 @@ crosstab(PG_FUNCTION_ARGS)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We'll fill in NULLs for the missing values, but we
|
* We'll fill in NULLs for the missing values, but we need
|
||||||
* need to decrement the counter since this sql result
|
* to decrement the counter since this sql result row
|
||||||
* row doesn't belong to the current output tuple.
|
* doesn't belong to the current output tuple.
|
||||||
*/
|
*/
|
||||||
call_cntr = --funcctx->call_cntr;
|
call_cntr = --funcctx->call_cntr;
|
||||||
break;
|
break;
|
||||||
@ -584,8 +580,8 @@ crosstab(PG_FUNCTION_ARGS)
|
|||||||
if (values[0] != NULL)
|
if (values[0] != NULL)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* switch to memory context appropriate for multiple
|
* switch to memory context appropriate for multiple function
|
||||||
* function calls
|
* calls
|
||||||
*/
|
*/
|
||||||
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
||||||
|
|
||||||
@ -612,8 +608,8 @@ crosstab(PG_FUNCTION_ARGS)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Skipping this tuple entirely, but we need to advance
|
* Skipping this tuple entirely, but we need to advance the
|
||||||
* the counter like the API would if we had returned one.
|
* counter like the API would if we had returned one.
|
||||||
*/
|
*/
|
||||||
call_cntr = ++funcctx->call_cntr;
|
call_cntr = ++funcctx->call_cntr;
|
||||||
|
|
||||||
@ -631,7 +627,7 @@ crosstab(PG_FUNCTION_ARGS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* do when there is no more left */
|
/* do when there is no more left */
|
||||||
{
|
{
|
||||||
/* release SPI related resources */
|
/* release SPI related resources */
|
||||||
SPI_finish();
|
SPI_finish();
|
||||||
@ -730,10 +726,10 @@ crosstab_hash(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* SFRM_Materialize mode expects us to return a NULL Datum. The actual
|
* SFRM_Materialize mode expects us to return a NULL Datum. The actual
|
||||||
* tuples are in our tuplestore and passed back through
|
* tuples are in our tuplestore and passed back through rsinfo->setResult.
|
||||||
* rsinfo->setResult. rsinfo->setDesc is set to the tuple description
|
* rsinfo->setDesc is set to the tuple description that we actually used
|
||||||
* that we actually used to build our tuples with, so the caller can
|
* to build our tuples with, so the caller can verify we did what it was
|
||||||
* verify we did what it was expecting.
|
* expecting.
|
||||||
*/
|
*/
|
||||||
rsinfo->setDesc = tupdesc;
|
rsinfo->setDesc = tupdesc;
|
||||||
MemoryContextSwitchTo(oldcontext);
|
MemoryContextSwitchTo(oldcontext);
|
||||||
@ -758,8 +754,8 @@ load_categories_hash(char *cats_sql, MemoryContext per_query_ctx)
|
|||||||
ctl.entrysize = sizeof(crosstab_HashEnt);
|
ctl.entrysize = sizeof(crosstab_HashEnt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* use INIT_CATS, defined above as a guess of how many hash table
|
* use INIT_CATS, defined above as a guess of how many hash table entries
|
||||||
* entries to create, initially
|
* to create, initially
|
||||||
*/
|
*/
|
||||||
crosstab_HashTable = hash_create("crosstab hash", INIT_CATS, &ctl, HASH_ELEM);
|
crosstab_HashTable = hash_create("crosstab hash", INIT_CATS, &ctl, HASH_ELEM);
|
||||||
|
|
||||||
@ -780,8 +776,8 @@ load_categories_hash(char *cats_sql, MemoryContext per_query_ctx)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The provided categories SQL query must always return one
|
* The provided categories SQL query must always return one column:
|
||||||
* column: category - the label or identifier for each column
|
* category - the label or identifier for each column
|
||||||
*/
|
*/
|
||||||
if (spi_tupdesc->natts != 1)
|
if (spi_tupdesc->natts != 1)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -872,26 +868,24 @@ get_crosstab_tuplestore(char *sql,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The provided SQL query must always return at least three
|
* The provided SQL query must always return at least three columns:
|
||||||
* columns:
|
|
||||||
*
|
*
|
||||||
* 1. rowname the label for each row - column 1 in the final result
|
* 1. rowname the label for each row - column 1 in the final result 2.
|
||||||
* 2. category the label for each value-column in the final
|
* category the label for each value-column in the final result 3.
|
||||||
* result 3. value the values used to populate the
|
* value the values used to populate the value-columns
|
||||||
* value-columns
|
|
||||||
*
|
*
|
||||||
* If there are more than three columns, the last two are taken as
|
* If there are more than three columns, the last two are taken as
|
||||||
* "category" and "values". The first column is taken as
|
* "category" and "values". The first column is taken as "rowname".
|
||||||
* "rowname". Additional columns (2 thru N-2) are assumed the same
|
* Additional columns (2 thru N-2) are assumed the same for the same
|
||||||
* for the same "rowname", and are copied into the result tuple
|
* "rowname", and are copied into the result tuple from the first time
|
||||||
* from the first time we encounter a particular rowname.
|
* we encounter a particular rowname.
|
||||||
*/
|
*/
|
||||||
if (ncols < 3)
|
if (ncols < 3)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
errmsg("invalid source data SQL statement"),
|
errmsg("invalid source data SQL statement"),
|
||||||
errdetail("The provided SQL must return 3 " \
|
errdetail("The provided SQL must return 3 " \
|
||||||
" columns; rowid, category, and values.")));
|
" columns; rowid, category, and values.")));
|
||||||
|
|
||||||
result_ncols = (ncols - 2) + num_categories;
|
result_ncols = (ncols - 2) + num_categories;
|
||||||
|
|
||||||
@ -902,7 +896,7 @@ get_crosstab_tuplestore(char *sql,
|
|||||||
errmsg("invalid return type"),
|
errmsg("invalid return type"),
|
||||||
errdetail("query-specified return " \
|
errdetail("query-specified return " \
|
||||||
"tuple has %d columns but crosstab " \
|
"tuple has %d columns but crosstab " \
|
||||||
"returns %d", tupdesc->natts, result_ncols)));
|
"returns %d", tupdesc->natts, result_ncols)));
|
||||||
|
|
||||||
/* allocate space */
|
/* allocate space */
|
||||||
values = (char **) palloc(result_ncols * sizeof(char *));
|
values = (char **) palloc(result_ncols * sizeof(char *));
|
||||||
@ -933,14 +927,13 @@ get_crosstab_tuplestore(char *sql,
|
|||||||
if ((lastrowid == NULL) || (strcmp(rowid, lastrowid) != 0))
|
if ((lastrowid == NULL) || (strcmp(rowid, lastrowid) != 0))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* a new row means we need to flush the old one first,
|
* a new row means we need to flush the old one first, unless
|
||||||
* unless we're on the very first row
|
* we're on the very first row
|
||||||
*/
|
*/
|
||||||
if (lastrowid != NULL)
|
if (lastrowid != NULL)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* switch to appropriate context while storing the
|
* switch to appropriate context while storing the tuple
|
||||||
* tuple
|
|
||||||
*/
|
*/
|
||||||
SPIcontext = MemoryContextSwitchTo(per_query_ctx);
|
SPIcontext = MemoryContextSwitchTo(per_query_ctx);
|
||||||
|
|
||||||
@ -1103,10 +1096,10 @@ connectby_text(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* SFRM_Materialize mode expects us to return a NULL Datum. The actual
|
* SFRM_Materialize mode expects us to return a NULL Datum. The actual
|
||||||
* tuples are in our tuplestore and passed back through
|
* tuples are in our tuplestore and passed back through rsinfo->setResult.
|
||||||
* rsinfo->setResult. rsinfo->setDesc is set to the tuple description
|
* rsinfo->setDesc is set to the tuple description that we actually used
|
||||||
* that we actually used to build our tuples with, so the caller can
|
* to build our tuples with, so the caller can verify we did what it was
|
||||||
* verify we did what it was expecting.
|
* expecting.
|
||||||
*/
|
*/
|
||||||
return (Datum) 0;
|
return (Datum) 0;
|
||||||
}
|
}
|
||||||
@ -1182,10 +1175,10 @@ connectby_text_serial(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* SFRM_Materialize mode expects us to return a NULL Datum. The actual
|
* SFRM_Materialize mode expects us to return a NULL Datum. The actual
|
||||||
* tuples are in our tuplestore and passed back through
|
* tuples are in our tuplestore and passed back through rsinfo->setResult.
|
||||||
* rsinfo->setResult. rsinfo->setDesc is set to the tuple description
|
* rsinfo->setDesc is set to the tuple description that we actually used
|
||||||
* that we actually used to build our tuples with, so the caller can
|
* to build our tuples with, so the caller can verify we did what it was
|
||||||
* verify we did what it was expecting.
|
* expecting.
|
||||||
*/
|
*/
|
||||||
return (Datum) 0;
|
return (Datum) 0;
|
||||||
}
|
}
|
||||||
@ -1382,16 +1375,16 @@ build_tuplestore_recursively(char *key_fld,
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Check that return tupdesc is compatible with the one we got
|
* Check that return tupdesc is compatible with the one we got
|
||||||
* from the query, but only at level 0 -- no need to check
|
* from the query, but only at level 0 -- no need to check more
|
||||||
* more than once
|
* than once
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!compatConnectbyTupleDescs(tupdesc, spi_tupdesc))
|
if (!compatConnectbyTupleDescs(tupdesc, spi_tupdesc))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("invalid return type"),
|
errmsg("invalid return type"),
|
||||||
errdetail("Return and SQL tuple descriptions are " \
|
errdetail("Return and SQL tuple descriptions are " \
|
||||||
"incompatible.")));
|
"incompatible.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < proc; i++)
|
for (i = 0; i < proc; i++)
|
||||||
@ -1576,7 +1569,7 @@ compatConnectbyTupleDescs(TupleDesc ret_tupdesc, TupleDesc sql_tupdesc)
|
|||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("invalid return type"),
|
errmsg("invalid return type"),
|
||||||
errdetail("SQL parent key field datatype does " \
|
errdetail("SQL parent key field datatype does " \
|
||||||
"not match return parent key field datatype.")));
|
"not match return parent key field datatype.")));
|
||||||
|
|
||||||
/* OK, the two tupdescs are compatible for our purposes */
|
/* OK, the two tupdescs are compatible for our purposes */
|
||||||
return true;
|
return true;
|
||||||
@ -1605,9 +1598,9 @@ compatCrosstabTupleDescs(TupleDesc ret_tupdesc, TupleDesc sql_tupdesc)
|
|||||||
"return rowid datatype.")));
|
"return rowid datatype.")));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* - attribute [1] of the sql tuple is the category; no need to check
|
* - attribute [1] of the sql tuple is the category; no need to check it -
|
||||||
* it - attribute [2] of the sql tuple should match attributes [1] to
|
* attribute [2] of the sql tuple should match attributes [1] to [natts]
|
||||||
* [natts] of the return tuple
|
* of the return tuple
|
||||||
*/
|
*/
|
||||||
sql_attr = sql_tupdesc->attrs[2];
|
sql_attr = sql_tupdesc->attrs[2];
|
||||||
for (i = 1; i < ret_tupdesc->natts; i++)
|
for (i = 1; i < ret_tupdesc->natts; i++)
|
||||||
|
@ -91,9 +91,9 @@ reset_dict(void)
|
|||||||
static int
|
static int
|
||||||
comparedict(const void *a, const void *b)
|
comparedict(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
if ( ((DictInfo *) a)->dict_id == ((DictInfo *) b)->dict_id )
|
if (((DictInfo *) a)->dict_id == ((DictInfo *) b)->dict_id)
|
||||||
return 0;
|
return 0;
|
||||||
return ( ((DictInfo *) a)->dict_id < ((DictInfo *) b)->dict_id ) ? -1 : 1;
|
return (((DictInfo *) a)->dict_id < ((DictInfo *) b)->dict_id) ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DictInfo *
|
DictInfo *
|
||||||
@ -184,8 +184,8 @@ lexize(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
text *in = PG_GETARG_TEXT_P(1);
|
text *in = PG_GETARG_TEXT_P(1);
|
||||||
DictInfo *dict;
|
DictInfo *dict;
|
||||||
TSLexeme *res,
|
TSLexeme *res,
|
||||||
*ptr;
|
*ptr;
|
||||||
Datum *da;
|
Datum *da;
|
||||||
ArrayType *a;
|
ArrayType *a;
|
||||||
|
|
||||||
@ -193,11 +193,11 @@ lexize(PG_FUNCTION_ARGS)
|
|||||||
dict = finddict(PG_GETARG_OID(0));
|
dict = finddict(PG_GETARG_OID(0));
|
||||||
|
|
||||||
ptr = res = (TSLexeme *) DatumGetPointer(
|
ptr = res = (TSLexeme *) DatumGetPointer(
|
||||||
FunctionCall3(&(dict->lexize_info),
|
FunctionCall3(&(dict->lexize_info),
|
||||||
PointerGetDatum(dict->dictionary),
|
PointerGetDatum(dict->dictionary),
|
||||||
PointerGetDatum(VARDATA(in)),
|
PointerGetDatum(VARDATA(in)),
|
||||||
Int32GetDatum(VARSIZE(in) - VARHDRSZ)
|
Int32GetDatum(VARSIZE(in) - VARHDRSZ)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
PG_FREE_IF_COPY(in, 1);
|
PG_FREE_IF_COPY(in, 1);
|
||||||
if (!res)
|
if (!res)
|
||||||
|
@ -39,26 +39,22 @@ typedef struct
|
|||||||
void parse_cfgdict(text *in, Map ** m);
|
void parse_cfgdict(text *in, Map ** m);
|
||||||
|
|
||||||
/* return struct for any lexize function */
|
/* return struct for any lexize function */
|
||||||
typedef struct {
|
typedef struct
|
||||||
/* number of variant of split word , for example
|
{
|
||||||
Word 'fotballklubber' (norwegian) has two varian to split:
|
/*
|
||||||
( fotball, klubb ) and ( fot, ball, klubb ). So, dictionary
|
* number of variant of split word , for example Word 'fotballklubber'
|
||||||
should return:
|
* (norwegian) has two varian to split: ( fotball, klubb ) and ( fot,
|
||||||
nvariant lexeme
|
* ball, klubb ). So, dictionary should return: nvariant lexeme 1
|
||||||
1 fotball
|
* fotball 1 klubb 2 fot 2 ball 2 klubb
|
||||||
1 klubb
|
*
|
||||||
2 fot
|
*/
|
||||||
2 ball
|
uint16 nvariant;
|
||||||
2 klubb
|
|
||||||
|
|
||||||
*/
|
|
||||||
uint16 nvariant;
|
|
||||||
|
|
||||||
/* currently unused */
|
/* currently unused */
|
||||||
uint16 flags;
|
uint16 flags;
|
||||||
|
|
||||||
/* C-string */
|
/* C-string */
|
||||||
char *lexeme;
|
char *lexeme;
|
||||||
} TSLexeme;
|
} TSLexeme;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,7 +52,7 @@ dex_lexize(PG_FUNCTION_ARGS)
|
|||||||
char *txt = pnstrdup(in, PG_GETARG_INT32(2));
|
char *txt = pnstrdup(in, PG_GETARG_INT32(2));
|
||||||
TSLexeme *res = palloc(sizeof(TSLexeme) * 2);
|
TSLexeme *res = palloc(sizeof(TSLexeme) * 2);
|
||||||
|
|
||||||
memset(res,0,sizeof(TSLexeme) * 2);
|
memset(res, 0, sizeof(TSLexeme) * 2);
|
||||||
|
|
||||||
if (*txt == '\0' || searchstoplist(&(d->stoplist), txt))
|
if (*txt == '\0' || searchstoplist(&(d->stoplist), txt))
|
||||||
{
|
{
|
||||||
|
@ -66,8 +66,8 @@ spell_init(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
freeDictISpell(d);
|
freeDictISpell(d);
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||||
errmsg("dictionary already loaded")));
|
errmsg("dictionary already loaded")));
|
||||||
}
|
}
|
||||||
if (NIImportDictionary(&(d->obj), pcfg->value))
|
if (NIImportDictionary(&(d->obj), pcfg->value))
|
||||||
{
|
{
|
||||||
@ -85,8 +85,8 @@ spell_init(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
freeDictISpell(d);
|
freeDictISpell(d);
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||||
errmsg("affixes already loaded")));
|
errmsg("affixes already loaded")));
|
||||||
}
|
}
|
||||||
if (NIImportAffixes(&(d->obj), pcfg->value))
|
if (NIImportAffixes(&(d->obj), pcfg->value))
|
||||||
{
|
{
|
||||||
@ -106,8 +106,8 @@ spell_init(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
freeDictISpell(d);
|
freeDictISpell(d);
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||||
errmsg("stop words already loaded")));
|
errmsg("stop words already loaded")));
|
||||||
}
|
}
|
||||||
readstoplist(tmp, &(d->stoplist));
|
readstoplist(tmp, &(d->stoplist));
|
||||||
sortstoplist(&(d->stoplist));
|
sortstoplist(&(d->stoplist));
|
||||||
@ -157,9 +157,9 @@ spell_lexize(PG_FUNCTION_ARGS)
|
|||||||
DictISpell *d = (DictISpell *) PG_GETARG_POINTER(0);
|
DictISpell *d = (DictISpell *) PG_GETARG_POINTER(0);
|
||||||
char *in = (char *) PG_GETARG_POINTER(1);
|
char *in = (char *) PG_GETARG_POINTER(1);
|
||||||
char *txt;
|
char *txt;
|
||||||
TSLexeme *res;
|
TSLexeme *res;
|
||||||
TSLexeme *ptr,
|
TSLexeme *ptr,
|
||||||
*cptr;
|
*cptr;
|
||||||
|
|
||||||
if (!PG_GETARG_INT32(2))
|
if (!PG_GETARG_INT32(2))
|
||||||
PG_RETURN_POINTER(NULL);
|
PG_RETURN_POINTER(NULL);
|
||||||
|
@ -102,7 +102,7 @@ snb_lexize(PG_FUNCTION_ARGS)
|
|||||||
DictSnowball *d = (DictSnowball *) PG_GETARG_POINTER(0);
|
DictSnowball *d = (DictSnowball *) PG_GETARG_POINTER(0);
|
||||||
char *in = (char *) PG_GETARG_POINTER(1);
|
char *in = (char *) PG_GETARG_POINTER(1);
|
||||||
char *txt = pnstrdup(in, PG_GETARG_INT32(2));
|
char *txt = pnstrdup(in, PG_GETARG_INT32(2));
|
||||||
TSLexeme *res = palloc(sizeof(TSLexeme) * 2);
|
TSLexeme *res = palloc(sizeof(TSLexeme) * 2);
|
||||||
|
|
||||||
memset(res, 0, sizeof(TSLexeme) * 2);
|
memset(res, 0, sizeof(TSLexeme) * 2);
|
||||||
if (*txt == '\0' || searchstoplist(&(d->stoplist), txt))
|
if (*txt == '\0' || searchstoplist(&(d->stoplist), txt))
|
||||||
|
@ -159,7 +159,7 @@ syn_lexize(PG_FUNCTION_ARGS)
|
|||||||
char *in = (char *) PG_GETARG_POINTER(1);
|
char *in = (char *) PG_GETARG_POINTER(1);
|
||||||
Syn key,
|
Syn key,
|
||||||
*found;
|
*found;
|
||||||
TSLexeme *res = NULL;
|
TSLexeme *res = NULL;
|
||||||
|
|
||||||
if (!PG_GETARG_INT32(2))
|
if (!PG_GETARG_INT32(2))
|
||||||
PG_RETURN_POINTER(NULL);
|
PG_RETURN_POINTER(NULL);
|
||||||
@ -174,7 +174,7 @@ syn_lexize(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_POINTER(NULL);
|
PG_RETURN_POINTER(NULL);
|
||||||
|
|
||||||
res = palloc(sizeof(TSLexeme) * 2);
|
res = palloc(sizeof(TSLexeme) * 2);
|
||||||
memset(res,0,sizeof(TSLexeme) * 2);
|
memset(res, 0, sizeof(TSLexeme) * 2);
|
||||||
res[0].lexeme = pstrdup(found->out);
|
res[0].lexeme = pstrdup(found->out);
|
||||||
|
|
||||||
PG_RETURN_POINTER(res);
|
PG_RETURN_POINTER(res);
|
||||||
|
@ -65,30 +65,32 @@ gtsvector_in(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_DATUM(0);
|
PG_RETURN_DATUM(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SINGOUTSTR "%d true bits, %d false bits"
|
#define SINGOUTSTR "%d true bits, %d false bits"
|
||||||
#define ARROUTSTR "%d unique words"
|
#define ARROUTSTR "%d unique words"
|
||||||
#define EXTRALEN ( 2*13 )
|
#define EXTRALEN ( 2*13 )
|
||||||
|
|
||||||
static int outbuf_maxlen = 0;
|
static int outbuf_maxlen = 0;
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
gtsvector_out(PG_FUNCTION_ARGS)
|
gtsvector_out(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
GISTTYPE *key = (GISTTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_POINTER(0)));
|
GISTTYPE *key = (GISTTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_POINTER(0)));
|
||||||
char *outbuf;
|
char *outbuf;
|
||||||
|
|
||||||
if ( outbuf_maxlen==0 )
|
if (outbuf_maxlen == 0)
|
||||||
outbuf_maxlen = 2*EXTRALEN + Max( strlen(SINGOUTSTR), strlen(ARROUTSTR) ) + 1;
|
outbuf_maxlen = 2 * EXTRALEN + Max(strlen(SINGOUTSTR), strlen(ARROUTSTR)) + 1;
|
||||||
outbuf = palloc( outbuf_maxlen );
|
outbuf = palloc(outbuf_maxlen);
|
||||||
|
|
||||||
if ( ISARRKEY(key) )
|
if (ISARRKEY(key))
|
||||||
sprintf( outbuf, ARROUTSTR, (int) ARRNELEM(key) );
|
sprintf(outbuf, ARROUTSTR, (int) ARRNELEM(key));
|
||||||
else {
|
else
|
||||||
int cnttrue = ( ISALLTRUE(key) ) ? SIGLENBIT : sizebitvec(GETSIGN(key));
|
{
|
||||||
sprintf( outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT - cnttrue );
|
int cnttrue = (ISALLTRUE(key)) ? SIGLENBIT : sizebitvec(GETSIGN(key));
|
||||||
|
|
||||||
|
sprintf(outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT - cnttrue);
|
||||||
}
|
}
|
||||||
|
|
||||||
PG_FREE_IF_COPY(key,0);
|
PG_FREE_IF_COPY(key, 0);
|
||||||
PG_RETURN_POINTER(outbuf);
|
PG_RETURN_POINTER(outbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,8 +167,8 @@ gtsvector_compress(PG_FUNCTION_ARGS)
|
|||||||
if (len != val->size)
|
if (len != val->size)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* there is a collision of hash-function; len is always less
|
* there is a collision of hash-function; len is always less than
|
||||||
* than val->size
|
* val->size
|
||||||
*/
|
*/
|
||||||
len = CALCGTSIZE(ARRKEY, len);
|
len = CALCGTSIZE(ARRKEY, len);
|
||||||
res = (GISTTYPE *) repalloc((void *) res, len);
|
res = (GISTTYPE *) repalloc((void *) res, len);
|
||||||
@ -280,7 +282,7 @@ gtsvector_consistent(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
QUERYTYPE *query = (QUERYTYPE *) PG_GETARG_POINTER(1);
|
QUERYTYPE *query = (QUERYTYPE *) PG_GETARG_POINTER(1);
|
||||||
GISTTYPE *key = (GISTTYPE *) DatumGetPointer(
|
GISTTYPE *key = (GISTTYPE *) DatumGetPointer(
|
||||||
((GISTENTRY *) PG_GETARG_POINTER(0))->key
|
((GISTENTRY *) PG_GETARG_POINTER(0))->key
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!query->size)
|
if (!query->size)
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define BITBYTE 8
|
#define BITBYTE 8
|
||||||
#define SIGLENINT 63 /* >121 => key will toast, so it will not
|
#define SIGLENINT 63 /* >121 => key will toast, so it will not work
|
||||||
* work !!! */
|
* !!! */
|
||||||
#define SIGLEN ( sizeof(int4) * SIGLENINT )
|
#define SIGLEN ( sizeof(int4) * SIGLENINT )
|
||||||
#define SIGLENBIT (SIGLEN * BITBYTE)
|
#define SIGLENBIT (SIGLEN * BITBYTE)
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ typedef struct
|
|||||||
#define ISSIGNKEY(x) ( ((GISTTYPE*)(x))->flag & SIGNKEY )
|
#define ISSIGNKEY(x) ( ((GISTTYPE*)(x))->flag & SIGNKEY )
|
||||||
#define ISALLTRUE(x) ( ((GISTTYPE*)(x))->flag & ALLISTRUE )
|
#define ISALLTRUE(x) ( ((GISTTYPE*)(x))->flag & ALLISTRUE )
|
||||||
|
|
||||||
#define GTHDRSIZE ( sizeof(int4) * 2 )
|
#define GTHDRSIZE ( sizeof(int4) * 2 )
|
||||||
#define CALCGTSIZE(flag, len) ( GTHDRSIZE + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(int4)) : (((flag) & ALLISTRUE) ? 0 : SIGLEN) ) )
|
#define CALCGTSIZE(flag, len) ( GTHDRSIZE + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(int4)) : (((flag) & ALLISTRUE) ? 0 : SIGLEN) ) )
|
||||||
|
|
||||||
#define GETSIGN(x) ( (BITVECP)( (char*)(x)+GTHDRSIZE ) )
|
#define GETSIGN(x) ( (BITVECP)( (char*)(x)+GTHDRSIZE ) )
|
||||||
|
@ -153,7 +153,7 @@ NIImportDictionary(IspellDict * Conf, const char *filename)
|
|||||||
return (1);
|
return (1);
|
||||||
while (fgets(str, sizeof(str), dict))
|
while (fgets(str, sizeof(str), dict))
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
const char *flag;
|
const char *flag;
|
||||||
|
|
||||||
flag = NULL;
|
flag = NULL;
|
||||||
@ -266,7 +266,7 @@ NIAddAffix(IspellDict * Conf, int flag, char flagflags, const char *mask, const
|
|||||||
{
|
{
|
||||||
Conf->Affix[Conf->naffixes].issimple = 0;
|
Conf->Affix[Conf->naffixes].issimple = 0;
|
||||||
Conf->Affix[Conf->naffixes].isregis = 0;
|
Conf->Affix[Conf->naffixes].isregis = 0;
|
||||||
Conf->Affix[Conf->naffixes].mask = (char*)malloc( strlen(mask) + 2 );
|
Conf->Affix[Conf->naffixes].mask = (char *) malloc(strlen(mask) + 2);
|
||||||
if (type == FF_SUFFIX)
|
if (type == FF_SUFFIX)
|
||||||
sprintf(Conf->Affix[Conf->naffixes].mask, "%s$", mask);
|
sprintf(Conf->Affix[Conf->naffixes].mask, "%s$", mask);
|
||||||
else
|
else
|
||||||
@ -489,8 +489,8 @@ mkSPNode(IspellDict * Conf, int low, int high, int level)
|
|||||||
if (data->isword && data->affix != Conf->Spell[i].p.d.affix)
|
if (data->isword && data->affix != Conf->Spell[i].p.d.affix)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* fprintf(stderr,"Word already exists: %s (affixes:
|
* fprintf(stderr,"Word already exists: %s (affixes: '%s'
|
||||||
* '%s' and '%s')\n", Conf->Spell[i].word,
|
* and '%s')\n", Conf->Spell[i].word,
|
||||||
* Conf->AffixData[data->affix],
|
* Conf->AffixData[data->affix],
|
||||||
* Conf->AffixData[Conf->Spell[i].p.d.affix] );
|
* Conf->AffixData[Conf->Spell[i].p.d.affix] );
|
||||||
*/
|
*/
|
||||||
@ -806,7 +806,8 @@ CheckAffix(const char *word, size_t len, AFFIX * Affix, char flagflags, char *ne
|
|||||||
pfree(mask);
|
pfree(mask);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
char regerrstr[ERRSTRSIZE];
|
char regerrstr[ERRSTRSIZE];
|
||||||
|
|
||||||
pg_regerror(err, &(Affix->reg.regex), regerrstr, ERRSTRSIZE);
|
pg_regerror(err, &(Affix->reg.regex), regerrstr, ERRSTRSIZE);
|
||||||
elog(ERROR, "Regex error in '%s': %s", Affix->mask, regerrstr);
|
elog(ERROR, "Regex error in '%s': %s", Affix->mask, regerrstr);
|
||||||
}
|
}
|
||||||
@ -1037,8 +1038,7 @@ SplitToVariants(IspellDict * Conf, SPNode * snode, SplitVar * orig, char *word,
|
|||||||
while (level > startpos && (lenaff = CheckCompoundAffixes(&caff, word + level, wordlen - level)) > 0)
|
while (level > startpos && (lenaff = CheckCompoundAffixes(&caff, word + level, wordlen - level)) > 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* there is one of compound suffixes, so check word for
|
* there is one of compound suffixes, so check word for existings
|
||||||
* existings
|
|
||||||
*/
|
*/
|
||||||
char buf[MAXNORMLEN];
|
char buf[MAXNORMLEN];
|
||||||
char **subres;
|
char **subres;
|
||||||
@ -1128,20 +1128,24 @@ TSLexeme *
|
|||||||
NINormalizeWord(IspellDict * Conf, char *word)
|
NINormalizeWord(IspellDict * Conf, char *word)
|
||||||
{
|
{
|
||||||
char **res = NormalizeSubWord(Conf, word, 0);
|
char **res = NormalizeSubWord(Conf, word, 0);
|
||||||
TSLexeme *lcur=NULL, *lres=NULL;
|
TSLexeme *lcur = NULL,
|
||||||
uint16 NVariant=1;
|
*lres = NULL;
|
||||||
|
uint16 NVariant = 1;
|
||||||
|
|
||||||
if (res) {
|
if (res)
|
||||||
char **ptr = res;
|
{
|
||||||
lcur = lres = (TSLexeme*)palloc( MAX_NORM * sizeof(TSLexeme) );
|
char **ptr = res;
|
||||||
while(*ptr) {
|
|
||||||
lcur->lexeme=*ptr;
|
lcur = lres = (TSLexeme *) palloc(MAX_NORM * sizeof(TSLexeme));
|
||||||
lcur->flags=0;
|
while (*ptr)
|
||||||
|
{
|
||||||
|
lcur->lexeme = *ptr;
|
||||||
|
lcur->flags = 0;
|
||||||
lcur->nvariant = NVariant++;
|
lcur->nvariant = NVariant++;
|
||||||
lcur++;
|
lcur++;
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
lcur->lexeme=NULL;
|
lcur->lexeme = NULL;
|
||||||
pfree(res);
|
pfree(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1162,29 +1166,31 @@ NINormalizeWord(IspellDict * Conf, char *word)
|
|||||||
{
|
{
|
||||||
char **subptr = subres;
|
char **subptr = subres;
|
||||||
|
|
||||||
if ( !lcur )
|
if (!lcur)
|
||||||
lcur = lres = (TSLexeme*)palloc( MAX_NORM * sizeof(TSLexeme) );
|
lcur = lres = (TSLexeme *) palloc(MAX_NORM * sizeof(TSLexeme));
|
||||||
|
|
||||||
while(*subptr) {
|
while (*subptr)
|
||||||
for(i=0;i<var->nstem-1;i++) {
|
{
|
||||||
lcur->lexeme=(subptr==subres) ? var->stem[ i ] : pstrdup(var->stem[ i ]);
|
for (i = 0; i < var->nstem - 1; i++)
|
||||||
lcur->flags=0;
|
{
|
||||||
|
lcur->lexeme = (subptr == subres) ? var->stem[i] : pstrdup(var->stem[i]);
|
||||||
|
lcur->flags = 0;
|
||||||
lcur->nvariant = NVariant;
|
lcur->nvariant = NVariant;
|
||||||
lcur++;
|
lcur++;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcur->lexeme=*subptr;
|
lcur->lexeme = *subptr;
|
||||||
lcur->flags=0;
|
lcur->flags = 0;
|
||||||
lcur->nvariant = NVariant;
|
lcur->nvariant = NVariant;
|
||||||
lcur++;
|
lcur++;
|
||||||
subptr++;
|
subptr++;
|
||||||
NVariant++;
|
NVariant++;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcur->lexeme=NULL;
|
lcur->lexeme = NULL;
|
||||||
pfree(subres);
|
pfree(subres);
|
||||||
var->stem[0] = NULL;
|
var->stem[0] = NULL;
|
||||||
pfree( var->stem[ var->nstem-1 ] );
|
pfree(var->stem[var->nstem - 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,9 +55,9 @@ typedef struct aff_struct
|
|||||||
isregis:1,
|
isregis:1,
|
||||||
unused:1,
|
unused:1,
|
||||||
replen:16;
|
replen:16;
|
||||||
char *mask;
|
char *mask;
|
||||||
char *find;
|
char *find;
|
||||||
char *repl;
|
char *repl;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
regex_t regex;
|
regex_t regex;
|
||||||
@ -117,7 +117,7 @@ typedef struct
|
|||||||
|
|
||||||
} IspellDict;
|
} IspellDict;
|
||||||
|
|
||||||
TSLexeme *NINormalizeWord(IspellDict * Conf, char *word);
|
TSLexeme *NINormalizeWord(IspellDict * Conf, char *word);
|
||||||
int NIImportAffixes(IspellDict * Conf, const char *filename);
|
int NIImportAffixes(IspellDict * Conf, const char *filename);
|
||||||
int NIImportDictionary(IspellDict * Conf, const char *filename);
|
int NIImportDictionary(IspellDict * Conf, const char *filename);
|
||||||
|
|
||||||
|
@ -73,8 +73,8 @@ parse_cfgdict(text *in, Map ** m)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("syntax error"),
|
errmsg("syntax error"),
|
||||||
errdetail("Syntax error in position %d near \"%c\"",
|
errdetail("Syntax error in position %d near \"%c\"",
|
||||||
(int) (ptr - VARDATA(in)), *ptr)));
|
(int) (ptr - VARDATA(in)), *ptr)));
|
||||||
}
|
}
|
||||||
else if (state == CS_INKEY)
|
else if (state == CS_INKEY)
|
||||||
{
|
{
|
||||||
@ -92,8 +92,8 @@ parse_cfgdict(text *in, Map ** m)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("syntax error"),
|
errmsg("syntax error"),
|
||||||
errdetail("Syntax error in position %d near \"%c\"",
|
errdetail("Syntax error in position %d near \"%c\"",
|
||||||
(int) (ptr - VARDATA(in)), *ptr)));
|
(int) (ptr - VARDATA(in)), *ptr)));
|
||||||
}
|
}
|
||||||
else if (state == CS_WAITEQ)
|
else if (state == CS_WAITEQ)
|
||||||
{
|
{
|
||||||
@ -103,8 +103,8 @@ parse_cfgdict(text *in, Map ** m)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("syntax error"),
|
errmsg("syntax error"),
|
||||||
errdetail("Syntax error in position %d near \"%c\"",
|
errdetail("Syntax error in position %d near \"%c\"",
|
||||||
(int) (ptr - VARDATA(in)), *ptr)));
|
(int) (ptr - VARDATA(in)), *ptr)));
|
||||||
}
|
}
|
||||||
else if (state == CS_WAITVALUE)
|
else if (state == CS_WAITVALUE)
|
||||||
{
|
{
|
||||||
@ -149,8 +149,8 @@ parse_cfgdict(text *in, Map ** m)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("syntax error"),
|
errmsg("syntax error"),
|
||||||
errdetail("Syntax error in position %d near \"%c\"",
|
errdetail("Syntax error in position %d near \"%c\"",
|
||||||
(int) (ptr - VARDATA(in)), *ptr)));
|
(int) (ptr - VARDATA(in)), *ptr)));
|
||||||
}
|
}
|
||||||
else if (state == CS_INESC)
|
else if (state == CS_INESC)
|
||||||
state = CS_INVALUE;
|
state = CS_INVALUE;
|
||||||
|
@ -265,7 +265,11 @@ pushval_morph(QPRS_STATE * state, int typeval, char *strval, int lenval, int2 we
|
|||||||
{
|
{
|
||||||
int4 count = 0;
|
int4 count = 0;
|
||||||
PRSTEXT prs;
|
PRSTEXT prs;
|
||||||
uint32 variant, pos, cntvar=0, cntpos=0, cnt=0;
|
uint32 variant,
|
||||||
|
pos,
|
||||||
|
cntvar = 0,
|
||||||
|
cntpos = 0,
|
||||||
|
cnt = 0;
|
||||||
|
|
||||||
prs.lenwords = 32;
|
prs.lenwords = 32;
|
||||||
prs.curwords = 0;
|
prs.curwords = 0;
|
||||||
@ -274,26 +278,30 @@ pushval_morph(QPRS_STATE * state, int typeval, char *strval, int lenval, int2 we
|
|||||||
|
|
||||||
parsetext_v2(findcfg(state->cfg_id), &prs, strval, lenval);
|
parsetext_v2(findcfg(state->cfg_id), &prs, strval, lenval);
|
||||||
|
|
||||||
if ( prs.curwords>0 ) {
|
if (prs.curwords > 0)
|
||||||
|
{
|
||||||
|
|
||||||
while (count < prs.curwords) {
|
while (count < prs.curwords)
|
||||||
|
{
|
||||||
pos = prs.words[count].pos.pos;
|
pos = prs.words[count].pos.pos;
|
||||||
cntvar=0;
|
cntvar = 0;
|
||||||
while(count < prs.curwords && pos==prs.words[count].pos.pos) {
|
while (count < prs.curwords && pos == prs.words[count].pos.pos)
|
||||||
|
{
|
||||||
variant = prs.words[count].nvariant;
|
variant = prs.words[count].nvariant;
|
||||||
|
|
||||||
cnt=0;
|
cnt = 0;
|
||||||
while(count < prs.curwords && pos==prs.words[count].pos.pos && variant==prs.words[count].nvariant) {
|
while (count < prs.curwords && pos == prs.words[count].pos.pos && variant == prs.words[count].nvariant)
|
||||||
|
{
|
||||||
|
|
||||||
pushval_asis(state, VAL, prs.words[count].word, prs.words[count].len, weight);
|
pushval_asis(state, VAL, prs.words[count].word, prs.words[count].len, weight);
|
||||||
pfree(prs.words[count].word);
|
pfree(prs.words[count].word);
|
||||||
if ( cnt )
|
if (cnt)
|
||||||
pushquery(state, OPR, (int4) '&', 0, 0, 0);
|
pushquery(state, OPR, (int4) '&', 0, 0, 0);
|
||||||
cnt++;
|
cnt++;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( cntvar )
|
if (cntvar)
|
||||||
pushquery(state, OPR, (int4) '|', 0, 0, 0);
|
pushquery(state, OPR, (int4) '|', 0, 0, 0);
|
||||||
cntvar++;
|
cntvar++;
|
||||||
}
|
}
|
||||||
@ -306,7 +314,8 @@ pushval_morph(QPRS_STATE * state, int typeval, char *strval, int lenval, int2 we
|
|||||||
|
|
||||||
pfree(prs.words);
|
pfree(prs.words);
|
||||||
|
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
pushval_asis(state, VALSTOP, NULL, 0, 0);
|
pushval_asis(state, VALSTOP, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ static float weights[] = {0.1, 0.2, 0.4, 1.0};
|
|||||||
|
|
||||||
static float calc_rank_or(float *w, tsvector * t, QUERYTYPE * q);
|
static float calc_rank_or(float *w, tsvector * t, QUERYTYPE * q);
|
||||||
static float calc_rank_and(float *w, tsvector * t, QUERYTYPE * q);
|
static float calc_rank_and(float *w, tsvector * t, QUERYTYPE * q);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns a weight of a word collocation
|
* Returns a weight of a word collocation
|
||||||
*/
|
*/
|
||||||
@ -115,44 +116,52 @@ find_wordentry(tsvector * t, QUERYTYPE * q, ITEM * item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char * SortAndUniqOperand=NULL;
|
static char *SortAndUniqOperand = NULL;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compareITEM( const void * a, const void * b ) {
|
compareITEM(const void *a, const void *b)
|
||||||
if ( (*(ITEM**)a)->length == (*(ITEM**)b)->length )
|
{
|
||||||
return strncmp( SortAndUniqOperand + (*(ITEM**)a)->distance,
|
if ((*(ITEM **) a)->length == (*(ITEM **) b)->length)
|
||||||
SortAndUniqOperand + (*(ITEM**)b)->distance,
|
return strncmp(SortAndUniqOperand + (*(ITEM **) a)->distance,
|
||||||
(*(ITEM**)b)->length );
|
SortAndUniqOperand + (*(ITEM **) b)->distance,
|
||||||
|
(*(ITEM **) b)->length);
|
||||||
|
|
||||||
return ((*(ITEM**)a)->length > (*(ITEM**)b)->length) ? 1 : -1;
|
return ((*(ITEM **) a)->length > (*(ITEM **) b)->length) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ITEM**
|
static ITEM **
|
||||||
SortAndUniqItems( char *operand, ITEM *item, int *size ) {
|
SortAndUniqItems(char *operand, ITEM * item, int *size)
|
||||||
ITEM **res, **ptr, **prevptr;
|
{
|
||||||
|
ITEM **res,
|
||||||
|
**ptr,
|
||||||
|
**prevptr;
|
||||||
|
|
||||||
ptr = res = (ITEM**) palloc( sizeof(ITEM*) * *size );
|
ptr = res = (ITEM **) palloc(sizeof(ITEM *) * *size);
|
||||||
|
|
||||||
while( (*size)-- ) {
|
while ((*size)--)
|
||||||
if ( item->type == VAL ) {
|
{
|
||||||
|
if (item->type == VAL)
|
||||||
|
{
|
||||||
*ptr = item;
|
*ptr = item;
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
item++;
|
item++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*size = ptr-res;
|
*size = ptr - res;
|
||||||
if ( *size < 2 )
|
if (*size < 2)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
SortAndUniqOperand=operand;
|
SortAndUniqOperand = operand;
|
||||||
qsort( res, *size, sizeof(ITEM**), compareITEM );
|
qsort(res, *size, sizeof(ITEM **), compareITEM);
|
||||||
|
|
||||||
ptr = res + 1;
|
ptr = res + 1;
|
||||||
prevptr = res;
|
prevptr = res;
|
||||||
|
|
||||||
while( ptr - res < *size ) {
|
while (ptr - res < *size)
|
||||||
if ( compareITEM( (void*) ptr, (void*) prevptr ) != 0 ) {
|
{
|
||||||
|
if (compareITEM((void *) ptr, (void *) prevptr) != 0)
|
||||||
|
{
|
||||||
prevptr++;
|
prevptr++;
|
||||||
*prevptr = *ptr;
|
*prevptr = *ptr;
|
||||||
}
|
}
|
||||||
@ -183,18 +192,19 @@ calc_rank_and(float *w, tsvector * t, QUERYTYPE * q)
|
|||||||
lenct,
|
lenct,
|
||||||
dist;
|
dist;
|
||||||
float res = -1.0;
|
float res = -1.0;
|
||||||
ITEM **item;
|
ITEM **item;
|
||||||
int size = q->size;
|
int size = q->size;
|
||||||
|
|
||||||
item = SortAndUniqItems( GETOPERAND(q), GETQUERY(q), &size);
|
item = SortAndUniqItems(GETOPERAND(q), GETQUERY(q), &size);
|
||||||
if ( size < 2 ) {
|
if (size < 2)
|
||||||
|
{
|
||||||
pfree(item);
|
pfree(item);
|
||||||
return calc_rank_or(w, t, q);
|
return calc_rank_or(w, t, q);
|
||||||
}
|
}
|
||||||
pos = (uint16 **) palloc(sizeof(uint16 *) * q->size);
|
pos = (uint16 **) palloc(sizeof(uint16 *) * q->size);
|
||||||
memset(pos, 0, sizeof(uint16 *) * q->size);
|
memset(pos, 0, sizeof(uint16 *) * q->size);
|
||||||
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
|
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
|
||||||
WEP_SETPOS(POSNULL[1], MAXENTRYPOS-1);
|
WEP_SETPOS(POSNULL[1], MAXENTRYPOS - 1);
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
@ -220,7 +230,7 @@ calc_rank_and(float *w, tsvector * t, QUERYTYPE * q)
|
|||||||
{
|
{
|
||||||
for (p = 0; p < lenct; p++)
|
for (p = 0; p < lenct; p++)
|
||||||
{
|
{
|
||||||
dist = Abs((int)WEP_GETPOS(post[l]) - (int)WEP_GETPOS(ct[p]));
|
dist = Abs((int) WEP_GETPOS(post[l]) - (int) WEP_GETPOS(ct[p]));
|
||||||
if (dist || (dist == 0 && (pos[i] == (uint16 *) POSNULL || pos[k] == (uint16 *) POSNULL)))
|
if (dist || (dist == 0 && (pos[i] == (uint16 *) POSNULL || pos[k] == (uint16 *) POSNULL)))
|
||||||
{
|
{
|
||||||
float curw;
|
float curw;
|
||||||
@ -248,11 +258,11 @@ calc_rank_or(float *w, tsvector * t, QUERYTYPE * q)
|
|||||||
j,
|
j,
|
||||||
i;
|
i;
|
||||||
float res = -1.0;
|
float res = -1.0;
|
||||||
ITEM **item;
|
ITEM **item;
|
||||||
int size = q->size;
|
int size = q->size;
|
||||||
|
|
||||||
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
|
*(uint16 *) POSNULL = lengthof(POSNULL) - 1;
|
||||||
item = SortAndUniqItems( GETOPERAND(q), GETQUERY(q), &size);
|
item = SortAndUniqItems(GETOPERAND(q), GETQUERY(q), &size);
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
@ -279,7 +289,7 @@ calc_rank_or(float *w, tsvector * t, QUERYTYPE * q)
|
|||||||
res = 1.0 - (1.0 - res) * (1.0 - wpos(post[j]));
|
res = 1.0 - (1.0 - res) * (1.0 - wpos(post[j]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pfree( item );
|
pfree(item);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +298,7 @@ calc_rank(float *w, tsvector * t, QUERYTYPE * q, int4 method)
|
|||||||
{
|
{
|
||||||
ITEM *item = GETQUERY(q);
|
ITEM *item = GETQUERY(q);
|
||||||
float res = 0.0;
|
float res = 0.0;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (!t->size || !q->size)
|
if (!t->size || !q->size)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
@ -304,11 +314,12 @@ calc_rank(float *w, tsvector * t, QUERYTYPE * q, int4 method)
|
|||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
res /= log( (float)(cnt_length(t)+1) ) / log(2.0);
|
res /= log((float) (cnt_length(t) + 1)) / log(2.0);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
len = cnt_length(t);
|
len = cnt_length(t);
|
||||||
if ( len > 0 ) res /= (float)len;
|
if (len > 0)
|
||||||
|
res /= (float) len;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* internal error */
|
/* internal error */
|
||||||
@ -406,7 +417,7 @@ checkcondition_DR(void *checkval, ITEM * val)
|
|||||||
|
|
||||||
while (ptr - ((ChkDocR *) checkval)->doc < ((ChkDocR *) checkval)->len)
|
while (ptr - ((ChkDocR *) checkval)->doc < ((ChkDocR *) checkval)->len)
|
||||||
{
|
{
|
||||||
if ( val == ptr->item || compareITEM( &val, &(ptr->item) ) == 0 )
|
if (val == ptr->item || compareITEM(&val, &(ptr->item)) == 0)
|
||||||
return true;
|
return true;
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
@ -500,8 +511,7 @@ Cover(DocRepresentation * doc, int len, QUERYTYPE * query, int *pos, int *p, int
|
|||||||
if (TS_execute(GETQUERY(query), &ch, false, checkcondition_DR))
|
if (TS_execute(GETQUERY(query), &ch, false, checkcondition_DR))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* elog(NOTICE,"OP:%d NP:%d P:%d Q:%d", *pos, lastpos, *p,
|
* elog(NOTICE,"OP:%d NP:%d P:%d Q:%d", *pos, lastpos, *p, *q);
|
||||||
* *q);
|
|
||||||
*/
|
*/
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -611,11 +621,12 @@ rank_cd(PG_FUNCTION_ARGS)
|
|||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
res /= log( (float)(cnt_length(txt)+1) );
|
res /= log((float) (cnt_length(txt) + 1));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
len = cnt_length(txt);
|
len = cnt_length(txt);
|
||||||
if ( len > 0 ) res /= (float)len;
|
if (len > 0)
|
||||||
|
res /= (float) len;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* internal error */
|
/* internal error */
|
||||||
@ -638,7 +649,7 @@ rank_cd_def(PG_FUNCTION_ARGS)
|
|||||||
Int32GetDatum(-1),
|
Int32GetDatum(-1),
|
||||||
PG_GETARG_DATUM(0),
|
PG_GETARG_DATUM(0),
|
||||||
PG_GETARG_DATUM(1),
|
PG_GETARG_DATUM(1),
|
||||||
(PG_NARGS() == 3) ? PG_GETARG_DATUM(2) : Int32GetDatum(DEF_NORM_METHOD)
|
(PG_NARGS() == 3) ? PG_GETARG_DATUM(2) : Int32GetDatum(DEF_NORM_METHOD)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,69 +1,85 @@
|
|||||||
|
|
||||||
#include <stdlib.h> /* for calloc, free */
|
#include <stdlib.h> /* for calloc, free */
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
|
|
||||||
extern struct SN_env * SN_create_env(int S_size, int I_size, int B_size)
|
extern struct SN_env *
|
||||||
|
SN_create_env(int S_size, int I_size, int B_size)
|
||||||
{
|
{
|
||||||
struct SN_env * z = (struct SN_env *) calloc(1, sizeof(struct SN_env));
|
struct SN_env *z = (struct SN_env *) calloc(1, sizeof(struct SN_env));
|
||||||
if (z == NULL) return NULL;
|
|
||||||
z->p = create_s();
|
|
||||||
if (z->p == NULL) goto error;
|
|
||||||
if (S_size)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
z->S = (symbol * *) calloc(S_size, sizeof(symbol *));
|
|
||||||
if (z->S == NULL) goto error;
|
|
||||||
|
|
||||||
for (i = 0; i < S_size; i++)
|
if (z == NULL)
|
||||||
{
|
return NULL;
|
||||||
z->S[i] = create_s();
|
z->p = create_s();
|
||||||
if (z->S[i] == NULL) goto error;
|
if (z->p == NULL)
|
||||||
}
|
goto error;
|
||||||
z->S_size = S_size;
|
if (S_size)
|
||||||
}
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (I_size)
|
z->S = (symbol * *) calloc(S_size, sizeof(symbol *));
|
||||||
{
|
if (z->S == NULL)
|
||||||
z->I = (int *) calloc(I_size, sizeof(int));
|
goto error;
|
||||||
if (z->I == NULL) goto error;
|
|
||||||
z->I_size = I_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (B_size)
|
for (i = 0; i < S_size; i++)
|
||||||
{
|
{
|
||||||
z->B = (symbol *) calloc(B_size, sizeof(symbol));
|
z->S[i] = create_s();
|
||||||
if (z->B == NULL) goto error;
|
if (z->S[i] == NULL)
|
||||||
z->B_size = B_size;
|
goto error;
|
||||||
}
|
}
|
||||||
|
z->S_size = S_size;
|
||||||
|
}
|
||||||
|
|
||||||
return z;
|
if (I_size)
|
||||||
|
{
|
||||||
|
z->I = (int *) calloc(I_size, sizeof(int));
|
||||||
|
if (z->I == NULL)
|
||||||
|
goto error;
|
||||||
|
z->I_size = I_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (B_size)
|
||||||
|
{
|
||||||
|
z->B = (symbol *) calloc(B_size, sizeof(symbol));
|
||||||
|
if (z->B == NULL)
|
||||||
|
goto error;
|
||||||
|
z->B_size = B_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return z;
|
||||||
error:
|
error:
|
||||||
SN_close_env(z);
|
SN_close_env(z);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void SN_close_env(struct SN_env * z)
|
extern void
|
||||||
|
SN_close_env(struct SN_env * z)
|
||||||
{
|
{
|
||||||
if (z == NULL) return;
|
if (z == NULL)
|
||||||
if (z->S_size)
|
return;
|
||||||
{
|
if (z->S_size)
|
||||||
int i;
|
{
|
||||||
for (i = 0; i < z->S_size; i++)
|
int i;
|
||||||
{
|
|
||||||
lose_s(z->S[i]);
|
for (i = 0; i < z->S_size; i++)
|
||||||
}
|
{
|
||||||
free(z->S);
|
lose_s(z->S[i]);
|
||||||
}
|
}
|
||||||
if (z->I_size) free(z->I);
|
free(z->S);
|
||||||
if (z->B_size) free(z->B);
|
}
|
||||||
if (z->p) lose_s(z->p);
|
if (z->I_size)
|
||||||
free(z);
|
free(z->I);
|
||||||
|
if (z->B_size)
|
||||||
|
free(z->B);
|
||||||
|
if (z->p)
|
||||||
|
lose_s(z->p);
|
||||||
|
free(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int SN_set_current(struct SN_env * z, int size, const symbol * s)
|
extern int
|
||||||
|
SN_set_current(struct SN_env * z, int size, const symbol * s)
|
||||||
{
|
{
|
||||||
int err = replace_s(z, 0, z->l, size, s, NULL);
|
int err = replace_s(z, 0, z->l, size, s, NULL);
|
||||||
z->c = 0;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
z->c = 0;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user