To niby jest C

05 grudnia 2010 17:13:19 | Kategorie: OpenSource Programowanie Techblog

Właśnie opublikowałem jedno z dziwniejszych przeżyć programistycznych. Niby jest to stare dobre C... Jednak sami powiedzcie, jak to Wam wygląda.

Plik poniższy wprowadza do Fossila możliwość rejestracji użytkownika przez HTTP.

/*
** Copyright (c) 2010 Remigiusz Modrzejewski 
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)

** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
**   Firstname.Lastname@gmail.com
**   http://lrem.net/
**
*******************************************************************************
**
** This file contains code for generating the register screen.
**
*/
#include "config.h"
#include "register.h"
#if defined(_WIN32)  
#  include <windows.h>           /* for Sleep */
#  if defined(__MINGW32__) || defined(_MSC_VER)
#    define sleep Sleep            /* windows does not have sleep, but Sleep */
#  endif
#endif
#include <time.h>

/*
** WEBPAGE: register
**
** Generate the register page.
**
*/
void register_page(void){
  const char *zUsername, *zPasswd, *zConfirm, *zContact, *zCS, *zPw, *zCap;

  style_header("Register");
  zUsername = P("u");
  zPasswd = P("p");
  zConfirm = P("cp");
  zContact = P("c");
  zCap = P("cap");
  zCS = P("cs"); /* Captcha Secret */

  /* Try to make any sense from user input. */
  if( P("new") ){
    zPw = captcha_decode((unsigned int)atoi(zCS)); /* If zCS == null this will
                                                      kill the page, what is in
                                                      fact good, as the request
                                                      is forged.*/
    if( !(zUsername && zPasswd && zConfirm && zContact) ){
      @ <p><span class="loginError">
      @ All fields are obligatory.
      @ </span></p>
    }else if( strcmp(zPasswd,zConfirm)!=0 ){
      @ <p><span class="loginError">
      @ The two copies of your new passwords do not match.
      @ </span></p>
    }else if( strcasecmp(zPw, zCap)!=0 ){
      @ <p><span class="loginError">
      @ Captcha text invalid.
      @ </span></p>
    }else{
      /* This almost is stupid copy-paste of code from user.c:user_cmd(). Meh. */
      Blob passwd, login, contact;

      blob_init(&login, zUsername, -1);
      blob_init(&contact, zContact, -1);
      blob_init(&passwd, zPasswd, -1);

      if( db_exists("SELECT 1 FROM user WHERE login=%B", &login) ){
        /* Here lies the reason I don't use zErrMsg - it would not substitute
         * this %s(zUsername), or at least I don't know how to force it to.*/
        @ <p><span class="loginError">
        @ %s(zUsername) already exists.
        @ </span></p>
      }else{
        char *zPw = sha1_shared_secret(blob_str(&passwd), blob_str(&login));
        db_multi_exec(
            "INSERT INTO user(login,pw,cap,info)"
            "VALUES(%B,%Q,'u',%B)", /* u - register as reader, not developer! */
            &login, zPw, &contact
            );
        free(zPw);

        /* The user is registered, now just log him in. */
        int uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUsername);
        char *zCookie;
        const char *zCookieName = login_cookie_name();
        const char *zExpire = db_get("cookie-expire","8766");
        int expires = atoi(zExpire)*3600;
        const char *zIpAddr = PD("REMOTE_ADDR","nil");

        zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid);
        cgi_set_cookie(zCookieName, zCookie, 0, expires);
        db_multi_exec(
            "UPDATE user SET cookie=%Q, ipaddr=%Q, "
            "  cexpire=julianday('now')+%d/86400.0 WHERE uid=%d",
            zCookie, zIpAddr, expires, uid
            );
        redirect_to_g();

      }
    }
  }

  /* Prepare the captcha. */
  unsigned int uSeed = captcha_seed();
  char const *zDecoded = captcha_decode(uSeed);
  char *zCaptcha = captcha_render(zDecoded);

  /* Print out the registration form. */
  @ <form action="register" method="post">
  if( P("g") ){
    @ <input type="hidden" name="g" value="%h(P("g"))" />
  }
  @ <p><input type="hidden" name="cs" value="%u(uSeed)" />
  @ <table class="login_out">
  @ <tr>
  @   <td class="login_out_label">User ID:</td>
  @   <td><input type="text" id="u" name="u" value="" size="30" /></td>
  @ </tr>
  @ <tr>
  @   <td class="login_out_label">Password:</td>
  @   <td><input type="password" id="p" name="p" value="" size="30" /></td>
  @ </tr>
  @ <tr>
  @   <td class="login_out_label">Confirm password:</td>
  @   <td><input type="password" id="cp" name="cp" value="" size="30" /></td>
  @ </tr>
  @ <tr>
  @   <td class="login_out_label">Contact info:</td>
  @   <td><input type="text" id="c" name="c" value="" size="30" /></td>
  @ </tr>
  @ <tr>
  @   <td class="login_out_label">Captcha text (below):</td>
  @   <td><input type="text" id="cap" name="cap" value="" size="30" /></td>
  @ </tr>
  @ <tr><td></td>
  @ <td><input type="submit" name="new" value="Register" /></td></tr>
  @ </table>
  @ <div class="captcha"><table class="captcha"><tr><td><pre>
  @ %s(zCaptcha)
  @ </pre></td></tr></table>
  @ </form>
    ;
  style_footer();

  free(zCaptcha);
}

// vim: set ts=2 sw=2 sts=2 et :

Komentarze do notki To niby jest C

  • airborn dnia 05 grudnia 2010 o 17:31:47:

    prawie jak bym widział swoją magisterkę...

  • Remigiusz 'lRem' Modrzejewski dnia 05 grudnia 2010 o 17:37:15:

    Współczuję... Ja do swojej kodowałem w Pythonie, acz i to było małym dodatkiem do teorii.

  • Bartek dnia 06 grudnia 2010 o 14:46:56:

    W C jest operator @ ? co on robi?

  • Remigiusz 'lRem' Modrzejewski dnia 06 grudnia 2010 o 14:48:22:

    To jest magia preprocessingu. W którymś momencie procesu kompilacji jest to tłumaczone na coś printf-o-podobnego wysyłającego do klienta html.

  • pecet dnia 06 grudnia 2010 o 21:51:31:

    Taki postprocessing tylko zaciemnia kod. C lubię za prostotę i dość dużą kontrolę nad tym co się dzieje, to jest niestety przeciwieństwem tego :/

  • lRem dnia 07 grudnia 2010 o 13:32:17:

    No sam nie wiem. Co jest jaśniejsze. Wersja z tym dzikim preprocesingiem:

    @ <input type="hidden" name="g" value="%h(P("g"))" />
    

    Czy bez niego:

    cgi_printf("<input type=\"hidden\" name=\"g\" value=\"%h\" />\n",P("g"));
    
  • SebaS86 dnia 07 grudnia 2010 o 18:44:50:

    Ale to chyba jakiś zewnętrzny preprocesor?

  • pecet dnia 07 grudnia 2010 o 20:32:55:

    lrem -- pomijając konieczność escapowania " " " to wydaje się całkiem czytelna wersja z printf IMHO

  • Remigiusz 'lRem' Modrzejewski dnia 08 grudnia 2010 o 15:38:56:

    SebaS86: ta, to jest w ogóle dziki makesystem gdzie make wywołuje skrypt w TCL-u który tworzy następny Makefile, wszystkie źródła są przemielone przez dodatkowy preprocesor, który również jest kompilowany w międzyczasie, na koniec nawet tworzy toto paczki. Część plików .c tworzonych jest podczas budowania na podstawie informacji zaszytych w komentarzach innych plików. Jak dodasz do tego jeszcze natywną obsługę cross-compile, to wyobrazisz sobie z jakim monstrum ma się do czynienia chcąc cokolwiek dodać.

  • real work from home jobs dnia 17 kwietnia 2014 o 09:44:02:

    This is because you lose a lot of money on transport, and also lose several hours
    on traffic jam. For example there is a new blog being
    started every second somewhere in the world. Due to this, many male members (fathers)
    have decided to start their own small businesses from home or seek
    work from home jobs to effectively manage their personal as well as professional
    life.

  • www.data-recovery-reviews.co.uk dnia 17 kwietnia 2014 o 13:45:06:

    Aw, this was an exceptionally nice post. Finding the time and actual effort to produce a really good article… but what can I say… I hesitate a
    lot and don't manage to get anything done.

  • ssd Recovery dnia 18 kwietnia 2014 o 16:45:36:

    I like the helpful info you provide in your articles.
    I will bookmark your weblog and check again here regularly.
    I'm quite certain I will learn lots of new stuff right here!
    Good luck for the next!

  • ssd Recovery dnia 18 kwietnia 2014 o 16:46:27:

    I like the helpful info you provide in your articles.
    I will bookmark your weblog and check again here regularly.
    I'm quite certain I will learn lots of new stuff right here!Good luck for
    the next!

  • nkle.in dnia 20 kwietnia 2014 o 00:36:21:

    The Venus Factor will not call for weighty machine raising or carrying out Aerobic for hours and
    hours. Also, there is no limitation on the diet
    regime that you just consume. You are able to try to
    eat every one of the food items the you care about with
    no sensing responsible concerning this and yet shed pounds along the way.

Komentuj Dodaj komentarz: