From 0a65ef1440681a22e66fb246240cc4a34665715d Mon Sep 17 00:00:00 2001 From: just n Date: Thu, 15 Jan 2026 20:35:50 +0000 Subject: [PATCH] Add reminder.c --- reminder.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 reminder.c diff --git a/reminder.c b/reminder.c new file mode 100644 index 0000000..505a126 --- /dev/null +++ b/reminder.c @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include +#include +#include + +#define F "r.db" +#define J "reminder@example.org" +#define P "safak" +#define R "remiders@room.example.org" +#define N "ReminderBot" + +typedef struct E{long long i;char*r,*u,*m;time_t d;struct E*n;}E; +typedef struct{xmpp_ctx_t*c;xmpp_conn_t*o;E*l;long long k;}B; + +static void T(xmpp_ctx_t*c,xmpp_stanza_t*p,const char*t){ + xmpp_stanza_t*n=xmpp_stanza_new(c); + xmpp_stanza_set_text(n,t); + xmpp_stanza_add_child(p,n); + xmpp_stanza_release(n); +} + +static time_t pt(const char*s){ + time_t w=time(0);struct tm t=*localtime(&w);int h,m; + if(strchr(s,':')&&sscanf(s,"%d:%d",&h,&m)==2){ + struct tm f=t;f.tm_hour=h;f.tm_min=m;f.tm_sec=0; + time_t x=mktime(&f);return x<=w?x+86400:x; + } + char*e;long v=strtol(s,&e,10);if(e==s)return 0; + char a=tolower(*e),b=e[1]?tolower(e[1]):0; + if(a=='s')return w+v; + if(a=='m'&&b!='o')return w+v*60; + if(a=='h')return w+v*3600; + if(a=='d')return w+v*86400; + if(a=='w')return w+v*604800; + if(a=='m'&&b=='o'){int n=t.tm_mon+v;t.tm_year+=n/12;t.tm_mon=n%12;if(t.tm_mon<0){t.tm_mon+=12;t.tm_year--;}return mktime(&t);} + if(a=='y'){int n=t.tm_mon+v*12;t.tm_year+=n/12;t.tm_mon=n%12;return mktime(&t);} + return 0; +} + +static void sv(B*b){ + FILE*f=fopen(F,"wb");if(!f)return; + int64_t c=b->k;fwrite(&c,8,1,f); + for(E*r=b->l;r;r=r->n){ + int64_t i=r->i,d=r->d; + uint16_t a=strlen(r->r),e=strlen(r->u),g=strlen(r->m); + fwrite(&i,8,1,f);fwrite(&d,8,1,f); + fwrite(&a,2,1,f);fwrite(&e,2,1,f);fwrite(&g,2,1,f); + fwrite(r->r,1,a,f);fwrite(r->u,1,e,f);fwrite(r->m,1,g,f); + } + fclose(f); +} + +static void ld(B*b){ + FILE*f=fopen(F,"rb");if(!f)return; + int64_t c;if(fread(&c,8,1,f)!=1){fclose(f);return;} + b->k=c;int64_t i; + while(fread(&i,8,1,f)==1){ + int64_t d;uint16_t a,e,g; + if(fread(&d,8,1,f)!=1||fread(&a,2,1,f)!=1||fread(&e,2,1,f)!=1||fread(&g,2,1,f)!=1)break; + E*r=malloc(sizeof(E));r->i=i;r->d=d; + r->r=malloc(a+1);r->u=malloc(e+1);r->m=malloc(g+1); + if(fread(r->r,1,a,f)!=a||fread(r->u,1,e,f)!=e||fread(r->m,1,g,f)!=g){free(r->r);free(r->u);free(r->m);free(r);break;} + r->r[a]=r->u[e]=r->m[g]=0;r->n=b->l;b->l=r; + } + fclose(f); +} + +static void rp(B*b,const char*t,const char*y,const char*m){ + xmpp_stanza_t*s=xmpp_stanza_new(b->c); + xmpp_stanza_set_name(s,"message"); + xmpp_stanza_set_type(s,y); + xmpp_stanza_set_attribute(s,"to",t); + xmpp_stanza_t*o=xmpp_stanza_new(b->c); + xmpp_stanza_set_name(o,"body"); + T(b->c,o,m); + xmpp_stanza_add_child(s,o); + xmpp_stanza_release(o); + xmpp_send(b->o,s); + xmpp_stanza_release(s); +} + +static int tc(xmpp_conn_t*o,void*x){ + B*b=x;time_t w=time(0);E**p=&b->l;int z=0; + while(*p){ + E*r=*p; + if(w>=r->d){ + char q[2048];snprintf(q,2048,"%s: %s",r->u,r->m); + rp(b,r->r,strstr(r->r,"@conf")||strstr(r->r,"@muc")?"groupchat":"chat",q); + *p=r->n;free(r->r);free(r->u);free(r->m);free(r);z=1; + }else p=&r->n; + } + if(z)sv(b);return 1; +} + +static int mc(xmpp_conn_t*o,xmpp_stanza_t*s,void*x){ + B*b=x; + xmpp_stanza_t*y=xmpp_stanza_get_child_by_name(s,"body"); + if(!y)return 1; + char*t=xmpp_stanza_get_text(y); + if(!t||*t!='!'){if(t)xmpp_free(b->c,t);return 1;} + const char*f=xmpp_stanza_get_attribute(s,"from"); + const char*p=xmpp_stanza_get_attribute(s,"type"); + if(!p)p="chat"; + if(!strcmp(p,"groupchat")){const char*l=strchr(f,'/');if(l&&!strcmp(l+1,N)){xmpp_free(b->c,t);return 1;}} + char*e=strdup(t),*c=strtok(e," "),rm[512],us[256]; + const char*l=strchr(f,'/'); + if(l){size_t n=l-f;memcpy(rm,f,n);rm[n]=0;strncpy(us,l+1,255);us[255]=0;} + else{strncpy(rm,f,511);strncpy(us,f,255);} + if(c&&!strcmp(c,"!remind")){ + char*ts=strtok(0," "),*mg=strtok(0,""); + if(ts&&mg){ + time_t d=pt(ts); + if(d>0){ + E*r=malloc(sizeof(E));r->i=++b->k;r->r=strdup(rm);r->u=strdup(us);r->m=strdup(mg);r->d=d;r->n=b->l;b->l=r;sv(b); + struct tm*z=localtime(&d);char q[256]; + snprintf(q,256,"Saved [%lld]: %04d-%02d-%02d %02d:%02d:%02d",r->i,z->tm_year+1900,z->tm_mon+1,z->tm_mday,z->tm_hour,z->tm_min,z->tm_sec); + rp(b,rm,p,q); + }else rp(b,rm,p,"Invalid format. Try: 30s, 5m, 1h, 10:30"); + }else rp(b,rm,p,"Usage: !remind