+static void _add_serialno(ogg_page *og,long **serialno_list, int *n){
+ long s = ogg_page_serialno(og);
+ (*n)++;
+
+ if(serialno_list){
+ *serialno_list = _ogg_realloc(*serialno_list, sizeof(*serialno_list)*(*n));
+ }else{
+ *serialno_list = _ogg_malloc(sizeof(**serialno_list));
+ }
+
+ (*serialno_list)[(*n)-1] = s;
+}
+
+/* returns nonzero if found */
+static int _lookup_serialno(ogg_page *og, long *serialno_list, int n){
+ long s = ogg_page_serialno(og);
+
+ if(serialno_list){
+ while(n--){
+ if(*serialno_list == s) return 1;
+ serialno_list++;
+ }
+ }
+ return 0;
+}
+
+/* start parsing pages at current offset, remembering all serial
+ numbers. Stop logging at first non-bos page */
+static int _get_serialnos(OggVorbis_File *vf, long **s, int *n){
+ ogg_page og;
+
+ *s=NULL;
+ *n=0;
+
+ while(1){
+ ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
+ if(llret==OV_EOF)return(0);
+ if(llret<0)return(llret);
+ if(!ogg_page_bos(&og)) return 0;
+
+ /* look for duplicate serialnos; add this one if unique */
+ if(_lookup_serialno(&og,*s,*n)){
+ if(*s)_ogg_free(*s);
+ *s=0;
+ *n=0;
+ return(OV_EBADHEADER);
+ }
+
+ _add_serialno(&og,s,n);
+ }
+}
+